diff --git a/lilypond/includes/part_I.ly b/lilypond/includes/part_I.ly index 2067438..69a6c32 100644 --- a/lilypond/includes/part_I.ly +++ b/lilypond/includes/part_I.ly @@ -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_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_3_rise/4874dd07/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_3_rise/4bf1af12/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_3_rise/7ede7adb/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_3_rise/6db2efcc/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_3_rise/4e9f1dcc/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" diff --git a/lilypond/includes/part_II.ly b/lilypond/includes/part_II.ly index d1bd448..335b398 100644 --- a/lilypond/includes/part_II.ly +++ b/lilypond/includes/part_II.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_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_3_rise/4874dd07/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_3_rise/4bf1af12/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_3_rise/7ede7adb/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_3_rise/6db2efcc/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_3_rise/4e9f1dcc/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" diff --git a/lilypond/includes/part_III.ly b/lilypond/includes/part_III.ly index 6bc7a83..87a3832 100644 --- a/lilypond/includes/part_III.ly +++ b/lilypond/includes/part_III.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_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_3_rise/4874dd07/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_3_rise/4bf1af12/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_3_rise/7ede7adb/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_3_rise/6db2efcc/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_3_rise/4e9f1dcc/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" diff --git a/lilypond/includes/part_IV.ly b/lilypond/includes/part_IV.ly index 4901429..4fbe550 100644 --- a/lilypond/includes/part_IV.ly +++ b/lilypond/includes/part_IV.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_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_3_rise/4874dd07/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_3_rise/4bf1af12/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_3_rise/7ede7adb/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_3_rise/6db2efcc/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_3_rise/4e9f1dcc/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" diff --git a/lilypond/score_template.pdf b/lilypond/score_template.pdf index f97631f..1fe5850 100644 Binary files a/lilypond/score_template.pdf and b/lilypond/score_template.pdf differ diff --git a/lilypond/string_quartet_1/score_template.midi b/lilypond/string_quartet_1/score_template.midi deleted file mode 100644 index e6dd3cf..0000000 Binary files a/lilypond/string_quartet_1/score_template.midi and /dev/null differ diff --git a/lilypond/string_quartet_1/score_template.pdf b/lilypond/string_quartet_1/score_template.pdf index 21591c0..aba0929 100644 Binary files a/lilypond/string_quartet_1/score_template.pdf and b/lilypond/string_quartet_1/score_template.pdf differ diff --git a/lilypond/string_quartet_2/includes/part_I.ly b/lilypond/string_quartet_2/includes/part_I.ly new file mode 100644 index 0000000..2b624ea --- /dev/null +++ b/lilypond/string_quartet_2/includes/part_I.ly @@ -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" diff --git a/lilypond/string_quartet_2/includes/part_II.ly b/lilypond/string_quartet_2/includes/part_II.ly new file mode 100644 index 0000000..87a685f --- /dev/null +++ b/lilypond/string_quartet_2/includes/part_II.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" diff --git a/lilypond/string_quartet_2/includes/part_III.ly b/lilypond/string_quartet_2/includes/part_III.ly new file mode 100644 index 0000000..e137865 --- /dev/null +++ b/lilypond/string_quartet_2/includes/part_III.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" diff --git a/lilypond/string_quartet_2/includes/part_IV.ly b/lilypond/string_quartet_2/includes/part_IV.ly new file mode 100644 index 0000000..447ef88 --- /dev/null +++ b/lilypond/string_quartet_2/includes/part_IV.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" diff --git a/lilypond/string_quartet_2/score_template.ly b/lilypond/string_quartet_2/score_template.ly new file mode 100644 index 0000000..46c9512 --- /dev/null +++ b/lilypond/string_quartet_2/score_template.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 +} diff --git a/lilypond/string_quartet_2/score_template.pdf b/lilypond/string_quartet_2/score_template.pdf new file mode 100644 index 0000000..b89aa06 Binary files /dev/null and b/lilypond/string_quartet_2/score_template.pdf differ diff --git a/resources/piece_ledger_sq1_candidates.json b/resources/piece_ledger_sq1_candidates.json deleted file mode 100644 index dbf6200..0000000 --- a/resources/piece_ledger_sq1_candidates.json +++ /dev/null @@ -1,13 +0,0 @@ -{ -"ledger": -[ - "314s49e1", - "4a8a6e53", - "66f6a618", - "4c01589b", - "7e170ef8", - "7ac10d34", - "628d5c8b", - "6abf27d4" -] -} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates.json_bak b/resources/piece_ledger_sq1_candidates.json_bak deleted file mode 100644 index 9f9e86f..0000000 --- a/resources/piece_ledger_sq1_candidates.json_bak +++ /dev/null @@ -1,13 +0,0 @@ -{ -"ledger": -[ - "314s49e1", - "4a8a6e53", - "4c01589b", - "7e170ef8", - "7ac10d34", - "628d5c8b", - "6abf27d4", - "535cc132" -] -} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates/4c01589b/4c01589b_code.scd b/resources/piece_ledger_sq1_candidates/4c01589b/4c01589b_code.scd deleted file mode 100644 index b11446a..0000000 --- a/resources/piece_ledger_sq1_candidates/4c01589b/4c01589b_code.scd +++ /dev/null @@ -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"); \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates/4c01589b/4c01589b_gui_state.json b/resources/piece_ledger_sq1_candidates/4c01589b/4c01589b_gui_state.json deleted file mode 100644 index 2bc73d6..0000000 --- a/resources/piece_ledger_sq1_candidates/4c01589b/4c01589b_gui_state.json +++ /dev/null @@ -1,1359 +0,0 @@ -{ - "motif_label": "motif", - "seeds_label": "seeds", - "order": "[\n [ [ 3, 1, 0 ], [ 2 ], [ ] ],\n [ [ 1, 2 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 3 ] ],\n [ [ 3, 2 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], [ 0 ] ],\n [ [ 2, 3 ], [ 0, 1, 0 ], [ ] ]\n]", - "order_lock": 1, - "order_size": [ - 3, - 8 - ], - "order_size_v2": 8, - "order_size_v1": 3, - "order_size_panel": -1, - "passage_size_v2": 8, - "passage_size_v1": 2, - "passage_size_panel": -1, - "sus_weights": [ - null, - null, - null - ], - "range_matrix": [ - null, - null, - null, - null - ], - "instrumentation": [ - 0, - 0 - ], - "entrances_probs_sync": "passages", - "entrances": -1, - "passages_probs_sync": "passages", - "passages": -1, - "exits_probs_sync": "passages", - "exits": -1, - "dur_panel": 0, - "durations": -1, - "passages_weights": [ - null, - null, - null, - null, - null - ], - "weights": -1, - "seeds_tab_panel": 0, - "weights_seed_lock": 0, - "weights_seed": 534103, - "sus_weights/0_slider_val": 0.21, - "sus_weights/0_slider_slider": 0.21, - "sus_weights/0_slider_input": 0.21, - "sus_weights/0_slider_label": 1, - "sus_weights/0_slider": -1, - "sus_weights/1_slider_val": 0.35, - "sus_weights/1_slider_slider": 0.35, - "sus_weights/1_slider_input": 0.35, - "sus_weights/1_slider_label": 2, - "sus_weights/1_slider": -1, - "sus_weights/2_slider_val": 0.21, - "sus_weights/2_slider_slider": 0.21, - "sus_weights/2_slider_input": 0.21, - "sus_weights/2_slider_label": 3, - "sus_weights/2_slider": -1, - "passages_weights/0_slider_val": 0.49, - "passages_weights/0_slider_slider": 0.49, - "passages_weights/0_slider_input": 0.49, - "passages_weights/0_slider_label": "step", - "passages_weights/0_slider": -1, - "passages_weights/1_slider_val": 0.53, - "passages_weights/1_slider_slider": 0.53, - "passages_weights/1_slider_input": 0.53, - "passages_weights/1_slider_label": "dc", - "passages_weights/1_slider": -1, - "passages_weights/2_slider_val": 0.35, - "passages_weights/2_slider_slider": 0.35, - "passages_weights/2_slider_input": 0.35, - "passages_weights/2_slider_label": "range", - "passages_weights/2_slider": -1, - "passages_weights/3_slider_val": 0.59, - "passages_weights/3_slider_slider": 0.59, - "passages_weights/3_slider_input": 0.59, - "passages_weights/3_slider_label": "registration", - "passages_weights/3_slider": -1, - "passages_weights/4_slider_val": 0.39, - "passages_weights/4_slider_slider": 0.39, - "passages_weights/4_slider_input": 0.39, - "passages_weights/4_slider_label": "hd", - "passages_weights/4_slider": -1, - "range_matrix/0_val_input_min": -853.2067988668555, - "range_matrix/0_val_rslider": [ - -853.2067988668555, - 401 - ], - "range_matrix/0_val_input_max": 401, - "range_matrix/0_val": -1, - "range_matrix/1_val_input_min": -659, - "range_matrix/1_val_rslider": [ - -659, - 880 - ], - "range_matrix/1_val_input_max": 880, - "range_matrix/1_val": -1, - "range_matrix/2_val_input_min": -241, - "range_matrix/2_val_rslider": [ - -241, - 1869 - ], - "range_matrix/2_val_input_max": 1869, - "range_matrix/2_val": -1, - "range_matrix/3_val_input_min": -27, - "range_matrix/3_val_rslider": [ - -27, - 2063 - ], - "range_matrix/3_val_input_max": 2063, - "range_matrix/3_val": -1, - "entrances_probs_chord_slider_val": 0.66, - "entrances_probs_chord_slider_slider": 0.66, - "entrances_probs_chord_slider_input": 0.66, - "entrances_probs_chord_slider_label": "chord prob", - "entrances_probs_chord_slider": -1, - "entrances_probs_vals": [ - 0.63, - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.3963730569948187, - 0.8716216216216216, - 0.4948186528497409, - 0.5912162162162162, - 0.5362694300518135, - 0.8614864864864865, - 0.6424870466321243, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "entrances_probs": -1, - "passages_probs_chord_slider_val": 0.63, - "passages_probs_chord_slider_slider": 0.63, - "passages_probs_chord_slider_input": 0.63, - "passages_probs_chord_slider_label": "chord prob", - "passages_probs_chord_slider": -1, - "passages_probs_vals": [ - 0.63, - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.3963730569948187, - 0.8716216216216216, - 0.4948186528497409, - 0.5912162162162162, - 0.5362694300518135, - 0.8614864864864865, - 0.6424870466321243, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "passages_probs": -1, - "exits_probs_chord_slider_val": 0, - "exits_probs_chord_slider_slider": 0, - "exits_probs_chord_slider_input": 0, - "exits_probs_chord_slider_label": "chord prob", - "exits_probs_chord_slider": -1, - "exits_probs_vals": [ - 0, - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.4948186528497409, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "exits_probs": -1, - "step_env_env_vals": [ - 0, - 5, - 0, - 0, - 0, - 0, - 0.14609053497942387, - 0.7613636363636364, - 0.20164609053497942, - 0.26136363636363635, - 0.24279835390946503, - 0.7215909090909092, - 0.39094650205761317, - 0.875, - 0.4567901234567901, - 0.44318181818181823, - 0.5432098765432098, - 0.34659090909090906, - 0.6481481481481481, - 0.8011363636363636, - 0.6810699588477366, - 0.5170454545454546, - 0.8868312757201646, - 0.49431818181818177, - 0.8868312757201646, - 0.49431818181818177 - ], - "step_env_env_canvas": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0.14609053497942387, - 0.7613636363636364 - ], - [ - 0.20164609053497942, - 0.26136363636363635 - ], - [ - 0.24279835390946503, - 0.7215909090909092 - ], - [ - 0.39094650205761317, - 0.875 - ], - [ - 0.4567901234567901, - 0.44318181818181823 - ], - [ - 0.5432098765432098, - 0.34659090909090906 - ], - [ - 0.6481481481481481, - 0.8011363636363636 - ], - [ - 0.6810699588477366, - 0.5170454545454546 - ], - [ - 0.8868312757201646, - 0.49431818181818177 - ], - [ - 0.8868312757201646, - 0.49431818181818177 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "step_env_env_size": 12, - "step_env_env_flatten": 0, - "step_env_env_rslider": [ - 0, - 5 - ], - "step_env_env_rslider_v2": 5, - "step_env_env_rslider_v1": 0, - "step_env_env_mpos": "", - "step_env_env": -1, - "entrances_probs_dur_env_vals": [ - 0.515267175572519, - 4.599236641221374, - 0, - 0.5, - 0.2772020725388601, - 0.7972972972972973, - 0.45077720207253885, - 0.8783783783783784, - 0.5, - 0.5, - 0.727979274611399, - 0.45270270270270274, - 0.7357512953367875, - 0.6486486486486487, - 0.8911917098445595, - 0.7905405405405406, - 1, - 0.5 - ], - "entrances_probs_dur_env_canvas": [ - [ - 0, - 0.5 - ], - [ - 0.2772020725388601, - 0.7972972972972973 - ], - [ - 0.45077720207253885, - 0.8783783783783784 - ], - [ - 0.5, - 0.5 - ], - [ - 0.727979274611399, - 0.45270270270270274 - ], - [ - 0.7357512953367875, - 0.6486486486486487 - ], - [ - 0.8911917098445595, - 0.7905405405405406 - ], - [ - 1, - 0.5 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "entrances_probs_dur_env_size": 8, - "entrances_probs_dur_env_flatten": 0, - "entrances_probs_dur_env_rslider": [ - 0.515267175572519, - 4.599236641221374 - ], - "entrances_probs_dur_env_rslider_v2": 4.599236641221374, - "entrances_probs_dur_env_rslider_v1": 0.515267175572519, - "entrances_probs_dur_env_mpos": "", - "entrances_probs_dur_env": -1, - "passages_probs_dur_env_vals": [ - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.3963730569948187, - 0.8716216216216216, - 0.4948186528497409, - 0.5912162162162162, - 0.5362694300518135, - 0.8614864864864865, - 0.6424870466321243, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "passages_probs_dur_env_canvas": [ - [ - 0, - 0.5 - ], - [ - 0.23316062176165803, - 0.7094594594594594 - ], - [ - 0.3963730569948187, - 0.8716216216216216 - ], - [ - 0.4948186528497409, - 0.5912162162162162 - ], - [ - 0.5362694300518135, - 0.8614864864864865 - ], - [ - 0.6424870466321243, - 0.5912162162162162 - ], - [ - 0.7901554404145078, - 0.8277027027027027 - ], - [ - 1, - 0.5 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "passages_probs_dur_env_size": 8, - "passages_probs_dur_env_flatten": 0, - "passages_probs_dur_env_rslider": [ - 0, - 5 - ], - "passages_probs_dur_env_rslider_v2": 5, - "passages_probs_dur_env_rslider_v1": 0, - "passages_probs_dur_env_mpos": "", - "passages_probs_dur_env": -1, - "exits_probs_dur_env_vals": [ - 0, - 5, - 0, - 0.5, - 0.5, - 0.5, - 1, - 0.5 - ], - "exits_probs_dur_env_canvas": [ - [ - 0, - 0.5 - ], - [ - 0.5, - 0.5 - ], - [ - 1, - 0.5 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "exits_probs_dur_env_size": 3, - "exits_probs_dur_env_flatten": 0, - "exits_probs_dur_env_rslider": [ - 0, - 5 - ], - "exits_probs_dur_env_rslider_v2": 5, - "exits_probs_dur_env_rslider_v1": 0, - "exits_probs_dur_env_mpos": "", - "exits_probs_dur_env": -1, - "mus_seq": [ - [ - [ - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - "Rest" - ], - [ - "Rest" - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - "Rest" - ] - ], - 1.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - 0, - 1, - -3, - 0, - 2, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.75 - ], - [ - [ - [ - 1, - 1, - -2, - -2, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.625 - ], - [ - [ - [ - 1, - 1, - -3, - -1, - 0, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.625 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ] - ], - [ - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -2, - 0, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.375 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 2, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -2, - -1, - 2, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 0, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.875 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1 - ] - ], - [ - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 2, - 0, - -3, - -1, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.625 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - "Rest" - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - "Rest" - ] - ], - 1.875 - ], - [ - [ - [ - "Rest" - ], - [ - "Rest" - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - "Rest" - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - "Rest" - ], - [ - "Rest" - ], - [ - "Rest" - ] - ], - 0.875 - ] - ] - ] - ], - "root": [ - 0.20743639921722112, - 0 - ], - "order_seed": 798574, - "dur_seed": 884869, - "passages_size": [ - 0, - 10 - ], - "dur_seed_lock": 1, - "order_seed_lock": 0, - "seeds_panel": -1, - "motif_panel": [ - 0, - 0 - ], - "ref_uid": "6f1a789f", - "cur_uid": "4c01589b" -} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates/4c01589b/4c01589b_mus_model.json b/resources/piece_ledger_sq1_candidates/4c01589b/4c01589b_mus_model.json deleted file mode 100644 index 436b630..0000000 --- a/resources/piece_ledger_sq1_candidates/4c01589b/4c01589b_mus_model.json +++ /dev/null @@ -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 ] -} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates/66f6a618/66f6a618_mus_model.json b/resources/piece_ledger_sq1_candidates/66f6a618/66f6a618_mus_model.json deleted file mode 100644 index 9b60dbd..0000000 --- a/resources/piece_ledger_sq1_candidates/66f6a618/66f6a618_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates_stitch.json_bak b/resources/piece_ledger_sq1_candidates_stitch.json_bak deleted file mode 100644 index fd22a58..0000000 --- a/resources/piece_ledger_sq1_candidates_stitch.json_bak +++ /dev/null @@ -1,24 +0,0 @@ -{ -"ledger": -[ - "4a8a6e53", - "66f6a618", - "490b1e6e", - "46985d14", - "761e4585", - "6fb60ab6", - "79e0a4a7", - "43b009ff", - "7d3c9a80", - "4b7745df", - "6ed95c4c", - "6d635e88", - "4e7d35e5", - "7edbdceb", - "784130cc", - "443ec222", - "52c9a980", - "4200a90d", - "61ce9067" -] -} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates_stitch/61ce9067/lilypond/part_I.ly b/resources/piece_ledger_sq1_candidates_stitch/61ce9067/lilypond/part_I.ly deleted file mode 100644 index 7f37d66..0000000 --- a/resources/piece_ledger_sq1_candidates_stitch/61ce9067/lilypond/part_I.ly +++ /dev/null @@ -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 "||" -} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates_stitch/61ce9067/lilypond/part_II.ly b/resources/piece_ledger_sq1_candidates_stitch/61ce9067/lilypond/part_II.ly deleted file mode 100644 index 0179fb5..0000000 --- a/resources/piece_ledger_sq1_candidates_stitch/61ce9067/lilypond/part_II.ly +++ /dev/null @@ -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 "||" -} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates_stitch/61ce9067/lilypond/part_III.ly b/resources/piece_ledger_sq1_candidates_stitch/61ce9067/lilypond/part_III.ly deleted file mode 100644 index b62bec1..0000000 --- a/resources/piece_ledger_sq1_candidates_stitch/61ce9067/lilypond/part_III.ly +++ /dev/null @@ -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 "||" -} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates_stitch/tmp/tmp_mus_model.json b/resources/piece_ledger_sq1_candidates_stitch/tmp/tmp_mus_model.json deleted file mode 100644 index a1f5f5e..0000000 --- a/resources/piece_ledger_sq1_candidates_stitch/tmp/tmp_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test.json b/resources/piece_ledger_transcribe_test.json deleted file mode 100644 index 09ace87..0000000 --- a/resources/piece_ledger_transcribe_test.json +++ /dev/null @@ -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" -] -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test.json_bak b/resources/piece_ledger_transcribe_test.json_bak deleted file mode 100644 index d79c6c0..0000000 --- a/resources/piece_ledger_transcribe_test.json_bak +++ /dev/null @@ -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" -] -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/314s49e1/314s49e1_code.scd b/resources/piece_ledger_transcribe_test/314s49e1/314s49e1_code.scd deleted file mode 100644 index 2d77a32..0000000 --- a/resources/piece_ledger_transcribe_test/314s49e1/314s49e1_code.scd +++ /dev/null @@ -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; \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/314s49e1/314s49e1_mus_model.json b/resources/piece_ledger_transcribe_test/314s49e1/314s49e1_mus_model.json deleted file mode 100644 index c78a753..0000000 --- a/resources/piece_ledger_transcribe_test/314s49e1/314s49e1_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/43c05737/43c05737_code.scd b/resources/piece_ledger_transcribe_test/43c05737/43c05737_code.scd deleted file mode 100644 index 26709a0..0000000 --- a/resources/piece_ledger_transcribe_test/43c05737/43c05737_code.scd +++ /dev/null @@ -1,1058 +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, genStepFunc; - -// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, -orders, susWeights, orderSize, passagesSize, -motifEdited, orderEdited; - -// model aux vars -var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; - -// 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) - stepFunc.value(pDistance); -}; - -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); -}; - -genStepFunc = {arg minStep, maxStep, envData, seed; - var envDataNorm, env, pTable, stepFunc; - [minStep, maxStep, envData].postln; - envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; - envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; - env = Env.pairs(envDataNorm); - stepFunc = {arg pDist; - env.at(pDist).clip(0.001, 1); - }; - seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); - if(hdInvert == 0, {hdScore = 1/hdScore}); - //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, fDur, durAdd; - - 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); - }); - - //round last duration to measure - fDur = fSeq.flatten.flatten.slice(nil, 1).sum; - durAdd = fDur.round(4) - fDur; - if(durAdd < 0, {durAdd = 4 - durAdd}); - fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; - - 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.notNil) { - ~msg; - ~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.0, 3.0)}, {rrand(0.3, 0.5)}); - }); - rels = rels.add(rrand(1.0, 3.0)); - 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; - }, { - var tmpRes; - if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); - if(res.contains("."), {tmpRes = res.asFloat}); - if(tmpRes != nil, {res = tmpRes}); - }); - }); - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", - "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)); - }); - - stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); - 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)); - //~seq = seq; - - addr.sendMsg("/generated", path, modelString, ledgerPath); -}, \generate); - - -OSCdef(\commit, {arg msg, time, addr, port; - var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; - //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; - commitType = msg[2].asString; - commitPos = msg[3].postln.asInteger; - - lastCurUID = curUID.deepCopy; - 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); - - /* - if(commitType == "add", { - if(lastCurUID == "tmp", { - ledger = ledger.drop(-1).add(curUID); - }, { - ledger = ledger.add(curUID); - }) - }); - */ - - ledger.postln; - - if(commitType == "add", {ledger = ledger.add(curUID)}); - - if(commitType == "insert", {ledger = ledger.insert(commitPos, curUID)}); - - if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); - - equalityLedger = ledger.collect({arg item; item.asSymbol}); - if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); - - ledger.postln; - - 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); - - -OSCdef(\transcribe_motif, {arg msg, time, addr, port; - var tSeq, refChord, refUID; - - msg.postln; - - tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; - refUID = msg[2].asString.postln; - - if((refUID != "nil") && (refUID != "tmp"), { - var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }, { - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - }); - - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); -}, \transcribe_motif); - - -OSCdef(\transcribe_all, {arg msg, time, addr, port; - var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; - if(true, { - cuedSeek = (seq != nil); - indexStart = msg[1].asInteger; - indexEnd = ledger.size - if(cuedSeek, {2}, {1}); - - //tmp for testing transcription - indexEnd = (indexStart+5); - - //ledger.postln; - if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { - var lilyPartLedgerFiles; - - lilyPartLedgerFiles = 4.collect({arg p; - File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); - }); - - ledger[indexStart..indexEnd].do({arg uid, index; - var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - fileString = file.readAllString; - tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); - refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); - file.close; - - //uid.postln; - //(refUID == "nil").postln; - - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - - if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }); - - if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); - }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); - }); - - lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); - }); - - }); - - lilyPartLedgerFiles.do({arg f; - f.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; - }); - */ - }, { - - }); - -}, \transcribe_all); - -) - -~transcribe.value(~seq, dir); - -( -//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; - - 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; -) -*/ - diff --git a/resources/piece_ledger_transcribe_test/43c05737/43c05737_mus_model.json b/resources/piece_ledger_transcribe_test/43c05737/43c05737_mus_model.json deleted file mode 100644 index 30e410b..0000000 --- a/resources/piece_ledger_transcribe_test/43c05737/43c05737_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/46631d0e/46631d0e_code.scd b/resources/piece_ledger_transcribe_test/46631d0e/46631d0e_code.scd deleted file mode 100644 index e1e007b..0000000 --- a/resources/piece_ledger_transcribe_test/46631d0e/46631d0e_code.scd +++ /dev/null @@ -1,1053 +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, genStepFunc; - -// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, -orders, susWeights, orderSize, passagesSize, -motifEdited, orderEdited; - -// model aux vars -var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; - -// 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) - stepFunc.value(pDistance); -}; - -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); -}; - -genStepFunc = {arg minStep, maxStep, envData, seed; - var envDataNorm, env, pTable, stepFunc; - [minStep, maxStep, envData].postln; - envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; - envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; - env = Env.pairs(envDataNorm); - stepFunc = {arg pDist; - env.at(pDist).clip(0.001, 1); - }; - seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); - if(hdInvert == 0, {hdScore = 1/hdScore}); - //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, fDur, durAdd; - - 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); - }); - - //round last duration to measure - fDur = fSeq.flatten.flatten.slice(nil, 1).sum; - durAdd = fDur.round(4) - fDur; - if(durAdd < 0, {durAdd = 4 - durAdd}); - fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; - - 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.notNil) { - ~msg; - ~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.0, 3.0)}, {rrand(0.3, 0.5)}); - }); - rels = rels.add(rrand(1.0, 3.0)); - 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; - }, { - var tmpRes; - if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); - if(res.contains("."), {tmpRes = res.asFloat}); - if(tmpRes != nil, {res = tmpRes}); - }); - }); - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", - "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)); - }); - - stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); - 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)); - //~seq = seq; - - addr.sendMsg("/generated", path, modelString, ledgerPath); -}, \generate); - - -OSCdef(\commit, {arg msg, time, addr, port; - var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos; - //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; - commitType = msg[2].asString; - commitPos = msg[3].postln.asInteger; - - lastCurUID = curUID.deepCopy; - 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); - - /* - if(commitType == "add", { - if(lastCurUID == "tmp", { - ledger = ledger.drop(-1).add(curUID); - }, { - ledger = ledger.add(curUID); - }) - }); - */ - - if(commitType == "add", {ledger = ledger.add(curUID)}); - - if(commitType == "insert", {ledger = ledger.insert(commitPos - 1, curUID)}); - - if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); - - if(ledger.includes("tmp"), {ledger = ledger.removeAt(ledger.indexOf("tmp"))}); - - 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); - - -OSCdef(\transcribe_motif, {arg msg, time, addr, port; - var tSeq, refChord, refUID; - - msg.postln; - - tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; - refUID = msg[2].asString.postln; - - if((refUID != "nil") && (refUID != "tmp"), { - var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }, { - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - }); - - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); -}, \transcribe_motif); - - -OSCdef(\transcribe_all, {arg msg, time, addr, port; - var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; - if(true, { - cuedSeek = (seq != nil); - indexStart = msg[1].asInteger; - indexEnd = ledger.size - if(cuedSeek, {2}, {1}); - - //tmp for testing transcription - indexEnd = (indexStart+5); - - //ledger.postln; - if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { - var lilyPartLedgerFiles; - - lilyPartLedgerFiles = 4.collect({arg p; - File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); - }); - - ledger[indexStart..indexEnd].do({arg uid, index; - var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - fileString = file.readAllString; - tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); - refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); - file.close; - - //uid.postln; - //(refUID == "nil").postln; - - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - - if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }); - - if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); - }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); - }); - - lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); - }); - - }); - - lilyPartLedgerFiles.do({arg f; - f.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; - }); - */ - }, { - - }); - -}, \transcribe_all); - -) - -~transcribe.value(~seq, dir); - -( -//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; - - 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; -) -*/ - diff --git a/resources/piece_ledger_transcribe_test/46631d0e/46631d0e_mus_model.json b/resources/piece_ledger_transcribe_test/46631d0e/46631d0e_mus_model.json deleted file mode 100644 index 05b6232..0000000 --- a/resources/piece_ledger_transcribe_test/46631d0e/46631d0e_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/47770d57/47770d57_code.scd b/resources/piece_ledger_transcribe_test/47770d57/47770d57_code.scd deleted file mode 100644 index dbbe348..0000000 --- a/resources/piece_ledger_transcribe_test/47770d57/47770d57_code.scd +++ /dev/null @@ -1,1053 +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, genStepFunc; - -// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, -orders, susWeights, orderSize, passagesSize, -motifEdited, orderEdited; - -// model aux vars -var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; - -// 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) - stepFunc.value(pDistance); -}; - -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); -}; - -genStepFunc = {arg minStep, maxStep, envData, seed; - var envDataNorm, env, pTable, stepFunc; - [minStep, maxStep, envData].postln; - envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; - envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; - env = Env.pairs(envDataNorm); - stepFunc = {arg pDist; - env.at(pDist).clip(0.001, 1); - }; - seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); - if(hdInvert == 0, {hdScore = 1/hdScore}); - //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, fDur, durAdd; - - 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); - }); - - //round last duration to measure - fDur = fSeq.flatten.flatten.slice(nil, 1).sum; - durAdd = fDur.round(4) - fDur; - if(durAdd < 0, {durAdd = 4 - durAdd}); - fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; - - 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.notNil) { - ~msg; - ~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.0, 3.0)}, {rrand(0.3, 0.5)}); - }); - rels = rels.add(rrand(1.0, 3.0)); - 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; - }, { - var tmpRes; - if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); - if(res.contains("."), {tmpRes = res.asFloat}); - if(tmpRes != nil, {res = tmpRes}); - }); - }); - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", - "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)); - }); - - stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); - 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)); - //~seq = seq; - - addr.sendMsg("/generated", path, modelString, ledgerPath); -}, \generate); - - -OSCdef(\commit, {arg msg, time, addr, port; - var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos; - //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; - commitType = msg[2].asString; - commitPos = msg[3].postln.asInteger; - - lastCurUID = curUID.deepCopy; - 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); - - /* - if(commitType == "add", { - if(lastCurUID == "tmp", { - ledger = ledger.drop(-1).add(curUID); - }, { - ledger = ledger.add(curUID); - }) - }); - */ - - if(commitType == "add", {ledger = ledger.add(curUID)}); - - if(commitType == "insert", {ledger = ledger.insert(commitPos - 1, curUID)}); - - if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); - - if(ledger.includes("tmp").postln, {ledger = ledger.removeAt(ledger.indexOf("tmp").postln)}); - - 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); - - -OSCdef(\transcribe_motif, {arg msg, time, addr, port; - var tSeq, refChord, refUID; - - msg.postln; - - tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; - refUID = msg[2].asString.postln; - - if((refUID != "nil") && (refUID != "tmp"), { - var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }, { - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - }); - - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); -}, \transcribe_motif); - - -OSCdef(\transcribe_all, {arg msg, time, addr, port; - var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; - if(true, { - cuedSeek = (seq != nil); - indexStart = msg[1].asInteger; - indexEnd = ledger.size - if(cuedSeek, {2}, {1}); - - //tmp for testing transcription - indexEnd = (indexStart+5); - - //ledger.postln; - if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { - var lilyPartLedgerFiles; - - lilyPartLedgerFiles = 4.collect({arg p; - File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); - }); - - ledger[indexStart..indexEnd].do({arg uid, index; - var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - fileString = file.readAllString; - tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); - refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); - file.close; - - //uid.postln; - //(refUID == "nil").postln; - - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - - if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }); - - if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); - }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); - }); - - lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); - }); - - }); - - lilyPartLedgerFiles.do({arg f; - f.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; - }); - */ - }, { - - }); - -}, \transcribe_all); - -) - -~transcribe.value(~seq, dir); - -( -//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; - - 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; -) -*/ - diff --git a/resources/piece_ledger_transcribe_test/47770d57/47770d57_mus_model.json b/resources/piece_ledger_transcribe_test/47770d57/47770d57_mus_model.json deleted file mode 100644 index 8784788..0000000 --- a/resources/piece_ledger_transcribe_test/47770d57/47770d57_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/4828752f/4828752f_mus_model.json b/resources/piece_ledger_transcribe_test/4828752f/4828752f_mus_model.json deleted file mode 100644 index 689c7a8..0000000 --- a/resources/piece_ledger_transcribe_test/4828752f/4828752f_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/49258e97/49258e97_code.scd b/resources/piece_ledger_transcribe_test/49258e97/49258e97_code.scd deleted file mode 100644 index 1c97ceb..0000000 --- a/resources/piece_ledger_transcribe_test/49258e97/49258e97_code.scd +++ /dev/null @@ -1,1055 +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, genStepFunc; - -// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, -orders, susWeights, orderSize, passagesSize, -motifEdited, orderEdited; - -// model aux vars -var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; - -// 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) - stepFunc.value(pDistance); -}; - -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); -}; - -genStepFunc = {arg minStep, maxStep, envData, seed; - var envDataNorm, env, pTable, stepFunc; - [minStep, maxStep, envData].postln; - envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; - envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; - env = Env.pairs(envDataNorm); - stepFunc = {arg pDist; - env.at(pDist).clip(0.001, 1); - }; - seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); - if(hdInvert == 0, {hdScore = 1/hdScore}); - //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, fDur, durAdd; - - 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); - }); - - //round last duration to measure - fDur = fSeq.flatten.flatten.slice(nil, 1).sum; - durAdd = fDur.round(4) - fDur; - if(durAdd < 0, {durAdd = 4 - durAdd}); - fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; - - 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.notNil) { - ~msg; - ~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.0, 3.0)}, {rrand(0.3, 0.5)}); - }); - rels = rels.add(rrand(1.0, 3.0)); - 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; - }, { - var tmpRes; - if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); - if(res.contains("."), {tmpRes = res.asFloat}); - if(tmpRes != nil, {res = tmpRes}); - }); - }); - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", - "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)); - }); - - stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); - 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)); - //~seq = seq; - - addr.sendMsg("/generated", path, modelString, ledgerPath); -}, \generate); - - -OSCdef(\commit, {arg msg, time, addr, port; - var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos; - //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; - commitType = msg[2].asString; - commitPos = msg[3].postln.asInteger; - - lastCurUID = curUID.deepCopy; - 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); - - /* - if(commitType == "add", { - if(lastCurUID == "tmp", { - ledger = ledger.drop(-1).add(curUID); - }, { - ledger = ledger.add(curUID); - }) - }); - */ - - ledger.postln; - - if(commitType == "add", {ledger = ledger.add(curUID)}); - - if(commitType == "insert", {ledger = ledger.insert(commitPos - 1, curUID)}); - - if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); - - if(ledger.includes("tmp").postln, {ledger = ledger.removeAt(ledger.indexOf("tmp").postln)}); - - 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); - - -OSCdef(\transcribe_motif, {arg msg, time, addr, port; - var tSeq, refChord, refUID; - - msg.postln; - - tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; - refUID = msg[2].asString.postln; - - if((refUID != "nil") && (refUID != "tmp"), { - var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }, { - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - }); - - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); -}, \transcribe_motif); - - -OSCdef(\transcribe_all, {arg msg, time, addr, port; - var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; - if(true, { - cuedSeek = (seq != nil); - indexStart = msg[1].asInteger; - indexEnd = ledger.size - if(cuedSeek, {2}, {1}); - - //tmp for testing transcription - indexEnd = (indexStart+5); - - //ledger.postln; - if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { - var lilyPartLedgerFiles; - - lilyPartLedgerFiles = 4.collect({arg p; - File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); - }); - - ledger[indexStart..indexEnd].do({arg uid, index; - var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - fileString = file.readAllString; - tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); - refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); - file.close; - - //uid.postln; - //(refUID == "nil").postln; - - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - - if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }); - - if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); - }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); - }); - - lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); - }); - - }); - - lilyPartLedgerFiles.do({arg f; - f.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; - }); - */ - }, { - - }); - -}, \transcribe_all); - -) - -~transcribe.value(~seq, dir); - -( -//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; - - 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; -) -*/ - diff --git a/resources/piece_ledger_transcribe_test/49258e97/49258e97_mus_model.json b/resources/piece_ledger_transcribe_test/49258e97/49258e97_mus_model.json deleted file mode 100644 index c8cf095..0000000 --- a/resources/piece_ledger_transcribe_test/49258e97/49258e97_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/497509c8/497509c8_mus_model.json b/resources/piece_ledger_transcribe_test/497509c8/497509c8_mus_model.json deleted file mode 100644 index ea15791..0000000 --- a/resources/piece_ledger_transcribe_test/497509c8/497509c8_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/4c01589b/4c01589b_code.scd b/resources/piece_ledger_transcribe_test/4c01589b/4c01589b_code.scd deleted file mode 100644 index b11446a..0000000 --- a/resources/piece_ledger_transcribe_test/4c01589b/4c01589b_code.scd +++ /dev/null @@ -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"); \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/4c01589b/4c01589b_gui_state.json b/resources/piece_ledger_transcribe_test/4c01589b/4c01589b_gui_state.json deleted file mode 100644 index 2bc73d6..0000000 --- a/resources/piece_ledger_transcribe_test/4c01589b/4c01589b_gui_state.json +++ /dev/null @@ -1,1359 +0,0 @@ -{ - "motif_label": "motif", - "seeds_label": "seeds", - "order": "[\n [ [ 3, 1, 0 ], [ 2 ], [ ] ],\n [ [ 1, 2 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 3 ] ],\n [ [ 3, 2 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], [ 0 ] ],\n [ [ 2, 3 ], [ 0, 1, 0 ], [ ] ]\n]", - "order_lock": 1, - "order_size": [ - 3, - 8 - ], - "order_size_v2": 8, - "order_size_v1": 3, - "order_size_panel": -1, - "passage_size_v2": 8, - "passage_size_v1": 2, - "passage_size_panel": -1, - "sus_weights": [ - null, - null, - null - ], - "range_matrix": [ - null, - null, - null, - null - ], - "instrumentation": [ - 0, - 0 - ], - "entrances_probs_sync": "passages", - "entrances": -1, - "passages_probs_sync": "passages", - "passages": -1, - "exits_probs_sync": "passages", - "exits": -1, - "dur_panel": 0, - "durations": -1, - "passages_weights": [ - null, - null, - null, - null, - null - ], - "weights": -1, - "seeds_tab_panel": 0, - "weights_seed_lock": 0, - "weights_seed": 534103, - "sus_weights/0_slider_val": 0.21, - "sus_weights/0_slider_slider": 0.21, - "sus_weights/0_slider_input": 0.21, - "sus_weights/0_slider_label": 1, - "sus_weights/0_slider": -1, - "sus_weights/1_slider_val": 0.35, - "sus_weights/1_slider_slider": 0.35, - "sus_weights/1_slider_input": 0.35, - "sus_weights/1_slider_label": 2, - "sus_weights/1_slider": -1, - "sus_weights/2_slider_val": 0.21, - "sus_weights/2_slider_slider": 0.21, - "sus_weights/2_slider_input": 0.21, - "sus_weights/2_slider_label": 3, - "sus_weights/2_slider": -1, - "passages_weights/0_slider_val": 0.49, - "passages_weights/0_slider_slider": 0.49, - "passages_weights/0_slider_input": 0.49, - "passages_weights/0_slider_label": "step", - "passages_weights/0_slider": -1, - "passages_weights/1_slider_val": 0.53, - "passages_weights/1_slider_slider": 0.53, - "passages_weights/1_slider_input": 0.53, - "passages_weights/1_slider_label": "dc", - "passages_weights/1_slider": -1, - "passages_weights/2_slider_val": 0.35, - "passages_weights/2_slider_slider": 0.35, - "passages_weights/2_slider_input": 0.35, - "passages_weights/2_slider_label": "range", - "passages_weights/2_slider": -1, - "passages_weights/3_slider_val": 0.59, - "passages_weights/3_slider_slider": 0.59, - "passages_weights/3_slider_input": 0.59, - "passages_weights/3_slider_label": "registration", - "passages_weights/3_slider": -1, - "passages_weights/4_slider_val": 0.39, - "passages_weights/4_slider_slider": 0.39, - "passages_weights/4_slider_input": 0.39, - "passages_weights/4_slider_label": "hd", - "passages_weights/4_slider": -1, - "range_matrix/0_val_input_min": -853.2067988668555, - "range_matrix/0_val_rslider": [ - -853.2067988668555, - 401 - ], - "range_matrix/0_val_input_max": 401, - "range_matrix/0_val": -1, - "range_matrix/1_val_input_min": -659, - "range_matrix/1_val_rslider": [ - -659, - 880 - ], - "range_matrix/1_val_input_max": 880, - "range_matrix/1_val": -1, - "range_matrix/2_val_input_min": -241, - "range_matrix/2_val_rslider": [ - -241, - 1869 - ], - "range_matrix/2_val_input_max": 1869, - "range_matrix/2_val": -1, - "range_matrix/3_val_input_min": -27, - "range_matrix/3_val_rslider": [ - -27, - 2063 - ], - "range_matrix/3_val_input_max": 2063, - "range_matrix/3_val": -1, - "entrances_probs_chord_slider_val": 0.66, - "entrances_probs_chord_slider_slider": 0.66, - "entrances_probs_chord_slider_input": 0.66, - "entrances_probs_chord_slider_label": "chord prob", - "entrances_probs_chord_slider": -1, - "entrances_probs_vals": [ - 0.63, - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.3963730569948187, - 0.8716216216216216, - 0.4948186528497409, - 0.5912162162162162, - 0.5362694300518135, - 0.8614864864864865, - 0.6424870466321243, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "entrances_probs": -1, - "passages_probs_chord_slider_val": 0.63, - "passages_probs_chord_slider_slider": 0.63, - "passages_probs_chord_slider_input": 0.63, - "passages_probs_chord_slider_label": "chord prob", - "passages_probs_chord_slider": -1, - "passages_probs_vals": [ - 0.63, - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.3963730569948187, - 0.8716216216216216, - 0.4948186528497409, - 0.5912162162162162, - 0.5362694300518135, - 0.8614864864864865, - 0.6424870466321243, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "passages_probs": -1, - "exits_probs_chord_slider_val": 0, - "exits_probs_chord_slider_slider": 0, - "exits_probs_chord_slider_input": 0, - "exits_probs_chord_slider_label": "chord prob", - "exits_probs_chord_slider": -1, - "exits_probs_vals": [ - 0, - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.4948186528497409, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "exits_probs": -1, - "step_env_env_vals": [ - 0, - 5, - 0, - 0, - 0, - 0, - 0.14609053497942387, - 0.7613636363636364, - 0.20164609053497942, - 0.26136363636363635, - 0.24279835390946503, - 0.7215909090909092, - 0.39094650205761317, - 0.875, - 0.4567901234567901, - 0.44318181818181823, - 0.5432098765432098, - 0.34659090909090906, - 0.6481481481481481, - 0.8011363636363636, - 0.6810699588477366, - 0.5170454545454546, - 0.8868312757201646, - 0.49431818181818177, - 0.8868312757201646, - 0.49431818181818177 - ], - "step_env_env_canvas": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0.14609053497942387, - 0.7613636363636364 - ], - [ - 0.20164609053497942, - 0.26136363636363635 - ], - [ - 0.24279835390946503, - 0.7215909090909092 - ], - [ - 0.39094650205761317, - 0.875 - ], - [ - 0.4567901234567901, - 0.44318181818181823 - ], - [ - 0.5432098765432098, - 0.34659090909090906 - ], - [ - 0.6481481481481481, - 0.8011363636363636 - ], - [ - 0.6810699588477366, - 0.5170454545454546 - ], - [ - 0.8868312757201646, - 0.49431818181818177 - ], - [ - 0.8868312757201646, - 0.49431818181818177 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "step_env_env_size": 12, - "step_env_env_flatten": 0, - "step_env_env_rslider": [ - 0, - 5 - ], - "step_env_env_rslider_v2": 5, - "step_env_env_rslider_v1": 0, - "step_env_env_mpos": "", - "step_env_env": -1, - "entrances_probs_dur_env_vals": [ - 0.515267175572519, - 4.599236641221374, - 0, - 0.5, - 0.2772020725388601, - 0.7972972972972973, - 0.45077720207253885, - 0.8783783783783784, - 0.5, - 0.5, - 0.727979274611399, - 0.45270270270270274, - 0.7357512953367875, - 0.6486486486486487, - 0.8911917098445595, - 0.7905405405405406, - 1, - 0.5 - ], - "entrances_probs_dur_env_canvas": [ - [ - 0, - 0.5 - ], - [ - 0.2772020725388601, - 0.7972972972972973 - ], - [ - 0.45077720207253885, - 0.8783783783783784 - ], - [ - 0.5, - 0.5 - ], - [ - 0.727979274611399, - 0.45270270270270274 - ], - [ - 0.7357512953367875, - 0.6486486486486487 - ], - [ - 0.8911917098445595, - 0.7905405405405406 - ], - [ - 1, - 0.5 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "entrances_probs_dur_env_size": 8, - "entrances_probs_dur_env_flatten": 0, - "entrances_probs_dur_env_rslider": [ - 0.515267175572519, - 4.599236641221374 - ], - "entrances_probs_dur_env_rslider_v2": 4.599236641221374, - "entrances_probs_dur_env_rslider_v1": 0.515267175572519, - "entrances_probs_dur_env_mpos": "", - "entrances_probs_dur_env": -1, - "passages_probs_dur_env_vals": [ - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.3963730569948187, - 0.8716216216216216, - 0.4948186528497409, - 0.5912162162162162, - 0.5362694300518135, - 0.8614864864864865, - 0.6424870466321243, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "passages_probs_dur_env_canvas": [ - [ - 0, - 0.5 - ], - [ - 0.23316062176165803, - 0.7094594594594594 - ], - [ - 0.3963730569948187, - 0.8716216216216216 - ], - [ - 0.4948186528497409, - 0.5912162162162162 - ], - [ - 0.5362694300518135, - 0.8614864864864865 - ], - [ - 0.6424870466321243, - 0.5912162162162162 - ], - [ - 0.7901554404145078, - 0.8277027027027027 - ], - [ - 1, - 0.5 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "passages_probs_dur_env_size": 8, - "passages_probs_dur_env_flatten": 0, - "passages_probs_dur_env_rslider": [ - 0, - 5 - ], - "passages_probs_dur_env_rslider_v2": 5, - "passages_probs_dur_env_rslider_v1": 0, - "passages_probs_dur_env_mpos": "", - "passages_probs_dur_env": -1, - "exits_probs_dur_env_vals": [ - 0, - 5, - 0, - 0.5, - 0.5, - 0.5, - 1, - 0.5 - ], - "exits_probs_dur_env_canvas": [ - [ - 0, - 0.5 - ], - [ - 0.5, - 0.5 - ], - [ - 1, - 0.5 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "exits_probs_dur_env_size": 3, - "exits_probs_dur_env_flatten": 0, - "exits_probs_dur_env_rslider": [ - 0, - 5 - ], - "exits_probs_dur_env_rslider_v2": 5, - "exits_probs_dur_env_rslider_v1": 0, - "exits_probs_dur_env_mpos": "", - "exits_probs_dur_env": -1, - "mus_seq": [ - [ - [ - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - "Rest" - ], - [ - "Rest" - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - "Rest" - ] - ], - 1.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - 0, - 1, - -3, - 0, - 2, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.75 - ], - [ - [ - [ - 1, - 1, - -2, - -2, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.625 - ], - [ - [ - [ - 1, - 1, - -3, - -1, - 0, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.625 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ] - ], - [ - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -2, - 0, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.375 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 2, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -2, - -1, - 2, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 0, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.875 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1 - ] - ], - [ - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 2, - 0, - -3, - -1, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.625 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - "Rest" - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - "Rest" - ] - ], - 1.875 - ], - [ - [ - [ - "Rest" - ], - [ - "Rest" - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - "Rest" - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - "Rest" - ], - [ - "Rest" - ], - [ - "Rest" - ] - ], - 0.875 - ] - ] - ] - ], - "root": [ - 0.20743639921722112, - 0 - ], - "order_seed": 798574, - "dur_seed": 884869, - "passages_size": [ - 0, - 10 - ], - "dur_seed_lock": 1, - "order_seed_lock": 0, - "seeds_panel": -1, - "motif_panel": [ - 0, - 0 - ], - "ref_uid": "6f1a789f", - "cur_uid": "4c01589b" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/4c01589b/4c01589b_mus_model.json b/resources/piece_ledger_transcribe_test/4c01589b/4c01589b_mus_model.json deleted file mode 100644 index 436b630..0000000 --- a/resources/piece_ledger_transcribe_test/4c01589b/4c01589b_mus_model.json +++ /dev/null @@ -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 ] -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/5397abab/5397abab_code.scd b/resources/piece_ledger_transcribe_test/5397abab/5397abab_code.scd deleted file mode 100644 index 26709a0..0000000 --- a/resources/piece_ledger_transcribe_test/5397abab/5397abab_code.scd +++ /dev/null @@ -1,1058 +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, genStepFunc; - -// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, -orders, susWeights, orderSize, passagesSize, -motifEdited, orderEdited; - -// model aux vars -var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; - -// 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) - stepFunc.value(pDistance); -}; - -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); -}; - -genStepFunc = {arg minStep, maxStep, envData, seed; - var envDataNorm, env, pTable, stepFunc; - [minStep, maxStep, envData].postln; - envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; - envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; - env = Env.pairs(envDataNorm); - stepFunc = {arg pDist; - env.at(pDist).clip(0.001, 1); - }; - seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); - if(hdInvert == 0, {hdScore = 1/hdScore}); - //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, fDur, durAdd; - - 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); - }); - - //round last duration to measure - fDur = fSeq.flatten.flatten.slice(nil, 1).sum; - durAdd = fDur.round(4) - fDur; - if(durAdd < 0, {durAdd = 4 - durAdd}); - fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; - - 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.notNil) { - ~msg; - ~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.0, 3.0)}, {rrand(0.3, 0.5)}); - }); - rels = rels.add(rrand(1.0, 3.0)); - 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; - }, { - var tmpRes; - if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); - if(res.contains("."), {tmpRes = res.asFloat}); - if(tmpRes != nil, {res = tmpRes}); - }); - }); - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", - "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)); - }); - - stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); - 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)); - //~seq = seq; - - addr.sendMsg("/generated", path, modelString, ledgerPath); -}, \generate); - - -OSCdef(\commit, {arg msg, time, addr, port; - var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; - //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; - commitType = msg[2].asString; - commitPos = msg[3].postln.asInteger; - - lastCurUID = curUID.deepCopy; - 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); - - /* - if(commitType == "add", { - if(lastCurUID == "tmp", { - ledger = ledger.drop(-1).add(curUID); - }, { - ledger = ledger.add(curUID); - }) - }); - */ - - ledger.postln; - - if(commitType == "add", {ledger = ledger.add(curUID)}); - - if(commitType == "insert", {ledger = ledger.insert(commitPos, curUID)}); - - if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); - - equalityLedger = ledger.collect({arg item; item.asSymbol}); - if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); - - ledger.postln; - - 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); - - -OSCdef(\transcribe_motif, {arg msg, time, addr, port; - var tSeq, refChord, refUID; - - msg.postln; - - tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; - refUID = msg[2].asString.postln; - - if((refUID != "nil") && (refUID != "tmp"), { - var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }, { - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - }); - - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); -}, \transcribe_motif); - - -OSCdef(\transcribe_all, {arg msg, time, addr, port; - var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; - if(true, { - cuedSeek = (seq != nil); - indexStart = msg[1].asInteger; - indexEnd = ledger.size - if(cuedSeek, {2}, {1}); - - //tmp for testing transcription - indexEnd = (indexStart+5); - - //ledger.postln; - if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { - var lilyPartLedgerFiles; - - lilyPartLedgerFiles = 4.collect({arg p; - File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); - }); - - ledger[indexStart..indexEnd].do({arg uid, index; - var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - fileString = file.readAllString; - tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); - refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); - file.close; - - //uid.postln; - //(refUID == "nil").postln; - - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - - if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }); - - if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); - }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); - }); - - lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); - }); - - }); - - lilyPartLedgerFiles.do({arg f; - f.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; - }); - */ - }, { - - }); - -}, \transcribe_all); - -) - -~transcribe.value(~seq, dir); - -( -//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; - - 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; -) -*/ - diff --git a/resources/piece_ledger_transcribe_test/5397abab/5397abab_mus_model.json b/resources/piece_ledger_transcribe_test/5397abab/5397abab_mus_model.json deleted file mode 100644 index b73001d..0000000 --- a/resources/piece_ledger_transcribe_test/5397abab/5397abab_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/54479f3d/54479f3d_mus_model.json b/resources/piece_ledger_transcribe_test/54479f3d/54479f3d_mus_model.json deleted file mode 100644 index f8b9c8e..0000000 --- a/resources/piece_ledger_transcribe_test/54479f3d/54479f3d_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/57fa6a01/57fa6a01_mus_model.json b/resources/piece_ledger_transcribe_test/57fa6a01/57fa6a01_mus_model.json deleted file mode 100644 index 90e5de8..0000000 --- a/resources/piece_ledger_transcribe_test/57fa6a01/57fa6a01_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/5cd72e22/5cd72e22_code.scd b/resources/piece_ledger_transcribe_test/5cd72e22/5cd72e22_code.scd deleted file mode 100644 index b638147..0000000 --- a/resources/piece_ledger_transcribe_test/5cd72e22/5cd72e22_code.scd +++ /dev/null @@ -1,1058 +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, genStepFunc; - -// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, -orders, susWeights, orderSize, passagesSize, -motifEdited, orderEdited; - -// model aux vars -var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; - -// 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) - stepFunc.value(pDistance); -}; - -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); -}; - -genStepFunc = {arg minStep, maxStep, envData, seed; - var envDataNorm, env, pTable, stepFunc; - [minStep, maxStep, envData].postln; - envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; - envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; - env = Env.pairs(envDataNorm); - stepFunc = {arg pDist; - env.at(pDist).clip(0.001, 1); - }; - seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); - if(hdInvert == 0, {hdScore = 1/hdScore}); - //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, fDur, durAdd; - - 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); - }); - - //round last duration to measure - fDur = fSeq.flatten.flatten.slice(nil, 1).sum; - durAdd = fDur.round(4) - fDur; - if(durAdd < 0, {durAdd = 4 - durAdd}); - fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; - - 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.notNil) { - ~msg; - ~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.0, 3.0)}, {rrand(0.3, 0.5)}); - }); - rels = rels.add(rrand(1.0, 3.0)); - 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; - }, { - var tmpRes; - if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); - if(res.contains("."), {tmpRes = res.asFloat}); - if(tmpRes != nil, {res = tmpRes}); - }); - }); - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", - "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)); - }); - - stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); - 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)); - //~seq = seq; - - addr.sendMsg("/generated", path, modelString, ledgerPath); -}, \generate); - - -OSCdef(\commit, {arg msg, time, addr, port; - var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; - //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; - commitType = msg[2].asString; - commitPos = msg[3].postln.asInteger; - - lastCurUID = curUID.deepCopy; - 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); - - /* - if(commitType == "add", { - if(lastCurUID == "tmp", { - ledger = ledger.drop(-1).add(curUID); - }, { - ledger = ledger.add(curUID); - }) - }); - */ - - ledger.postln; - - if(commitType == "add", {ledger = ledger.add(curUID)}); - - if(commitType == "insert", {ledger = ledger.insert(commitPos - 1, curUID)}); - - if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); - - equalityLedger = ledger.collect({arg item; item.asSymbol}); - if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); - - ledger.postln; - - 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); - - -OSCdef(\transcribe_motif, {arg msg, time, addr, port; - var tSeq, refChord, refUID; - - msg.postln; - - tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; - refUID = msg[2].asString.postln; - - if((refUID != "nil") && (refUID != "tmp"), { - var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }, { - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - }); - - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); -}, \transcribe_motif); - - -OSCdef(\transcribe_all, {arg msg, time, addr, port; - var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; - if(true, { - cuedSeek = (seq != nil); - indexStart = msg[1].asInteger; - indexEnd = ledger.size - if(cuedSeek, {2}, {1}); - - //tmp for testing transcription - indexEnd = (indexStart+5); - - //ledger.postln; - if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { - var lilyPartLedgerFiles; - - lilyPartLedgerFiles = 4.collect({arg p; - File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); - }); - - ledger[indexStart..indexEnd].do({arg uid, index; - var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - fileString = file.readAllString; - tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); - refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); - file.close; - - //uid.postln; - //(refUID == "nil").postln; - - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - - if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }); - - if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); - }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); - }); - - lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); - }); - - }); - - lilyPartLedgerFiles.do({arg f; - f.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; - }); - */ - }, { - - }); - -}, \transcribe_all); - -) - -~transcribe.value(~seq, dir); - -( -//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; - - 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; -) -*/ - diff --git a/resources/piece_ledger_transcribe_test/5cd72e22/5cd72e22_mus_model.json b/resources/piece_ledger_transcribe_test/5cd72e22/5cd72e22_mus_model.json deleted file mode 100644 index 058c7ca..0000000 --- a/resources/piece_ledger_transcribe_test/5cd72e22/5cd72e22_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/600e3005/600e3005_mus_model.json b/resources/piece_ledger_transcribe_test/600e3005/600e3005_mus_model.json deleted file mode 100644 index 1fa4af0..0000000 --- a/resources/piece_ledger_transcribe_test/600e3005/600e3005_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/640eeed3/640eeed3_code.scd b/resources/piece_ledger_transcribe_test/640eeed3/640eeed3_code.scd deleted file mode 100644 index af06ede..0000000 --- a/resources/piece_ledger_transcribe_test/640eeed3/640eeed3_code.scd +++ /dev/null @@ -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"); \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/640eeed3/640eeed3_mus_model.json b/resources/piece_ledger_transcribe_test/640eeed3/640eeed3_mus_model.json deleted file mode 100644 index 79d175f..0000000 --- a/resources/piece_ledger_transcribe_test/640eeed3/640eeed3_mus_model.json +++ /dev/null @@ -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 ] -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/674b56e3/674b56e3_mus_model.json b/resources/piece_ledger_transcribe_test/674b56e3/674b56e3_mus_model.json deleted file mode 100644 index 89b468a..0000000 --- a/resources/piece_ledger_transcribe_test/674b56e3/674b56e3_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/688ee3e1/688ee3e1_code.scd b/resources/piece_ledger_transcribe_test/688ee3e1/688ee3e1_code.scd deleted file mode 100644 index b638147..0000000 --- a/resources/piece_ledger_transcribe_test/688ee3e1/688ee3e1_code.scd +++ /dev/null @@ -1,1058 +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, genStepFunc; - -// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, -orders, susWeights, orderSize, passagesSize, -motifEdited, orderEdited; - -// model aux vars -var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; - -// 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) - stepFunc.value(pDistance); -}; - -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); -}; - -genStepFunc = {arg minStep, maxStep, envData, seed; - var envDataNorm, env, pTable, stepFunc; - [minStep, maxStep, envData].postln; - envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; - envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; - env = Env.pairs(envDataNorm); - stepFunc = {arg pDist; - env.at(pDist).clip(0.001, 1); - }; - seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); - if(hdInvert == 0, {hdScore = 1/hdScore}); - //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, fDur, durAdd; - - 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); - }); - - //round last duration to measure - fDur = fSeq.flatten.flatten.slice(nil, 1).sum; - durAdd = fDur.round(4) - fDur; - if(durAdd < 0, {durAdd = 4 - durAdd}); - fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; - - 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.notNil) { - ~msg; - ~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.0, 3.0)}, {rrand(0.3, 0.5)}); - }); - rels = rels.add(rrand(1.0, 3.0)); - 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; - }, { - var tmpRes; - if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); - if(res.contains("."), {tmpRes = res.asFloat}); - if(tmpRes != nil, {res = tmpRes}); - }); - }); - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", - "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)); - }); - - stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); - 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)); - //~seq = seq; - - addr.sendMsg("/generated", path, modelString, ledgerPath); -}, \generate); - - -OSCdef(\commit, {arg msg, time, addr, port; - var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; - //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; - commitType = msg[2].asString; - commitPos = msg[3].postln.asInteger; - - lastCurUID = curUID.deepCopy; - 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); - - /* - if(commitType == "add", { - if(lastCurUID == "tmp", { - ledger = ledger.drop(-1).add(curUID); - }, { - ledger = ledger.add(curUID); - }) - }); - */ - - ledger.postln; - - if(commitType == "add", {ledger = ledger.add(curUID)}); - - if(commitType == "insert", {ledger = ledger.insert(commitPos - 1, curUID)}); - - if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); - - equalityLedger = ledger.collect({arg item; item.asSymbol}); - if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); - - ledger.postln; - - 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); - - -OSCdef(\transcribe_motif, {arg msg, time, addr, port; - var tSeq, refChord, refUID; - - msg.postln; - - tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; - refUID = msg[2].asString.postln; - - if((refUID != "nil") && (refUID != "tmp"), { - var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }, { - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - }); - - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); -}, \transcribe_motif); - - -OSCdef(\transcribe_all, {arg msg, time, addr, port; - var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; - if(true, { - cuedSeek = (seq != nil); - indexStart = msg[1].asInteger; - indexEnd = ledger.size - if(cuedSeek, {2}, {1}); - - //tmp for testing transcription - indexEnd = (indexStart+5); - - //ledger.postln; - if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { - var lilyPartLedgerFiles; - - lilyPartLedgerFiles = 4.collect({arg p; - File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); - }); - - ledger[indexStart..indexEnd].do({arg uid, index; - var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - fileString = file.readAllString; - tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); - refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); - file.close; - - //uid.postln; - //(refUID == "nil").postln; - - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - - if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }); - - if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); - }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); - }); - - lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); - }); - - }); - - lilyPartLedgerFiles.do({arg f; - f.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; - }); - */ - }, { - - }); - -}, \transcribe_all); - -) - -~transcribe.value(~seq, dir); - -( -//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; - - 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; -) -*/ - diff --git a/resources/piece_ledger_transcribe_test/688ee3e1/688ee3e1_mus_model.json b/resources/piece_ledger_transcribe_test/688ee3e1/688ee3e1_mus_model.json deleted file mode 100644 index fc848a7..0000000 --- a/resources/piece_ledger_transcribe_test/688ee3e1/688ee3e1_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/75638b4d/75638b4d_mus_model.json b/resources/piece_ledger_transcribe_test/75638b4d/75638b4d_mus_model.json deleted file mode 100644 index 17ba0f5..0000000 --- a/resources/piece_ledger_transcribe_test/75638b4d/75638b4d_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/7ac10d34/7ac10d34_code.scd b/resources/piece_ledger_transcribe_test/7ac10d34/7ac10d34_code.scd deleted file mode 100644 index 65c17df..0000000 --- a/resources/piece_ledger_transcribe_test/7ac10d34/7ac10d34_code.scd +++ /dev/null @@ -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"); \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/7ac10d34/7ac10d34_gui_state.json b/resources/piece_ledger_transcribe_test/7ac10d34/7ac10d34_gui_state.json deleted file mode 100644 index 84e6edd..0000000 --- a/resources/piece_ledger_transcribe_test/7ac10d34/7ac10d34_gui_state.json +++ /dev/null @@ -1,1359 +0,0 @@ -{ - "motif_label": "motif", - "seeds_label": "seeds", - "order": "[\n [ [ 3, 1, 0 ], [ 2 ], [ ] ],\n [ [ 1, 2 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 3 ] ],\n [ [ 3, 2 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], [ 0 ] ],\n [ [ 2, 3 ], [ 0, 1, 0 ], [ ] ]\n]", - "order_lock": 1, - "order_size": [ - 3, - 8 - ], - "order_size_v2": 8, - "order_size_v1": 3, - "order_size_panel": -1, - "passage_size_v2": 8, - "passage_size_v1": 2, - "passage_size_panel": -1, - "sus_weights": [ - null, - null, - null - ], - "range_matrix": [ - null, - null, - null, - null - ], - "instrumentation": [ - 0, - 0 - ], - "entrances_probs_sync": "passages", - "entrances": -1, - "passages_probs_sync": "passages", - "passages": -1, - "exits_probs_sync": "passages", - "exits": -1, - "dur_panel": 0, - "durations": -1, - "passages_weights": [ - null, - null, - null, - null, - null - ], - "weights": -1, - "seeds_tab_panel": 0, - "weights_seed_lock": 0, - "weights_seed": 534103, - "sus_weights/0_slider_val": 0.21, - "sus_weights/0_slider_slider": 0.21, - "sus_weights/0_slider_input": 0.21, - "sus_weights/0_slider_label": 1, - "sus_weights/0_slider": -1, - "sus_weights/1_slider_val": 0.35, - "sus_weights/1_slider_slider": 0.35, - "sus_weights/1_slider_input": 0.35, - "sus_weights/1_slider_label": 2, - "sus_weights/1_slider": -1, - "sus_weights/2_slider_val": 0.21, - "sus_weights/2_slider_slider": 0.21, - "sus_weights/2_slider_input": 0.21, - "sus_weights/2_slider_label": 3, - "sus_weights/2_slider": -1, - "passages_weights/0_slider_val": 0.49, - "passages_weights/0_slider_slider": 0.49, - "passages_weights/0_slider_input": 0.49, - "passages_weights/0_slider_label": "step", - "passages_weights/0_slider": -1, - "passages_weights/1_slider_val": 0.53, - "passages_weights/1_slider_slider": 0.53, - "passages_weights/1_slider_input": 0.53, - "passages_weights/1_slider_label": "dc", - "passages_weights/1_slider": -1, - "passages_weights/2_slider_val": 0.35, - "passages_weights/2_slider_slider": 0.35, - "passages_weights/2_slider_input": 0.35, - "passages_weights/2_slider_label": "range", - "passages_weights/2_slider": -1, - "passages_weights/3_slider_val": 0.59, - "passages_weights/3_slider_slider": 0.59, - "passages_weights/3_slider_input": 0.59, - "passages_weights/3_slider_label": "registration", - "passages_weights/3_slider": -1, - "passages_weights/4_slider_val": 0.39, - "passages_weights/4_slider_slider": 0.39, - "passages_weights/4_slider_input": 0.39, - "passages_weights/4_slider_label": "hd", - "passages_weights/4_slider": -1, - "range_matrix/0_val_input_min": -853.2067988668555, - "range_matrix/0_val_rslider": [ - -853.2067988668555, - 401 - ], - "range_matrix/0_val_input_max": 401, - "range_matrix/0_val": -1, - "range_matrix/1_val_input_min": -659, - "range_matrix/1_val_rslider": [ - -659, - 880 - ], - "range_matrix/1_val_input_max": 880, - "range_matrix/1_val": -1, - "range_matrix/2_val_input_min": -241, - "range_matrix/2_val_rslider": [ - -241, - 1869 - ], - "range_matrix/2_val_input_max": 1869, - "range_matrix/2_val": -1, - "range_matrix/3_val_input_min": -27, - "range_matrix/3_val_rslider": [ - -27, - 2063 - ], - "range_matrix/3_val_input_max": 2063, - "range_matrix/3_val": -1, - "entrances_probs_chord_slider_val": 0.66, - "entrances_probs_chord_slider_slider": 0.66, - "entrances_probs_chord_slider_input": 0.66, - "entrances_probs_chord_slider_label": "chord prob", - "entrances_probs_chord_slider": -1, - "entrances_probs_vals": [ - 0.63, - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.3963730569948187, - 0.8716216216216216, - 0.4948186528497409, - 0.5912162162162162, - 0.5362694300518135, - 0.8614864864864865, - 0.6424870466321243, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "entrances_probs": -1, - "passages_probs_chord_slider_val": 0.63, - "passages_probs_chord_slider_slider": 0.63, - "passages_probs_chord_slider_input": 0.63, - "passages_probs_chord_slider_label": "chord prob", - "passages_probs_chord_slider": -1, - "passages_probs_vals": [ - 0.63, - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.3963730569948187, - 0.8716216216216216, - 0.4948186528497409, - 0.5912162162162162, - 0.5362694300518135, - 0.8614864864864865, - 0.6424870466321243, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "passages_probs": -1, - "exits_probs_chord_slider_val": 0, - "exits_probs_chord_slider_slider": 0, - "exits_probs_chord_slider_input": 0, - "exits_probs_chord_slider_label": "chord prob", - "exits_probs_chord_slider": -1, - "exits_probs_vals": [ - 0, - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.4948186528497409, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "exits_probs": -1, - "step_env_env_vals": [ - 0, - 5, - 0, - 0, - 0, - 0, - 0.14609053497942387, - 0.7613636363636364, - 0.20164609053497942, - 0.26136363636363635, - 0.24279835390946503, - 0.7215909090909092, - 0.39094650205761317, - 0.875, - 0.4567901234567901, - 0.44318181818181823, - 0.5432098765432098, - 0.34659090909090906, - 0.6481481481481481, - 0.8011363636363636, - 0.6810699588477366, - 0.5170454545454546, - 0.8868312757201646, - 0.49431818181818177, - 0.8868312757201646, - 0.49431818181818177 - ], - "step_env_env_canvas": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0.14609053497942387, - 0.7613636363636364 - ], - [ - 0.20164609053497942, - 0.26136363636363635 - ], - [ - 0.24279835390946503, - 0.7215909090909092 - ], - [ - 0.39094650205761317, - 0.875 - ], - [ - 0.4567901234567901, - 0.44318181818181823 - ], - [ - 0.5432098765432098, - 0.34659090909090906 - ], - [ - 0.6481481481481481, - 0.8011363636363636 - ], - [ - 0.6810699588477366, - 0.5170454545454546 - ], - [ - 0.8868312757201646, - 0.49431818181818177 - ], - [ - 0.8868312757201646, - 0.49431818181818177 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "step_env_env_size": 12, - "step_env_env_flatten": 0, - "step_env_env_rslider": [ - 0, - 5 - ], - "step_env_env_rslider_v2": 5, - "step_env_env_rslider_v1": 0, - "step_env_env_mpos": "", - "step_env_env": -1, - "entrances_probs_dur_env_vals": [ - 0.515267175572519, - 4.599236641221374, - 0, - 0.5, - 0.2772020725388601, - 0.7972972972972973, - 0.45077720207253885, - 0.8783783783783784, - 0.5, - 0.5, - 0.727979274611399, - 0.45270270270270274, - 0.7357512953367875, - 0.6486486486486487, - 0.8911917098445595, - 0.7905405405405406, - 1, - 0.5 - ], - "entrances_probs_dur_env_canvas": [ - [ - 0, - 0.5 - ], - [ - 0.2772020725388601, - 0.7972972972972973 - ], - [ - 0.45077720207253885, - 0.8783783783783784 - ], - [ - 0.5, - 0.5 - ], - [ - 0.727979274611399, - 0.45270270270270274 - ], - [ - 0.7357512953367875, - 0.6486486486486487 - ], - [ - 0.8911917098445595, - 0.7905405405405406 - ], - [ - 1, - 0.5 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "entrances_probs_dur_env_size": 8, - "entrances_probs_dur_env_flatten": 0, - "entrances_probs_dur_env_rslider": [ - 0.515267175572519, - 4.599236641221374 - ], - "entrances_probs_dur_env_rslider_v2": 4.599236641221374, - "entrances_probs_dur_env_rslider_v1": 0.515267175572519, - "entrances_probs_dur_env_mpos": "", - "entrances_probs_dur_env": -1, - "passages_probs_dur_env_vals": [ - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.3963730569948187, - 0.8716216216216216, - 0.4948186528497409, - 0.5912162162162162, - 0.5362694300518135, - 0.8614864864864865, - 0.6424870466321243, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "passages_probs_dur_env_canvas": [ - [ - 0, - 0.5 - ], - [ - 0.23316062176165803, - 0.7094594594594594 - ], - [ - 0.3963730569948187, - 0.8716216216216216 - ], - [ - 0.4948186528497409, - 0.5912162162162162 - ], - [ - 0.5362694300518135, - 0.8614864864864865 - ], - [ - 0.6424870466321243, - 0.5912162162162162 - ], - [ - 0.7901554404145078, - 0.8277027027027027 - ], - [ - 1, - 0.5 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "passages_probs_dur_env_size": 8, - "passages_probs_dur_env_flatten": 0, - "passages_probs_dur_env_rslider": [ - 0, - 5 - ], - "passages_probs_dur_env_rslider_v2": 5, - "passages_probs_dur_env_rslider_v1": 0, - "passages_probs_dur_env_mpos": "", - "passages_probs_dur_env": -1, - "exits_probs_dur_env_vals": [ - 0, - 5, - 0, - 0.5, - 0.5, - 0.5, - 1, - 0.5 - ], - "exits_probs_dur_env_canvas": [ - [ - 0, - 0.5 - ], - [ - 0.5, - 0.5 - ], - [ - 1, - 0.5 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "exits_probs_dur_env_size": 3, - "exits_probs_dur_env_flatten": 0, - "exits_probs_dur_env_rslider": [ - 0, - 5 - ], - "exits_probs_dur_env_rslider_v2": 5, - "exits_probs_dur_env_rslider_v1": 0, - "exits_probs_dur_env_mpos": "", - "exits_probs_dur_env": -1, - "mus_seq": [ - [ - [ - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - "Rest" - ], - [ - "Rest" - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - "Rest" - ] - ], - 1.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - 0, - 1, - -3, - 0, - 2, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.75 - ], - [ - [ - [ - 1, - 1, - -2, - -2, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.625 - ], - [ - [ - [ - 1, - 1, - -3, - -1, - 0, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.625 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ] - ], - [ - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -2, - 0, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.375 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 2, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -2, - -1, - 2, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 0, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.875 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1 - ] - ], - [ - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 2, - 0, - -3, - -1, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.625 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - "Rest" - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - "Rest" - ] - ], - 1.875 - ], - [ - [ - [ - "Rest" - ], - [ - "Rest" - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - "Rest" - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - "Rest" - ], - [ - "Rest" - ], - [ - "Rest" - ] - ], - 0.875 - ] - ] - ] - ], - "root": [ - 0.20743639921722112, - 0 - ], - "order_seed": 798574, - "dur_seed": 884869, - "passages_size": [ - 0, - 10 - ], - "dur_seed_lock": 1, - "order_seed_lock": 0, - "seeds_panel": -1, - "motif_panel": [ - 0, - 0 - ], - "ref_uid": "6f1a789f", - "cur_uid": "7ac10d34" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/7ac10d34/7ac10d34_mus_model.json b/resources/piece_ledger_transcribe_test/7ac10d34/7ac10d34_mus_model.json deleted file mode 100644 index 73f197b..0000000 --- a/resources/piece_ledger_transcribe_test/7ac10d34/7ac10d34_mus_model.json +++ /dev/null @@ -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 ] -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/7bfea52f/7bfea52f_code.scd b/resources/piece_ledger_transcribe_test/7bfea52f/7bfea52f_code.scd deleted file mode 100644 index 662c461..0000000 --- a/resources/piece_ledger_transcribe_test/7bfea52f/7bfea52f_code.scd +++ /dev/null @@ -1,1056 +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, genStepFunc; - -// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, -orders, susWeights, orderSize, passagesSize, -motifEdited, orderEdited; - -// model aux vars -var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; - -// 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) - stepFunc.value(pDistance); -}; - -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); -}; - -genStepFunc = {arg minStep, maxStep, envData, seed; - var envDataNorm, env, pTable, stepFunc; - [minStep, maxStep, envData].postln; - envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; - envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; - env = Env.pairs(envDataNorm); - stepFunc = {arg pDist; - env.at(pDist).clip(0.001, 1); - }; - seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); - if(hdInvert == 0, {hdScore = 1/hdScore}); - //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, fDur, durAdd; - - 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); - }); - - //round last duration to measure - fDur = fSeq.flatten.flatten.slice(nil, 1).sum; - durAdd = fDur.round(4) - fDur; - if(durAdd < 0, {durAdd = 4 - durAdd}); - fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; - - 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.notNil) { - ~msg; - ~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.0, 3.0)}, {rrand(0.3, 0.5)}); - }); - rels = rels.add(rrand(1.0, 3.0)); - 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; - }, { - var tmpRes; - if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); - if(res.contains("."), {tmpRes = res.asFloat}); - if(tmpRes != nil, {res = tmpRes}); - }); - }); - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", - "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)); - }); - - stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); - 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)); - //~seq = seq; - - addr.sendMsg("/generated", path, modelString, ledgerPath); -}, \generate); - - -OSCdef(\commit, {arg msg, time, addr, port; - var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; - //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; - commitType = msg[2].asString; - commitPos = msg[3].postln.asInteger; - - lastCurUID = curUID.deepCopy; - 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); - - /* - if(commitType == "add", { - if(lastCurUID == "tmp", { - ledger = ledger.drop(-1).add(curUID); - }, { - ledger = ledger.add(curUID); - }) - }); - */ - - ledger.postln; - - if(commitType == "add", {ledger = ledger.add(curUID)}); - - if(commitType == "insert", {ledger = ledger.insert(commitPos - 1, curUID)}); - - if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); - - equalityLedger = ledger.collect({arg item; item.asSymbol}); - if(equalityLedger.includes("tmp").postln, {ledger = ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); - - 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); - - -OSCdef(\transcribe_motif, {arg msg, time, addr, port; - var tSeq, refChord, refUID; - - msg.postln; - - tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; - refUID = msg[2].asString.postln; - - if((refUID != "nil") && (refUID != "tmp"), { - var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }, { - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - }); - - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); -}, \transcribe_motif); - - -OSCdef(\transcribe_all, {arg msg, time, addr, port; - var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; - if(true, { - cuedSeek = (seq != nil); - indexStart = msg[1].asInteger; - indexEnd = ledger.size - if(cuedSeek, {2}, {1}); - - //tmp for testing transcription - indexEnd = (indexStart+5); - - //ledger.postln; - if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { - var lilyPartLedgerFiles; - - lilyPartLedgerFiles = 4.collect({arg p; - File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); - }); - - ledger[indexStart..indexEnd].do({arg uid, index; - var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - fileString = file.readAllString; - tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); - refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); - file.close; - - //uid.postln; - //(refUID == "nil").postln; - - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - - if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }); - - if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); - }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); - }); - - lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); - }); - - }); - - lilyPartLedgerFiles.do({arg f; - f.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; - }); - */ - }, { - - }); - -}, \transcribe_all); - -) - -~transcribe.value(~seq, dir); - -( -//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; - - 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; -) -*/ - diff --git a/resources/piece_ledger_transcribe_test/7bfea52f/7bfea52f_mus_model.json b/resources/piece_ledger_transcribe_test/7bfea52f/7bfea52f_mus_model.json deleted file mode 100644 index 5791c40..0000000 --- a/resources/piece_ledger_transcribe_test/7bfea52f/7bfea52f_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/7e170ef8/7e170ef8_code.scd b/resources/piece_ledger_transcribe_test/7e170ef8/7e170ef8_code.scd deleted file mode 100644 index b11446a..0000000 --- a/resources/piece_ledger_transcribe_test/7e170ef8/7e170ef8_code.scd +++ /dev/null @@ -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"); \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/7e170ef8/7e170ef8_gui_state.json b/resources/piece_ledger_transcribe_test/7e170ef8/7e170ef8_gui_state.json deleted file mode 100644 index 704cf3a..0000000 --- a/resources/piece_ledger_transcribe_test/7e170ef8/7e170ef8_gui_state.json +++ /dev/null @@ -1,1359 +0,0 @@ -{ - "motif_label": "motif", - "seeds_label": "seeds", - "order": "[\n [ [ 3, 1, 0 ], [ 2 ], [ ] ],\n [ [ 1, 2 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 3 ] ],\n [ [ 3, 2 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], [ 0 ] ],\n [ [ 2, 3 ], [ 0, 1, 0 ], [ ] ]\n]", - "order_lock": 1, - "order_size": [ - 3, - 8 - ], - "order_size_v2": 8, - "order_size_v1": 3, - "order_size_panel": -1, - "passage_size_v2": 8, - "passage_size_v1": 2, - "passage_size_panel": -1, - "sus_weights": [ - null, - null, - null - ], - "range_matrix": [ - null, - null, - null, - null - ], - "instrumentation": [ - 0, - 0 - ], - "entrances_probs_sync": "passages", - "entrances": -1, - "passages_probs_sync": "passages", - "passages": -1, - "exits_probs_sync": "passages", - "exits": -1, - "dur_panel": 0, - "durations": -1, - "passages_weights": [ - null, - null, - null, - null, - null - ], - "weights": -1, - "seeds_tab_panel": 0, - "weights_seed_lock": 0, - "weights_seed": 534103, - "sus_weights/0_slider_val": 0.21, - "sus_weights/0_slider_slider": 0.21, - "sus_weights/0_slider_input": 0.21, - "sus_weights/0_slider_label": 1, - "sus_weights/0_slider": -1, - "sus_weights/1_slider_val": 0.35, - "sus_weights/1_slider_slider": 0.35, - "sus_weights/1_slider_input": 0.35, - "sus_weights/1_slider_label": 2, - "sus_weights/1_slider": -1, - "sus_weights/2_slider_val": 0.21, - "sus_weights/2_slider_slider": 0.21, - "sus_weights/2_slider_input": 0.21, - "sus_weights/2_slider_label": 3, - "sus_weights/2_slider": -1, - "passages_weights/0_slider_val": 0.49, - "passages_weights/0_slider_slider": 0.49, - "passages_weights/0_slider_input": 0.49, - "passages_weights/0_slider_label": "step", - "passages_weights/0_slider": -1, - "passages_weights/1_slider_val": 0.53, - "passages_weights/1_slider_slider": 0.53, - "passages_weights/1_slider_input": 0.53, - "passages_weights/1_slider_label": "dc", - "passages_weights/1_slider": -1, - "passages_weights/2_slider_val": 0.35, - "passages_weights/2_slider_slider": 0.35, - "passages_weights/2_slider_input": 0.35, - "passages_weights/2_slider_label": "range", - "passages_weights/2_slider": -1, - "passages_weights/3_slider_val": 0.59, - "passages_weights/3_slider_slider": 0.59, - "passages_weights/3_slider_input": 0.59, - "passages_weights/3_slider_label": "registration", - "passages_weights/3_slider": -1, - "passages_weights/4_slider_val": 0.39, - "passages_weights/4_slider_slider": 0.39, - "passages_weights/4_slider_input": 0.39, - "passages_weights/4_slider_label": "hd", - "passages_weights/4_slider": -1, - "range_matrix/0_val_input_min": -853.2067988668555, - "range_matrix/0_val_rslider": [ - -853.2067988668555, - 401 - ], - "range_matrix/0_val_input_max": 401, - "range_matrix/0_val": -1, - "range_matrix/1_val_input_min": -659, - "range_matrix/1_val_rslider": [ - -659, - 880 - ], - "range_matrix/1_val_input_max": 880, - "range_matrix/1_val": -1, - "range_matrix/2_val_input_min": -241, - "range_matrix/2_val_rslider": [ - -241, - 1869 - ], - "range_matrix/2_val_input_max": 1869, - "range_matrix/2_val": -1, - "range_matrix/3_val_input_min": -27, - "range_matrix/3_val_rslider": [ - -27, - 2063 - ], - "range_matrix/3_val_input_max": 2063, - "range_matrix/3_val": -1, - "entrances_probs_chord_slider_val": 0.66, - "entrances_probs_chord_slider_slider": 0.66, - "entrances_probs_chord_slider_input": 0.66, - "entrances_probs_chord_slider_label": "chord prob", - "entrances_probs_chord_slider": -1, - "entrances_probs_vals": [ - 0.63, - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.3963730569948187, - 0.8716216216216216, - 0.4948186528497409, - 0.5912162162162162, - 0.5362694300518135, - 0.8614864864864865, - 0.6424870466321243, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "entrances_probs": -1, - "passages_probs_chord_slider_val": 0.63, - "passages_probs_chord_slider_slider": 0.63, - "passages_probs_chord_slider_input": 0.63, - "passages_probs_chord_slider_label": "chord prob", - "passages_probs_chord_slider": -1, - "passages_probs_vals": [ - 0.63, - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.3963730569948187, - 0.8716216216216216, - 0.4948186528497409, - 0.5912162162162162, - 0.5362694300518135, - 0.8614864864864865, - 0.6424870466321243, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "passages_probs": -1, - "exits_probs_chord_slider_val": 0, - "exits_probs_chord_slider_slider": 0, - "exits_probs_chord_slider_input": 0, - "exits_probs_chord_slider_label": "chord prob", - "exits_probs_chord_slider": -1, - "exits_probs_vals": [ - 0, - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.4948186528497409, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "exits_probs": -1, - "step_env_env_vals": [ - 0, - 5, - 0, - 0, - 0, - 0, - 0.14609053497942387, - 0.7613636363636364, - 0.20164609053497942, - 0.26136363636363635, - 0.24279835390946503, - 0.7215909090909092, - 0.39094650205761317, - 0.875, - 0.4567901234567901, - 0.44318181818181823, - 0.5432098765432098, - 0.34659090909090906, - 0.6481481481481481, - 0.8011363636363636, - 0.6810699588477366, - 0.5170454545454546, - 0.8868312757201646, - 0.49431818181818177, - 0.8868312757201646, - 0.49431818181818177 - ], - "step_env_env_canvas": [ - [ - 0, - 0 - ], - [ - 0, - 0 - ], - [ - 0.14609053497942387, - 0.7613636363636364 - ], - [ - 0.20164609053497942, - 0.26136363636363635 - ], - [ - 0.24279835390946503, - 0.7215909090909092 - ], - [ - 0.39094650205761317, - 0.875 - ], - [ - 0.4567901234567901, - 0.44318181818181823 - ], - [ - 0.5432098765432098, - 0.34659090909090906 - ], - [ - 0.6481481481481481, - 0.8011363636363636 - ], - [ - 0.6810699588477366, - 0.5170454545454546 - ], - [ - 0.8868312757201646, - 0.49431818181818177 - ], - [ - 0.8868312757201646, - 0.49431818181818177 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "step_env_env_size": 12, - "step_env_env_flatten": 0, - "step_env_env_rslider": [ - 0, - 5 - ], - "step_env_env_rslider_v2": 5, - "step_env_env_rslider_v1": 0, - "step_env_env_mpos": "", - "step_env_env": -1, - "entrances_probs_dur_env_vals": [ - 0.515267175572519, - 4.599236641221374, - 0, - 0.5, - 0.2772020725388601, - 0.7972972972972973, - 0.45077720207253885, - 0.8783783783783784, - 0.5, - 0.5, - 0.727979274611399, - 0.45270270270270274, - 0.7357512953367875, - 0.6486486486486487, - 0.8911917098445595, - 0.7905405405405406, - 1, - 0.5 - ], - "entrances_probs_dur_env_canvas": [ - [ - 0, - 0.5 - ], - [ - 0.2772020725388601, - 0.7972972972972973 - ], - [ - 0.45077720207253885, - 0.8783783783783784 - ], - [ - 0.5, - 0.5 - ], - [ - 0.727979274611399, - 0.45270270270270274 - ], - [ - 0.7357512953367875, - 0.6486486486486487 - ], - [ - 0.8911917098445595, - 0.7905405405405406 - ], - [ - 1, - 0.5 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "entrances_probs_dur_env_size": 8, - "entrances_probs_dur_env_flatten": 0, - "entrances_probs_dur_env_rslider": [ - 0.515267175572519, - 4.599236641221374 - ], - "entrances_probs_dur_env_rslider_v2": 4.599236641221374, - "entrances_probs_dur_env_rslider_v1": 0.515267175572519, - "entrances_probs_dur_env_mpos": "", - "entrances_probs_dur_env": -1, - "passages_probs_dur_env_vals": [ - 0, - 5, - 0, - 0.5, - 0.23316062176165803, - 0.7094594594594594, - 0.3963730569948187, - 0.8716216216216216, - 0.4948186528497409, - 0.5912162162162162, - 0.5362694300518135, - 0.8614864864864865, - 0.6424870466321243, - 0.5912162162162162, - 0.7901554404145078, - 0.8277027027027027, - 1, - 0.5 - ], - "passages_probs_dur_env_canvas": [ - [ - 0, - 0.5 - ], - [ - 0.23316062176165803, - 0.7094594594594594 - ], - [ - 0.3963730569948187, - 0.8716216216216216 - ], - [ - 0.4948186528497409, - 0.5912162162162162 - ], - [ - 0.5362694300518135, - 0.8614864864864865 - ], - [ - 0.6424870466321243, - 0.5912162162162162 - ], - [ - 0.7901554404145078, - 0.8277027027027027 - ], - [ - 1, - 0.5 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "passages_probs_dur_env_size": 8, - "passages_probs_dur_env_flatten": 0, - "passages_probs_dur_env_rslider": [ - 0, - 5 - ], - "passages_probs_dur_env_rslider_v2": 5, - "passages_probs_dur_env_rslider_v1": 0, - "passages_probs_dur_env_mpos": "", - "passages_probs_dur_env": -1, - "exits_probs_dur_env_vals": [ - 0, - 5, - 0, - 0.5, - 0.5, - 0.5, - 1, - 0.5 - ], - "exits_probs_dur_env_canvas": [ - [ - 0, - 0.5 - ], - [ - 0.5, - 0.5 - ], - [ - 1, - 0.5 - ], - 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, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "exits_probs_dur_env_size": 3, - "exits_probs_dur_env_flatten": 0, - "exits_probs_dur_env_rslider": [ - 0, - 5 - ], - "exits_probs_dur_env_rslider_v2": 5, - "exits_probs_dur_env_rslider_v1": 0, - "exits_probs_dur_env_mpos": "", - "exits_probs_dur_env": -1, - "mus_seq": [ - [ - [ - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - "Rest" - ], - [ - "Rest" - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - "Rest" - ] - ], - 1.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - 0, - 1, - -3, - 0, - 2, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.75 - ], - [ - [ - [ - 1, - 1, - -2, - -2, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.625 - ], - [ - [ - [ - 1, - 1, - -3, - -1, - 0, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.625 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ] - ], - [ - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -3, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -2, - 0, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.375 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 2, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -2, - -1, - 2, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 0, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.875 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1 - ] - ], - [ - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 0 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 2, - 0, - -3, - -1, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.625 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - 1, - 1, - -2, - -1, - 0, - 0 - ] - ], - 1.75 - ], - [ - [ - [ - 1, - 0, - -3, - 0, - 1, - -1 - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - "Rest" - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - 1, - 1, - -2, - -1, - 1, - 0 - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - "Rest" - ] - ], - 1.875 - ], - [ - [ - [ - "Rest" - ], - [ - "Rest" - ], - [ - 0, - 1, - -1, - -1, - 1, - 0 - ], - [ - "Rest" - ] - ], - 0 - ], - [ - [ - [ - "Rest" - ], - [ - "Rest" - ], - [ - "Rest" - ], - [ - "Rest" - ] - ], - 0.875 - ] - ] - ] - ], - "root": [ - 0.20743639921722112, - 0 - ], - "order_seed": 798574, - "dur_seed": 884869, - "passages_size": [ - 0, - 10 - ], - "dur_seed_lock": 1, - "order_seed_lock": 0, - "seeds_panel": -1, - "motif_panel": [ - 0, - 0 - ], - "ref_uid": "6f1a789f", - "cur_uid": "7e170ef8" -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/7e170ef8/7e170ef8_mus_model.json b/resources/piece_ledger_transcribe_test/7e170ef8/7e170ef8_mus_model.json deleted file mode 100644 index c9b8807..0000000 --- a/resources/piece_ledger_transcribe_test/7e170ef8/7e170ef8_mus_model.json +++ /dev/null @@ -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 ] -} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/7e2c2e91/7e2c2e91_code.scd b/resources/piece_ledger_transcribe_test/7e2c2e91/7e2c2e91_code.scd deleted file mode 100644 index b638147..0000000 --- a/resources/piece_ledger_transcribe_test/7e2c2e91/7e2c2e91_code.scd +++ /dev/null @@ -1,1058 +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, genStepFunc; - -// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, -orders, susWeights, orderSize, passagesSize, -motifEdited, orderEdited; - -// model aux vars -var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; - -// 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) - stepFunc.value(pDistance); -}; - -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); -}; - -genStepFunc = {arg minStep, maxStep, envData, seed; - var envDataNorm, env, pTable, stepFunc; - [minStep, maxStep, envData].postln; - envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; - envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; - env = Env.pairs(envDataNorm); - stepFunc = {arg pDist; - env.at(pDist).clip(0.001, 1); - }; - seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); - if(hdInvert == 0, {hdScore = 1/hdScore}); - //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, fDur, durAdd; - - 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); - }); - - //round last duration to measure - fDur = fSeq.flatten.flatten.slice(nil, 1).sum; - durAdd = fDur.round(4) - fDur; - if(durAdd < 0, {durAdd = 4 - durAdd}); - fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; - - 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.notNil) { - ~msg; - ~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.0, 3.0)}, {rrand(0.3, 0.5)}); - }); - rels = rels.add(rrand(1.0, 3.0)); - 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; - }, { - var tmpRes; - if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); - if(res.contains("."), {tmpRes = res.asFloat}); - if(tmpRes != nil, {res = tmpRes}); - }); - }); - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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, stepProbsVals, passagesWeights, hdExp, hdInvert, - 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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", - "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)); - }); - - stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); - 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)); - //~seq = seq; - - addr.sendMsg("/generated", path, modelString, ledgerPath); -}, \generate); - - -OSCdef(\commit, {arg msg, time, addr, port; - var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; - //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; - commitType = msg[2].asString; - commitPos = msg[3].postln.asInteger; - - lastCurUID = curUID.deepCopy; - 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); - - /* - if(commitType == "add", { - if(lastCurUID == "tmp", { - ledger = ledger.drop(-1).add(curUID); - }, { - ledger = ledger.add(curUID); - }) - }); - */ - - ledger.postln; - - if(commitType == "add", {ledger = ledger.add(curUID)}); - - if(commitType == "insert", {ledger = ledger.insert(commitPos - 1, curUID)}); - - if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); - - equalityLedger = ledger.collect({arg item; item.asSymbol}); - if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); - - ledger.postln; - - 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); - - -OSCdef(\transcribe_motif, {arg msg, time, addr, port; - var tSeq, refChord, refUID; - - msg.postln; - - tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; - refUID = msg[2].asString.postln; - - if((refUID != "nil") && (refUID != "tmp"), { - var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }, { - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - }); - - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); -}, \transcribe_motif); - - -OSCdef(\transcribe_all, {arg msg, time, addr, port; - var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; - if(true, { - cuedSeek = (seq != nil); - indexStart = msg[1].asInteger; - indexEnd = ledger.size - if(cuedSeek, {2}, {1}); - - //tmp for testing transcription - indexEnd = (indexStart+5); - - //ledger.postln; - if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { - var lilyPartLedgerFiles; - - lilyPartLedgerFiles = 4.collect({arg p; - File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); - }); - - ledger[indexStart..indexEnd].do({arg uid, index; - var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - fileString = file.readAllString; - tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); - refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); - file.close; - - //uid.postln; - //(refUID == "nil").postln; - - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - - if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }); - - if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); - }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); - }); - - lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); - }); - - }); - - lilyPartLedgerFiles.do({arg f; - f.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; - }); - */ - }, { - - }); - -}, \transcribe_all); - -) - -~transcribe.value(~seq, dir); - -( -//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; - - 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; -) -*/ - diff --git a/resources/piece_ledger_transcribe_test/7e2c2e91/7e2c2e91_mus_model.json b/resources/piece_ledger_transcribe_test/7e2c2e91/7e2c2e91_mus_model.json deleted file mode 100644 index 431cc40..0000000 --- a/resources/piece_ledger_transcribe_test/7e2c2e91/7e2c2e91_mus_model.json +++ /dev/null @@ -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" -} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas.json b/resources/resources_bak_2024_01_03/piece_ledger_pas.json new file mode 100644 index 0000000..f04a134 --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas.json @@ -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" +] +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas.json_bak b/resources/resources_bak_2024_01_03/piece_ledger_pas.json_bak new file mode 100644 index 0000000..f69bd2d --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas.json_bak @@ -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" +] +} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates/314s49e1/314s49e1_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/314s49e1/314s49e1_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates/314s49e1/314s49e1_code.scd rename to resources/resources_bak_2024_01_03/piece_ledger_pas/314s49e1/314s49e1_code.scd diff --git a/resources/piece_ledger_sq1_candidates/314s49e1/314s49e1_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/314s49e1/314s49e1_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates/314s49e1/314s49e1_mus_model.json rename to resources/resources_bak_2024_01_03/piece_ledger_pas/314s49e1/314s49e1_mus_model.json diff --git a/resources/piece_ledger_transcribe_test/497509c8/497509c8_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/449aeaa6/449aeaa6_code.scd similarity index 82% rename from resources/piece_ledger_transcribe_test/497509c8/497509c8_code.scd rename to resources/resources_bak_2024_01_03/piece_ledger_pas/449aeaa6/449aeaa6_code.scd index ab2dc17..3ec9b1a 100644 --- a/resources/piece_ledger_transcribe_test/497509c8/497509c8_code.scd +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/449aeaa6/449aeaa6_code.scd @@ -6,7 +6,7 @@ var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; // subroutines -var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; // primary routines var genMotif, genSecondarySeq; @@ -24,12 +24,11 @@ setGlobalVars, globalVarsToDict, saveLedger; var seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, -ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, -orders, susWeights, orderSize, passagesSize, +ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited; // model aux vars -var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; +var entrancesDurFunc, passagesDurFunc, exitsDurFunc; // other global vars var popSize, exPath, dir, primes, dims, tuples, @@ -120,8 +119,7 @@ intervalScore = { arg hsArray1, hsArray2, mean, sd, signed = false; var pDistance; pDistance = pDist.value(hsArray1, hsArray2, signed); - //pDistance.gaussCurve(1, mean, sd) - stepFunc.value(pDistance); + pDistance.gaussCurve(1, mean, sd) }; inclusionScore = { @@ -173,18 +171,6 @@ genDurFunc = {arg chordProb, minPad, maxPad, minDur, maxDur, envData, seed; seedFunc.value(durFunc, seed); }; -genStepFunc = {arg minStep, maxStep, envData, seed; - var envDataNorm, env, pTable, stepFunc; - [minStep, maxStep, envData].postln; - envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; - envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; - env = Env.pairs(envDataNorm); - stepFunc = {arg pDist; - env.at(pDist).clip(0.001, 1); - }; - seedFunc.value(stepFunc, seed); -}; - genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; ((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; @@ -215,8 +201,7 @@ updateVoices = {arg ins, sus; 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); - if(hdInvert == 0, {hdScore = 1/hdScore}); + 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); @@ -306,7 +291,7 @@ genSubMotif = {arg order, orderIndex, lastState, repeatLast = false, startFromLa //------primary routines genMotif = { - var repeats, fSeq, fDur, durAdd; + var repeats, fSeq; repeats = 1; fSeq = []; @@ -328,13 +313,6 @@ genMotif = { fSeq = fSeq.add(motif); }); - - //round last duration to measure - fDur = fSeq.flatten.flatten.slice(nil, 1).sum; - durAdd = fDur.round(4) - fDur; - if(durAdd < 0, {durAdd = 4 - durAdd}); - fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; - fSeq }; @@ -370,8 +348,8 @@ Event.addEventType(\osc, { */ Event.addEventType(\osc, { - if (~addr.notNil) { - ~msg; + if (~addr.postln.notNil) { + ~msg.postln; ~addr.sendMsg(~path, *~msg); }; }); @@ -389,9 +367,8 @@ genPatterns = {arg inSeq, addr, oneShot = false; 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.0, 3.0)}, {rrand(0.3, 0.5)}); + if(clumps[c + 1][0] == ["Rest"], {rrand(1, 3)}, {rrand(0.3, 0.5)}); }); - rels = rels.add(rrand(1.0, 3.0)); amps = freqs.collect({rrand(0.6, 0.99)}); [ @@ -540,10 +517,8 @@ msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; res = res.replace("Rest", "\"Rest\""); res = res.interpret; }, { - var tmpRes; - if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); - if(res.contains("."), {tmpRes = res.asFloat}); - if(tmpRes != nil, {res = tmpRes}); + //res.postln; + if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); }); }); res @@ -557,8 +532,7 @@ writeResources = {arg path, dict; seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, - ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, - orders, susWeights, orderSize, passagesSize, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited ]; @@ -592,8 +566,7 @@ setGlobalVars = {arg dict, skipLastXChanges = false; // order really matters!!!! # seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, - ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, - orders, susWeights, orderSize, passagesSize, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited = nameSpaces.collect({arg nS; dict[nS]}); if(skipLastXChanges, {lastXChanges = tmpLastXChanges}); dict @@ -606,8 +579,7 @@ globalVarsToDict = { seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, - ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, - orders, susWeights, orderSize, passagesSize, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited ]; dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); @@ -646,8 +618,7 @@ loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); 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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", - "order", "sus_weights", "order_size", "passages_size", + "ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size", "motif_edited", "order_edited" ]; @@ -708,8 +679,6 @@ OSCdef(\generate, {arg msg, time, addr, port; orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); //addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); }); - - stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); seq = seedFunc.value(genMotif, motifSeed).value; lastXChanges.collect({arg item; item.postln}); @@ -718,14 +687,12 @@ OSCdef(\generate, {arg msg, time, addr, port; modelString = writeResources.value(path, dict); //addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); - //~seq = seq; - addr.sendMsg("/generated", path, modelString, ledgerPath); }, \generate); OSCdef(\commit, {arg msg, time, addr, port; - var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2; //msg.postln; /* @@ -738,9 +705,7 @@ OSCdef(\commit, {arg msg, time, addr, port; musicData = loadModelJSON.value(msg[1].asString.parseJSON)["music_data"].postln; musicChanged = (musicData != seq).postln; - commitType = msg[2].asString; - lastCurUID = curUID.deepCopy; curUID = genUID.value; File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); @@ -760,18 +725,7 @@ OSCdef(\commit, {arg msg, time, addr, port; File.delete(ledgerPath ++ "_bak"); File.copy(ledgerPath, ledgerPath ++ "_bak"); File.delete(ledgerPath); - - if(commitType == "add", { - if(lastCurUID == "tmp", { - ledger = ledger.drop(-1).add(curUID); - }, { - ledger = ledger.add(curUID); - }) - }); - - if(commitType == "insert", {ledger = ledger.insert(ledger.indexOf(lastCurUID), curUID)}); - - if(commitType == "replace", {ledger = ledger.put(ledger.indexOf(lastCurUID), curUID)}); + ledger = ledger.drop(-1).add(curUID); saveLedger.value(ledger, ledgerPath); @@ -824,102 +778,8 @@ OSCdef(\transport, {arg msg, time, addr, port; }); }, \transport); - -OSCdef(\transcribe_motif, {arg msg, time, addr, port; - var tSeq, refChord, refUID; - - msg.postln; - - tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; - refUID = msg[2].asString.postln; - - if((refUID != "nil") && (refUID != "tmp"), { - var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }, { - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - }); - - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); -}, \transcribe_motif); - - -OSCdef(\transcribe_all, {arg msg, time, addr, port; - var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; - if(true, { - cuedSeek = (seq != nil); - indexStart = msg[1].asInteger; - indexEnd = ledger.size - if(cuedSeek, {2}, {1}); - - //tmp for testing transcription - indexEnd = (indexStart+5); - - //ledger.postln; - if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { - var lilyPartLedgerFiles; - - lilyPartLedgerFiles = 4.collect({arg p; - File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); - }); - - ledger[indexStart..indexEnd].do({arg uid, index; - var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - fileString = file.readAllString; - tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); - refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); - file.close; - - //uid.postln; - //(refUID == "nil").postln; - - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - - if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }); - - if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); - }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); - }); - - lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); - }); - - }); - - lilyPartLedgerFiles.do({arg f; - f.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; - }); - */ - }, { - - }); - -}, \transcribe_all); - ) -~transcribe.value(~seq, dir); - ( //synthdefs ~stringModelBusArray = 4.collect({Bus.audio(s, 1)}); @@ -948,9 +808,15 @@ SynthDef(\sine, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; }).add; SynthDef(\mixer, {arg freq, gate = 1, sustain, amp, dur, out; - var nameSpaces, sigs; + 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; + 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)}); @@ -1002,25 +868,20 @@ SynthDef(\hdust, { ( 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 diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/449aeaa6/449aeaa6_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/449aeaa6/449aeaa6_mus_model.json new file mode 100644 index 0000000..dde9e73 --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/449aeaa6/449aeaa6_mus_model.json @@ -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" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/46210507/46210507_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/46210507/46210507_code.scd new file mode 100644 index 0000000..a4e8b56 --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/46210507/46210507_code.scd @@ -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; +) +*/ + diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/46210507/46210507_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/46210507/46210507_mus_model.json new file mode 100644 index 0000000..3ec4056 --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/46210507/46210507_mus_model.json @@ -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" +} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/4828752f/4828752f_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/4b96f62d/4b96f62d_code.scd similarity index 82% rename from resources/piece_ledger_transcribe_test/4828752f/4828752f_code.scd rename to resources/resources_bak_2024_01_03/piece_ledger_pas/4b96f62d/4b96f62d_code.scd index ab2dc17..3ec9b1a 100644 --- a/resources/piece_ledger_transcribe_test/4828752f/4828752f_code.scd +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/4b96f62d/4b96f62d_code.scd @@ -6,7 +6,7 @@ var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; // subroutines -var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; // primary routines var genMotif, genSecondarySeq; @@ -24,12 +24,11 @@ setGlobalVars, globalVarsToDict, saveLedger; var seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, -ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, -orders, susWeights, orderSize, passagesSize, +ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited; // model aux vars -var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; +var entrancesDurFunc, passagesDurFunc, exitsDurFunc; // other global vars var popSize, exPath, dir, primes, dims, tuples, @@ -120,8 +119,7 @@ intervalScore = { arg hsArray1, hsArray2, mean, sd, signed = false; var pDistance; pDistance = pDist.value(hsArray1, hsArray2, signed); - //pDistance.gaussCurve(1, mean, sd) - stepFunc.value(pDistance); + pDistance.gaussCurve(1, mean, sd) }; inclusionScore = { @@ -173,18 +171,6 @@ genDurFunc = {arg chordProb, minPad, maxPad, minDur, maxDur, envData, seed; seedFunc.value(durFunc, seed); }; -genStepFunc = {arg minStep, maxStep, envData, seed; - var envDataNorm, env, pTable, stepFunc; - [minStep, maxStep, envData].postln; - envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; - envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; - env = Env.pairs(envDataNorm); - stepFunc = {arg pDist; - env.at(pDist).clip(0.001, 1); - }; - seedFunc.value(stepFunc, seed); -}; - genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; ((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; @@ -215,8 +201,7 @@ updateVoices = {arg ins, sus; 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); - if(hdInvert == 0, {hdScore = 1/hdScore}); + 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); @@ -306,7 +291,7 @@ genSubMotif = {arg order, orderIndex, lastState, repeatLast = false, startFromLa //------primary routines genMotif = { - var repeats, fSeq, fDur, durAdd; + var repeats, fSeq; repeats = 1; fSeq = []; @@ -328,13 +313,6 @@ genMotif = { fSeq = fSeq.add(motif); }); - - //round last duration to measure - fDur = fSeq.flatten.flatten.slice(nil, 1).sum; - durAdd = fDur.round(4) - fDur; - if(durAdd < 0, {durAdd = 4 - durAdd}); - fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; - fSeq }; @@ -370,8 +348,8 @@ Event.addEventType(\osc, { */ Event.addEventType(\osc, { - if (~addr.notNil) { - ~msg; + if (~addr.postln.notNil) { + ~msg.postln; ~addr.sendMsg(~path, *~msg); }; }); @@ -389,9 +367,8 @@ genPatterns = {arg inSeq, addr, oneShot = false; 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.0, 3.0)}, {rrand(0.3, 0.5)}); + if(clumps[c + 1][0] == ["Rest"], {rrand(1, 3)}, {rrand(0.3, 0.5)}); }); - rels = rels.add(rrand(1.0, 3.0)); amps = freqs.collect({rrand(0.6, 0.99)}); [ @@ -540,10 +517,8 @@ msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; res = res.replace("Rest", "\"Rest\""); res = res.interpret; }, { - var tmpRes; - if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); - if(res.contains("."), {tmpRes = res.asFloat}); - if(tmpRes != nil, {res = tmpRes}); + //res.postln; + if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); }); }); res @@ -557,8 +532,7 @@ writeResources = {arg path, dict; seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, - ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, - orders, susWeights, orderSize, passagesSize, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited ]; @@ -592,8 +566,7 @@ setGlobalVars = {arg dict, skipLastXChanges = false; // order really matters!!!! # seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, - ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, - orders, susWeights, orderSize, passagesSize, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited = nameSpaces.collect({arg nS; dict[nS]}); if(skipLastXChanges, {lastXChanges = tmpLastXChanges}); dict @@ -606,8 +579,7 @@ globalVarsToDict = { seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, - ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, - orders, susWeights, orderSize, passagesSize, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited ]; dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); @@ -646,8 +618,7 @@ loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); 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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", - "order", "sus_weights", "order_size", "passages_size", + "ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size", "motif_edited", "order_edited" ]; @@ -708,8 +679,6 @@ OSCdef(\generate, {arg msg, time, addr, port; orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); //addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); }); - - stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); seq = seedFunc.value(genMotif, motifSeed).value; lastXChanges.collect({arg item; item.postln}); @@ -718,14 +687,12 @@ OSCdef(\generate, {arg msg, time, addr, port; modelString = writeResources.value(path, dict); //addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); - //~seq = seq; - addr.sendMsg("/generated", path, modelString, ledgerPath); }, \generate); OSCdef(\commit, {arg msg, time, addr, port; - var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2; //msg.postln; /* @@ -738,9 +705,7 @@ OSCdef(\commit, {arg msg, time, addr, port; musicData = loadModelJSON.value(msg[1].asString.parseJSON)["music_data"].postln; musicChanged = (musicData != seq).postln; - commitType = msg[2].asString; - lastCurUID = curUID.deepCopy; curUID = genUID.value; File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); @@ -760,18 +725,7 @@ OSCdef(\commit, {arg msg, time, addr, port; File.delete(ledgerPath ++ "_bak"); File.copy(ledgerPath, ledgerPath ++ "_bak"); File.delete(ledgerPath); - - if(commitType == "add", { - if(lastCurUID == "tmp", { - ledger = ledger.drop(-1).add(curUID); - }, { - ledger = ledger.add(curUID); - }) - }); - - if(commitType == "insert", {ledger = ledger.insert(ledger.indexOf(lastCurUID), curUID)}); - - if(commitType == "replace", {ledger = ledger.put(ledger.indexOf(lastCurUID), curUID)}); + ledger = ledger.drop(-1).add(curUID); saveLedger.value(ledger, ledgerPath); @@ -824,102 +778,8 @@ OSCdef(\transport, {arg msg, time, addr, port; }); }, \transport); - -OSCdef(\transcribe_motif, {arg msg, time, addr, port; - var tSeq, refChord, refUID; - - msg.postln; - - tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; - refUID = msg[2].asString.postln; - - if((refUID != "nil") && (refUID != "tmp"), { - var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }, { - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - }); - - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); -}, \transcribe_motif); - - -OSCdef(\transcribe_all, {arg msg, time, addr, port; - var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; - if(true, { - cuedSeek = (seq != nil); - indexStart = msg[1].asInteger; - indexEnd = ledger.size - if(cuedSeek, {2}, {1}); - - //tmp for testing transcription - indexEnd = (indexStart+5); - - //ledger.postln; - if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { - var lilyPartLedgerFiles; - - lilyPartLedgerFiles = 4.collect({arg p; - File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); - }); - - ledger[indexStart..indexEnd].do({arg uid, index; - var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - fileString = file.readAllString; - tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); - refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); - file.close; - - //uid.postln; - //(refUID == "nil").postln; - - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - - if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }); - - if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); - }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); - }); - - lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); - }); - - }); - - lilyPartLedgerFiles.do({arg f; - f.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; - }); - */ - }, { - - }); - -}, \transcribe_all); - ) -~transcribe.value(~seq, dir); - ( //synthdefs ~stringModelBusArray = 4.collect({Bus.audio(s, 1)}); @@ -948,9 +808,15 @@ SynthDef(\sine, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; }).add; SynthDef(\mixer, {arg freq, gate = 1, sustain, amp, dur, out; - var nameSpaces, sigs; + 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; + 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)}); @@ -1002,25 +868,20 @@ SynthDef(\hdust, { ( 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 diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/4b96f62d/4b96f62d_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/4b96f62d/4b96f62d_mus_model.json new file mode 100644 index 0000000..c8a77ec --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/4b96f62d/4b96f62d_mus_model.json @@ -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" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/50fec831/50fec831_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/50fec831/50fec831_code.scd new file mode 100644 index 0000000..ab370bd --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/50fec831/50fec831_code.scd @@ -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; +) +*/ + diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/50fec831/50fec831_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/50fec831/50fec831_mus_model.json new file mode 100644 index 0000000..e3299cd --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/50fec831/50fec831_mus_model.json @@ -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" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/5267b235/5267b235_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/5267b235/5267b235_code.scd new file mode 100644 index 0000000..ab370bd --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/5267b235/5267b235_code.scd @@ -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; +) +*/ + diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/5267b235/5267b235_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/5267b235/5267b235_mus_model.json new file mode 100644 index 0000000..56ea9be --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/5267b235/5267b235_mus_model.json @@ -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" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/5625a95a/5625a95a_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/5625a95a/5625a95a_code.scd new file mode 100644 index 0000000..ab370bd --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/5625a95a/5625a95a_code.scd @@ -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; +) +*/ + diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/5625a95a/5625a95a_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/5625a95a/5625a95a_mus_model.json new file mode 100644 index 0000000..2bd7c20 --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/5625a95a/5625a95a_mus_model.json @@ -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" +} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates/628d5c8b/628d5c8b_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/628d5c8b/628d5c8b_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates/628d5c8b/628d5c8b_code.scd rename to resources/resources_bak_2024_01_03/piece_ledger_pas/628d5c8b/628d5c8b_code.scd diff --git a/resources/piece_ledger_sq1_candidates/628d5c8b/628d5c8b_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/628d5c8b/628d5c8b_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates/628d5c8b/628d5c8b_mus_model.json rename to resources/resources_bak_2024_01_03/piece_ledger_pas/628d5c8b/628d5c8b_mus_model.json diff --git a/resources/piece_ledger_transcribe_test/674b56e3/674b56e3_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/6409252e/6409252e_code.scd similarity index 82% rename from resources/piece_ledger_transcribe_test/674b56e3/674b56e3_code.scd rename to resources/resources_bak_2024_01_03/piece_ledger_pas/6409252e/6409252e_code.scd index 40ae463..3ec9b1a 100644 --- a/resources/piece_ledger_transcribe_test/674b56e3/674b56e3_code.scd +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/6409252e/6409252e_code.scd @@ -6,7 +6,7 @@ var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; // subroutines -var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; // primary routines var genMotif, genSecondarySeq; @@ -24,12 +24,11 @@ setGlobalVars, globalVarsToDict, saveLedger; var seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, -ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, -orders, susWeights, orderSize, passagesSize, +ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited; // model aux vars -var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; +var entrancesDurFunc, passagesDurFunc, exitsDurFunc; // other global vars var popSize, exPath, dir, primes, dims, tuples, @@ -120,8 +119,7 @@ intervalScore = { arg hsArray1, hsArray2, mean, sd, signed = false; var pDistance; pDistance = pDist.value(hsArray1, hsArray2, signed); - //pDistance.gaussCurve(1, mean, sd) - stepFunc.value(pDistance); + pDistance.gaussCurve(1, mean, sd) }; inclusionScore = { @@ -173,18 +171,6 @@ genDurFunc = {arg chordProb, minPad, maxPad, minDur, maxDur, envData, seed; seedFunc.value(durFunc, seed); }; -genStepFunc = {arg minStep, maxStep, envData, seed; - var envDataNorm, env, pTable, stepFunc; - [minStep, maxStep, envData].postln; - envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; - envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; - env = Env.pairs(envDataNorm); - stepFunc = {arg pDist; - env.at(pDist).clip(0.001, 1); - }; - seedFunc.value(stepFunc, seed); -}; - genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; ((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; @@ -215,8 +201,7 @@ updateVoices = {arg ins, sus; 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); - if(hdInvert == 0, {hdScore = 1/hdScore}); + 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); @@ -306,7 +291,7 @@ genSubMotif = {arg order, orderIndex, lastState, repeatLast = false, startFromLa //------primary routines genMotif = { - var repeats, fSeq, fDur, durAdd; + var repeats, fSeq; repeats = 1; fSeq = []; @@ -328,13 +313,6 @@ genMotif = { fSeq = fSeq.add(motif); }); - - //round last duration to measure - fDur = fSeq.flatten.flatten.slice(nil, 1).sum; - durAdd = fDur.round(4) - fDur; - if(durAdd < 0, {durAdd = 4 - durAdd}); - fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; - fSeq }; @@ -370,8 +348,8 @@ Event.addEventType(\osc, { */ Event.addEventType(\osc, { - if (~addr.notNil) { - ~msg; + if (~addr.postln.notNil) { + ~msg.postln; ~addr.sendMsg(~path, *~msg); }; }); @@ -389,9 +367,8 @@ genPatterns = {arg inSeq, addr, oneShot = false; 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.0, 3.0)}, {rrand(0.3, 0.5)}); + if(clumps[c + 1][0] == ["Rest"], {rrand(1, 3)}, {rrand(0.3, 0.5)}); }); - rels = rels.add(rrand(1.0, 3.0)); amps = freqs.collect({rrand(0.6, 0.99)}); [ @@ -540,10 +517,8 @@ msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; res = res.replace("Rest", "\"Rest\""); res = res.interpret; }, { - var tmpRes; - if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); - if(res.contains("."), {tmpRes = res.asFloat}); - if(tmpRes != nil, {res = tmpRes}); + //res.postln; + if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); }); }); res @@ -557,8 +532,7 @@ writeResources = {arg path, dict; seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, - ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, - orders, susWeights, orderSize, passagesSize, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited ]; @@ -592,8 +566,7 @@ setGlobalVars = {arg dict, skipLastXChanges = false; // order really matters!!!! # seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, - ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, - orders, susWeights, orderSize, passagesSize, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited = nameSpaces.collect({arg nS; dict[nS]}); if(skipLastXChanges, {lastXChanges = tmpLastXChanges}); dict @@ -606,8 +579,7 @@ globalVarsToDict = { seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, - ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, - orders, susWeights, orderSize, passagesSize, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited ]; dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); @@ -646,8 +618,7 @@ loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); 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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", - "order", "sus_weights", "order_size", "passages_size", + "ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size", "motif_edited", "order_edited" ]; @@ -708,8 +679,6 @@ OSCdef(\generate, {arg msg, time, addr, port; orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); //addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); }); - - stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); seq = seedFunc.value(genMotif, motifSeed).value; lastXChanges.collect({arg item; item.postln}); @@ -718,14 +687,12 @@ OSCdef(\generate, {arg msg, time, addr, port; modelString = writeResources.value(path, dict); //addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); - //~seq = seq; - addr.sendMsg("/generated", path, modelString, ledgerPath); }, \generate); OSCdef(\commit, {arg msg, time, addr, port; - var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2; //msg.postln; /* @@ -738,10 +705,7 @@ OSCdef(\commit, {arg msg, time, addr, port; musicData = loadModelJSON.value(msg[1].asString.parseJSON)["music_data"].postln; musicChanged = (musicData != seq).postln; - commitType = msg[2].asString; - commitPos = msg[3].postln.asInteger; - lastCurUID = curUID.deepCopy; curUID = genUID.value; File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); @@ -761,18 +725,7 @@ OSCdef(\commit, {arg msg, time, addr, port; File.delete(ledgerPath ++ "_bak"); File.copy(ledgerPath, ledgerPath ++ "_bak"); File.delete(ledgerPath); - - if(commitType == "add", { - if(lastCurUID == "tmp", { - ledger = ledger.drop(-1).add(curUID); - }, { - ledger = ledger.add(curUID); - }) - }); - - if(commitType == "insert", {ledger = ledger.insert(commitPos.postln, curUID)}); - - if(commitType == "replace", {ledger = ledger.put(commitPos.postln, curUID)}); + ledger = ledger.drop(-1).add(curUID); saveLedger.value(ledger, ledgerPath); @@ -825,102 +778,8 @@ OSCdef(\transport, {arg msg, time, addr, port; }); }, \transport); - -OSCdef(\transcribe_motif, {arg msg, time, addr, port; - var tSeq, refChord, refUID; - - msg.postln; - - tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; - refUID = msg[2].asString.postln; - - if((refUID != "nil") && (refUID != "tmp"), { - var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }, { - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - }); - - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); -}, \transcribe_motif); - - -OSCdef(\transcribe_all, {arg msg, time, addr, port; - var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; - if(true, { - cuedSeek = (seq != nil); - indexStart = msg[1].asInteger; - indexEnd = ledger.size - if(cuedSeek, {2}, {1}); - - //tmp for testing transcription - indexEnd = (indexStart+5); - - //ledger.postln; - if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { - var lilyPartLedgerFiles; - - lilyPartLedgerFiles = 4.collect({arg p; - File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); - }); - - ledger[indexStart..indexEnd].do({arg uid, index; - var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - fileString = file.readAllString; - tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); - refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); - file.close; - - //uid.postln; - //(refUID == "nil").postln; - - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - - if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }); - - if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); - }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); - }); - - lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); - }); - - }); - - lilyPartLedgerFiles.do({arg f; - f.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; - }); - */ - }, { - - }); - -}, \transcribe_all); - ) -~transcribe.value(~seq, dir); - ( //synthdefs ~stringModelBusArray = 4.collect({Bus.audio(s, 1)}); @@ -949,9 +808,15 @@ SynthDef(\sine, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; }).add; SynthDef(\mixer, {arg freq, gate = 1, sustain, amp, dur, out; - var nameSpaces, sigs; + 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; + 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)}); @@ -1003,25 +868,20 @@ SynthDef(\hdust, { ( 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 diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/6409252e/6409252e_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/6409252e/6409252e_mus_model.json new file mode 100644 index 0000000..50778fb --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/6409252e/6409252e_mus_model.json @@ -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" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/6a3f7c7c/6a3f7c7c_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/6a3f7c7c/6a3f7c7c_code.scd new file mode 100644 index 0000000..ab370bd --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/6a3f7c7c/6a3f7c7c_code.scd @@ -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; +) +*/ + diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/6a3f7c7c/6a3f7c7c_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/6a3f7c7c/6a3f7c7c_mus_model.json new file mode 100644 index 0000000..829f700 --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/6a3f7c7c/6a3f7c7c_mus_model.json @@ -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" +} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates/6abf27d4/6abf27d4_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/6abf27d4/6abf27d4_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates/6abf27d4/6abf27d4_code.scd rename to resources/resources_bak_2024_01_03/piece_ledger_pas/6abf27d4/6abf27d4_code.scd diff --git a/resources/piece_ledger_sq1_candidates/6abf27d4/6abf27d4_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/6abf27d4/6abf27d4_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates/6abf27d4/6abf27d4_mus_model.json rename to resources/resources_bak_2024_01_03/piece_ledger_pas/6abf27d4/6abf27d4_mus_model.json diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/6d0c2f19/6d0c2f19_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/6d0c2f19/6d0c2f19_code.scd new file mode 100644 index 0000000..ab370bd --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/6d0c2f19/6d0c2f19_code.scd @@ -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; +) +*/ + diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/6d0c2f19/6d0c2f19_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/6d0c2f19/6d0c2f19_mus_model.json new file mode 100644 index 0000000..a36e0d1 --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/6d0c2f19/6d0c2f19_mus_model.json @@ -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" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/6d743c5c/6d743c5c_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/6d743c5c/6d743c5c_code.scd new file mode 100644 index 0000000..1b05aa0 --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/6d743c5c/6d743c5c_code.scd @@ -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; +) +*/ + diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/6d743c5c/6d743c5c_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/6d743c5c/6d743c5c_mus_model.json new file mode 100644 index 0000000..b1611ee --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/6d743c5c/6d743c5c_mus_model.json @@ -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" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/6f1305ed/6f1305ed_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/6f1305ed/6f1305ed_code.scd new file mode 100644 index 0000000..830a192 --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/6f1305ed/6f1305ed_code.scd @@ -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; +) +*/ + diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/6f1305ed/6f1305ed_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/6f1305ed/6f1305ed_mus_model.json new file mode 100644 index 0000000..89155f1 --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/6f1305ed/6f1305ed_mus_model.json @@ -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" +} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/54479f3d/54479f3d_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/703e109b/703e109b_code.scd similarity index 82% rename from resources/piece_ledger_transcribe_test/54479f3d/54479f3d_code.scd rename to resources/resources_bak_2024_01_03/piece_ledger_pas/703e109b/703e109b_code.scd index 40ae463..3ec9b1a 100644 --- a/resources/piece_ledger_transcribe_test/54479f3d/54479f3d_code.scd +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/703e109b/703e109b_code.scd @@ -6,7 +6,7 @@ var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; // subroutines -var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc; // primary routines var genMotif, genSecondarySeq; @@ -24,12 +24,11 @@ setGlobalVars, globalVarsToDict, saveLedger; var seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, -ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, -orders, susWeights, orderSize, passagesSize, +ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited; // model aux vars -var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; +var entrancesDurFunc, passagesDurFunc, exitsDurFunc; // other global vars var popSize, exPath, dir, primes, dims, tuples, @@ -120,8 +119,7 @@ intervalScore = { arg hsArray1, hsArray2, mean, sd, signed = false; var pDistance; pDistance = pDist.value(hsArray1, hsArray2, signed); - //pDistance.gaussCurve(1, mean, sd) - stepFunc.value(pDistance); + pDistance.gaussCurve(1, mean, sd) }; inclusionScore = { @@ -173,18 +171,6 @@ genDurFunc = {arg chordProb, minPad, maxPad, minDur, maxDur, envData, seed; seedFunc.value(durFunc, seed); }; -genStepFunc = {arg minStep, maxStep, envData, seed; - var envDataNorm, env, pTable, stepFunc; - [minStep, maxStep, envData].postln; - envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; - envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; - env = Env.pairs(envDataNorm); - stepFunc = {arg pDist; - env.at(pDist).clip(0.001, 1); - }; - seedFunc.value(stepFunc, seed); -}; - genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; ((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; @@ -215,8 +201,7 @@ updateVoices = {arg ins, sus; 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); - if(hdInvert == 0, {hdScore = 1/hdScore}); + 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); @@ -306,7 +291,7 @@ genSubMotif = {arg order, orderIndex, lastState, repeatLast = false, startFromLa //------primary routines genMotif = { - var repeats, fSeq, fDur, durAdd; + var repeats, fSeq; repeats = 1; fSeq = []; @@ -328,13 +313,6 @@ genMotif = { fSeq = fSeq.add(motif); }); - - //round last duration to measure - fDur = fSeq.flatten.flatten.slice(nil, 1).sum; - durAdd = fDur.round(4) - fDur; - if(durAdd < 0, {durAdd = 4 - durAdd}); - fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; - fSeq }; @@ -370,8 +348,8 @@ Event.addEventType(\osc, { */ Event.addEventType(\osc, { - if (~addr.notNil) { - ~msg; + if (~addr.postln.notNil) { + ~msg.postln; ~addr.sendMsg(~path, *~msg); }; }); @@ -389,9 +367,8 @@ genPatterns = {arg inSeq, addr, oneShot = false; 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.0, 3.0)}, {rrand(0.3, 0.5)}); + if(clumps[c + 1][0] == ["Rest"], {rrand(1, 3)}, {rrand(0.3, 0.5)}); }); - rels = rels.add(rrand(1.0, 3.0)); amps = freqs.collect({rrand(0.6, 0.99)}); [ @@ -540,10 +517,8 @@ msgInterpret = {arg in, escapeDoubleQuotes = true, escapeSingleQuotes = true; res = res.replace("Rest", "\"Rest\""); res = res.interpret; }, { - var tmpRes; - if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); - if(res.contains("."), {tmpRes = res.asFloat}); - if(tmpRes != nil, {res = tmpRes}); + //res.postln; + if(res.every({arg char; char.isDecDigit}), {res = res.asInteger}); }); }); res @@ -557,8 +532,7 @@ writeResources = {arg path, dict; seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, - ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, - orders, susWeights, orderSize, passagesSize, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited ]; @@ -592,8 +566,7 @@ setGlobalVars = {arg dict, skipLastXChanges = false; // order really matters!!!! # seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, - ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, - orders, susWeights, orderSize, passagesSize, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited = nameSpaces.collect({arg nS; dict[nS]}); if(skipLastXChanges, {lastXChanges = tmpLastXChanges}); dict @@ -606,8 +579,7 @@ globalVarsToDict = { seq, lastXChanges, curUID, refUID, orderSeed, durSeed, motifSeed, entrancesProbVals, passagesProbVals, exitsProbVals, - ranges, stepProbsVals, passagesWeights, hdExp, hdInvert, - orders, susWeights, orderSize, passagesSize, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, motifEdited, orderEdited ]; dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); @@ -646,8 +618,7 @@ loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); 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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", - "order", "sus_weights", "order_size", "passages_size", + "ranges", "passages_weights", "order", "sus_weights", "order_size", "passages_size", "motif_edited", "order_edited" ]; @@ -708,8 +679,6 @@ OSCdef(\generate, {arg msg, time, addr, port; orders = seedFunc.value(genOrders, orderSeed).valueArray(orderSize ++ passagesSize); //addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); }); - - stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); seq = seedFunc.value(genMotif, motifSeed).value; lastXChanges.collect({arg item; item.postln}); @@ -718,14 +687,12 @@ OSCdef(\generate, {arg msg, time, addr, port; modelString = writeResources.value(path, dict); //addr.sendMsg("/generated", musPath, stringifyToDepth.value(seq, 3)); - //~seq = seq; - addr.sendMsg("/generated", path, modelString, ledgerPath); }, \generate); OSCdef(\commit, {arg msg, time, addr, port; - var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2; //msg.postln; /* @@ -738,10 +705,7 @@ OSCdef(\commit, {arg msg, time, addr, port; musicData = loadModelJSON.value(msg[1].asString.parseJSON)["music_data"].postln; musicChanged = (musicData != seq).postln; - commitType = msg[2].asString; - commitPos = msg[3].postln.asInteger; - lastCurUID = curUID.deepCopy; curUID = genUID.value; File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); @@ -761,18 +725,7 @@ OSCdef(\commit, {arg msg, time, addr, port; File.delete(ledgerPath ++ "_bak"); File.copy(ledgerPath, ledgerPath ++ "_bak"); File.delete(ledgerPath); - - if(commitType == "add", { - if(lastCurUID == "tmp", { - ledger = ledger.drop(-1).add(curUID); - }, { - ledger = ledger.add(curUID); - }) - }); - - if(commitType == "insert", {ledger = ledger.insert(commitPos.postln, curUID)}); - - if(commitType == "replace", {ledger = ledger.put(commitPos.postln, curUID)}); + ledger = ledger.drop(-1).add(curUID); saveLedger.value(ledger, ledgerPath); @@ -825,102 +778,8 @@ OSCdef(\transport, {arg msg, time, addr, port; }); }, \transport); - -OSCdef(\transcribe_motif, {arg msg, time, addr, port; - var tSeq, refChord, refUID; - - msg.postln; - - tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; - refUID = msg[2].asString.postln; - - if((refUID != "nil") && (refUID != "tmp"), { - var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }, { - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - }); - - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); -}, \transcribe_motif); - - -OSCdef(\transcribe_all, {arg msg, time, addr, port; - var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; - if(true, { - cuedSeek = (seq != nil); - indexStart = msg[1].asInteger; - indexEnd = ledger.size - if(cuedSeek, {2}, {1}); - - //tmp for testing transcription - indexEnd = (indexStart+5); - - //ledger.postln; - if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { - var lilyPartLedgerFiles; - - lilyPartLedgerFiles = 4.collect({arg p; - File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); - }); - - ledger[indexStart..indexEnd].do({arg uid, index; - var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - fileString = file.readAllString; - tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); - refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); - file.close; - - //uid.postln; - //(refUID == "nil").postln; - - refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; - - if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; - file = File(path, "r"); - refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; - file.close; - }); - - if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); - }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); - }); - - lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); - }); - - }); - - lilyPartLedgerFiles.do({arg f; - f.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; - }); - */ - }, { - - }); - -}, \transcribe_all); - ) -~transcribe.value(~seq, dir); - ( //synthdefs ~stringModelBusArray = 4.collect({Bus.audio(s, 1)}); @@ -949,9 +808,15 @@ SynthDef(\sine, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0; }).add; SynthDef(\mixer, {arg freq, gate = 1, sustain, amp, dur, out; - var nameSpaces, sigs; + 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; + 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)}); @@ -1003,25 +868,20 @@ SynthDef(\hdust, { ( 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 diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/703e109b/703e109b_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/703e109b/703e109b_mus_model.json new file mode 100644 index 0000000..c0a214c --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/703e109b/703e109b_mus_model.json @@ -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" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/74faf83f/74faf83f_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/74faf83f/74faf83f_code.scd new file mode 100644 index 0000000..3ec9b1a --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/74faf83f/74faf83f_code.scd @@ -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; +) +*/ + diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/74faf83f/74faf83f_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/74faf83f/74faf83f_mus_model.json new file mode 100644 index 0000000..38b642a --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/74faf83f/74faf83f_mus_model.json @@ -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" +} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates/7ac10d34/7ac10d34_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/7ac10d34/7ac10d34_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates/7ac10d34/7ac10d34_code.scd rename to resources/resources_bak_2024_01_03/piece_ledger_pas/7ac10d34/7ac10d34_code.scd diff --git a/resources/piece_ledger_sq1_candidates/7ac10d34/7ac10d34_gui_state.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/7ac10d34/7ac10d34_gui_state.json similarity index 100% rename from resources/piece_ledger_sq1_candidates/7ac10d34/7ac10d34_gui_state.json rename to resources/resources_bak_2024_01_03/piece_ledger_pas/7ac10d34/7ac10d34_gui_state.json diff --git a/resources/piece_ledger_sq1_candidates/7ac10d34/7ac10d34_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/7ac10d34/7ac10d34_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates/7ac10d34/7ac10d34_mus_model.json rename to resources/resources_bak_2024_01_03/piece_ledger_pas/7ac10d34/7ac10d34_mus_model.json diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/7bf874ce/7bf874ce_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/7bf874ce/7bf874ce_code.scd new file mode 100644 index 0000000..ab370bd --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/7bf874ce/7bf874ce_code.scd @@ -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; +) +*/ + diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/7bf874ce/7bf874ce_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/7bf874ce/7bf874ce_mus_model.json new file mode 100644 index 0000000..4675781 --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/7bf874ce/7bf874ce_mus_model.json @@ -0,0 +1,59 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ], [ "Rest" ] ], 0.375 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ], [ "Rest" ] ], 2.25 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 1, 0, 0, 0 ] ], 0.375 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 1, 0, 0, 0 ] ], 0.5 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 2, 0, 0, 0, 0, -1 ] ], 0.375 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 2, 0, 0, 0, 0, -1 ] ], 3.625 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ], [ 2, 0, 0, 0, 0, -1 ] ], 0.875 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ], [ "Rest" ] ], 0.625 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 1, 0, 0 ], [ "Rest" ] ], 0.75 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 4.125 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.375 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ "Rest" ] ], 0.5 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ] ], 4 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 1, 1, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ] ], 0.5 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, 1, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ] ], 0.875 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, 1, 0, 0, 0 ], [ "Rest" ] ], 0.5 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 4.375 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 2, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 2, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ] ] +], +"cur_uid": "7bf874ce", +"ref_uid": "6d0c2f19", +"order_seed": 460016, +"dur_seed": 553757, +"motifs_seed": 771464, +"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": +[ + [ [ 2, 0 ], [ 3, 1, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 2 ], [ 1, 3 ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ] +], +"sus_weights": [ 0.75, 0.69, 0.75 ], +"order_size": [ 1, 4 ], +"passages_size": [ 0, 3 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/7c7a96a2/7c7a96a2_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/7c7a96a2/7c7a96a2_code.scd new file mode 100644 index 0000000..1b308bc --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/7c7a96a2/7c7a96a2_code.scd @@ -0,0 +1,897 @@ +( +// 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, rels; + 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}); + rels = freqs.drop(-1).collect({rrand(0.3, 0.5)}) ++ [rrand(1, 2)]; + + [ + Pbind( + \instrument, \string_model, + \group, group, + \freq, Pseq(freqs, 1), + \dur, Pseq(fDurs, 1), + \sustain, Pseq(fDurs, 1), + \release, Pseq(rels, 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, 3, 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)); + //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; +) +*/ + diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/7c7a96a2/7c7a96a2_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/7c7a96a2/7c7a96a2_mus_model.json new file mode 100644 index 0000000..cd8ded8 --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/7c7a96a2/7c7a96a2_mus_model.json @@ -0,0 +1,45 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ 1, 0, 0, -1, 1, -1 ], [ "Rest" ], [ "Rest" ] ], 1.625 ], + [ [ [ "Rest" ], [ 1, 0, 0, -1, 1, -1 ], [ "Rest" ], [ 3, 0, 0, -1, 0, -1 ] ], 1.25 ], + [ [ [ 0, 1, 0, -1, 1, -1 ], [ 1, 0, 0, -1, 1, -1 ], [ "Rest" ], [ 3, 0, 0, -1, 0, -1 ] ], 1.25 ], + [ [ [ 0, 1, 0, -1, 1, -1 ], [ 1, 0, 0, -1, 1, -1 ], [ 3, 0, -1, -1, 1, -1 ], [ 3, 0, 0, -1, 0, -1 ] ], 1.5 ], + [ [ [ 0, 0, 0, -1, 2, -1 ], [ 1, 0, 0, -1, 1, -1 ], [ 3, 0, -1, -1, 1, -1 ], [ 3, 0, 0, -1, 0, -1 ] ], 2.125 ], + [ [ [ 0, 0, 0, -1, 2, -1 ], [ 1, 0, 0, -1, 1, -1 ], [ "Rest" ], [ 3, 0, 0, -1, 0, -1 ] ], 1.5 ], + [ [ [ 0, 0, 0, -1, 2, -1 ], [ "Rest" ], [ "Rest" ], [ 3, 0, 0, -1, 0, -1 ] ], 1.125 ], + [ [ [ 0, 0, 0, -1, 2, -1 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.375 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.75 ] + ] + ] +], +"last_changes": +[ + [ [ -1, 0, 0, 1, 1, -1 ], [ 1, 0, 0, -1, 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 ], [ 3, 0, 0, -1, 0, -1 ] ], + [ [ 0, 1, 0, -1, 1, -1 ], [ 1, 0, 0, -1, 1, -1 ], [ 2, 0, 0, 0, 1, -1 ], [ 3, 0, 0, -1, 0, -1 ] ], + [ [ 0, 1, 0, -1, 1, -1 ], [ 1, 0, 0, -1, 1, -1 ], [ 3, 0, -1, -1, 1, -1 ], [ 3, 0, 0, -1, 0, -1 ] ], + [ [ 0, 0, 0, -1, 2, -1 ], [ 1, 0, 0, -1, 1, -1 ], [ 3, 0, -1, -1, 1, -1 ], [ 3, 0, 0, -1, 0, -1 ] ] +], +"cur_uid": "7c7a96a2", +"ref_uid": "6f1305ed", +"order_seed": 768571, +"dur_seed": 647965, +"motifs_seed": 710750, +"entrances_probs_vals": [ 0, 0.48, 1.7460317460317, 0.58, 1.6758241758242, 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.6758241758242, 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.6758241758242, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], +"ranges": [ [ -1100, 237.77089783282 ], [ -1066.253869969, 260.06191950464 ], [ 1207.4303405573, 2065.6346749226 ], [ 1040.2476780186, 2053 ] ], +"passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], +"order": +[ + [ [ 1 ], [ 3, 0, 2, 0 ], [ ] ] +], +"sus_weights": [ 0.73, 0.49, 0 ], +"order_size": [ 1, 7 ], +"passages_size": [ 0, 2 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/7c8bc6df/7c8bc6df_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/7c8bc6df/7c8bc6df_code.scd new file mode 100644 index 0000000..a4e8b56 --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/7c8bc6df/7c8bc6df_code.scd @@ -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; +) +*/ + diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/7c8bc6df/7c8bc6df_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/7c8bc6df/7c8bc6df_mus_model.json new file mode 100644 index 0000000..a8f0de5 --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/7c8bc6df/7c8bc6df_mus_model.json @@ -0,0 +1,84 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ 6, -1, 0, -1, -1, -4 ], [ "Rest" ] ], 2.375 ], + [ [ [ "Rest" ], [ 4, -1, 1, -1, -1, -4 ], [ 6, -1, 0, -1, -1, -4 ], [ "Rest" ] ], 1.25 ], + [ [ [ "Rest" ], [ 5, -2, 0, -1, -1, -4 ], [ 6, -1, 0, -1, -1, -4 ], [ "Rest" ] ], 1.5 ], + [ [ [ "Rest" ], [ 5, -1, 0, -2, -1, -4 ], [ 6, -1, 0, -1, -1, -4 ], [ "Rest" ] ], 1.25 ], + [ [ [ "Rest" ], [ 5, -1, 0, -1, -1, -5 ], [ 6, -1, 0, -1, -1, -4 ], [ "Rest" ] ], 3.125 ] + ], + [ + [ [ [ "Rest" ], [ 5, -1, 0, -1, -1, -5 ], [ 6, -1, 0, -1, -1, -4 ], [ 5, -1, 0, 0, 0, -5 ] ], 2.625 ], + [ [ [ 3, -1, 0, -1, 0, -5 ], [ 5, -1, 0, -1, -1, -5 ], [ 6, -1, 0, -1, -1, -4 ], [ 5, -1, 0, 0, 0, -5 ] ], 1.375 ], + [ [ [ 3, -1, 0, -1, 0, -5 ], [ 5, -1, 0, -1, -1, -5 ], [ 5, -1, 1, 0, 0, -5 ], [ 5, -1, 0, 0, 0, -5 ] ], 2.625 ] + ], + [ + [ [ [ 3, -1, 0, -1, 0, -5 ], [ 3, 0, 1, 0, 0, -5 ], [ 5, -1, 1, 0, 0, -5 ], [ 5, -1, 0, 0, 0, -5 ] ], 1.125 ], + [ [ [ 2, -1, 1, 0, 0, -5 ], [ 3, 0, 1, 0, 0, -5 ], [ 5, -1, 1, 0, 0, -5 ], [ 5, -1, 0, 0, 0, -5 ] ], 0.875 ], + [ [ [ 2, -1, 1, 0, 0, -5 ], [ 3, 0, 1, 0, 0, -5 ], [ 5, -1, 1, 0, 0, -5 ], [ 4, -1, 1, 1, 0, -5 ] ], 1.5 ], + [ [ [ 2, -1, 1, 0, 0, -5 ], [ 3, -1, 1, 1, 0, -5 ], [ 5, -1, 1, 0, 0, -5 ], [ 4, -1, 1, 1, 0, -5 ] ], 1 ], + [ [ [ 3, -1, 1, -1, 0, -5 ], [ 3, -1, 1, 1, 0, -5 ], [ 5, -1, 1, 0, 0, -5 ], [ 4, -1, 1, 1, 0, -5 ] ], 2.125 ] + ], + [ + [ [ [ 3, -1, 1, -1, 0, -5 ], [ 3, -1, 1, 1, 0, -5 ], [ 4, -1, 2, 1, 0, -5 ], [ 4, -1, 1, 1, 0, -5 ] ], 0.75 ], + [ [ [ 2, -1, 1, 1, 0, -6 ], [ 3, -1, 1, 1, 0, -5 ], [ 4, -1, 2, 1, 0, -5 ], [ 4, -1, 1, 1, 0, -5 ] ], 0.75 ], + [ [ [ 2, -2, 1, 1, 0, -5 ], [ 3, -1, 1, 1, 0, -5 ], [ 4, -1, 2, 1, 0, -5 ], [ 4, -1, 1, 1, 0, -5 ] ], 2 ] + ], + [ + [ [ [ 2, -2, 1, 1, 0, -5 ], [ 3, -1, 1, 1, 0, -5 ], [ "Rest" ], [ 4, -1, 1, 1, 0, -5 ] ], 0.75 ], + [ [ [ 2, -1, 1, 1, -1, -5 ], [ 3, -1, 1, 1, 0, -5 ], [ "Rest" ], [ 4, -1, 1, 1, 0, -5 ] ], 1.125 ], + [ [ [ 2, -1, 1, 1, -1, -5 ], [ 2, -1, 1, 2, 0, -5 ], [ "Rest" ], [ 4, -1, 1, 1, 0, -5 ] ], 1 ], + [ [ [ 2, -1, 1, 1, -1, -5 ], [ 3, -1, 0, 1, 0, -5 ], [ "Rest" ], [ 4, -1, 1, 1, 0, -5 ] ], 1.5 ], + [ [ [ 2, -1, 1, 1, -1, -5 ], [ 2, -1, 1, 1, 0, -4 ], [ "Rest" ], [ 4, -1, 1, 1, 0, -5 ] ], 1.5 ], + [ [ [ 1, -1, 1, 1, 1, -5 ], [ 2, -1, 1, 1, 0, -4 ], [ "Rest" ], [ 4, -1, 1, 1, 0, -5 ] ], 0.75 ], + [ [ [ 1, -1, 1, 1, 1, -5 ], [ 2, 0, 1, 1, 0, -5 ], [ "Rest" ], [ 4, -1, 1, 1, 0, -5 ] ], 1.5 ] + ], + [ + [ [ [ 1, -1, 1, 1, 1, -5 ], [ 2, 0, 1, 1, 0, -5 ], [ "Rest" ], [ 3, 0, 1, 1, 1, -5 ] ], 0.75 ], + [ [ [ 1, -1, 1, 1, 1, -5 ], [ 2, 0, 1, 1, 0, -5 ], [ 3, -1, 1, 2, 1, -5 ], [ 3, 0, 1, 1, 1, -5 ] ], 1.625 ], + [ [ [ 1, -1, 1, 1, 1, -5 ], [ 2, -1, 1, 1, 1, -5 ], [ 3, -1, 1, 2, 1, -5 ], [ 3, 0, 1, 1, 1, -5 ] ], 1.125 ], + [ [ [ 1, -1, 1, 1, 1, -5 ], [ 1, -1, 1, 2, 1, -5 ], [ 3, -1, 1, 2, 1, -5 ], [ 3, 0, 1, 1, 1, -5 ] ], 0.875 ], + [ [ [ 1, -1, 1, 1, 1, -5 ], [ 1, 0, 1, 1, 1, -5 ], [ 3, -1, 1, 2, 1, -5 ], [ 3, 0, 1, 1, 1, -5 ] ], 1.5 ], + [ [ [ 1, -1, 1, 1, 1, -5 ], [ 1, 0, 1, 1, 1, -5 ], [ 4, -1, 0, 1, 1, -5 ], [ 3, 0, 1, 1, 1, -5 ] ], 2.625 ], + [ [ [ "Rest" ], [ 1, 0, 1, 1, 1, -5 ], [ 4, -1, 0, 1, 1, -5 ], [ 3, 0, 1, 1, 1, -5 ] ], 1 ], + [ [ [ "Rest" ], [ 1, 0, 1, 1, 1, -5 ], [ 4, -1, 0, 1, 1, -5 ], [ "Rest" ] ], 1.5 ], + [ [ [ "Rest" ], [ "Rest" ], [ 4, -1, 0, 1, 1, -5 ], [ "Rest" ] ], 1.25 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 2.875 ] + ] + ] +], +"last_changes": +[ + [ [ 1, -1, 1, 1, 1, -5 ], [ 2, 0, 1, 1, 0, -5 ], [ 3, -1, 1, 2, 1, -5 ], [ 3, 0, 1, 1, 1, -5 ] ], + [ [ 1, -1, 1, 1, 1, -5 ], [ 2, -1, 1, 1, 1, -5 ], [ 3, -1, 1, 2, 1, -5 ], [ 3, 0, 1, 1, 1, -5 ] ], + [ [ 1, -1, 1, 1, 1, -5 ], [ 1, -1, 1, 2, 1, -5 ], [ 3, -1, 1, 2, 1, -5 ], [ 3, 0, 1, 1, 1, -5 ] ], + [ [ 1, -1, 1, 1, 1, -5 ], [ 1, 0, 1, 1, 1, -5 ], [ 3, -1, 1, 2, 1, -5 ], [ 3, 0, 1, 1, 1, -5 ] ], + [ [ 1, -1, 1, 1, 1, -5 ], [ 1, 0, 1, 1, 1, -5 ], [ 4, -1, 0, 1, 1, -5 ], [ 3, 0, 1, 1, 1, -5 ] ] +], +"cur_uid": "7c8bc6df", +"ref_uid": "tmp", +"order_seed": 487536, +"dur_seed": 140662, +"motifs_seed": 617352, +"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 ], [ 1, 1, 1, 1 ], [ 3, 0 ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 1, 0 ], [ ] ], + [ [ 1, 3 ], [ 2, 0, 0 ], [ ] ], + [ [ 3 ], [ 0, 1, 1, 1, 0, 1 ], [ 2 ] ], + [ [ 0 ], [ 3, 2, 1, 1, 1, 2 ], [ ] ] +], +"sus_weights": [ 0.73, 0.49, 0 ], +"order_size": [ 1, 7 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates/7e170ef8/7e170ef8_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/7e170ef8/7e170ef8_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates/7e170ef8/7e170ef8_code.scd rename to resources/resources_bak_2024_01_03/piece_ledger_pas/7e170ef8/7e170ef8_code.scd diff --git a/resources/piece_ledger_sq1_candidates/7e170ef8/7e170ef8_gui_state.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/7e170ef8/7e170ef8_gui_state.json similarity index 100% rename from resources/piece_ledger_sq1_candidates/7e170ef8/7e170ef8_gui_state.json rename to resources/resources_bak_2024_01_03/piece_ledger_pas/7e170ef8/7e170ef8_gui_state.json diff --git a/resources/piece_ledger_sq1_candidates/7e170ef8/7e170ef8_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/7e170ef8/7e170ef8_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates/7e170ef8/7e170ef8_mus_model.json rename to resources/resources_bak_2024_01_03/piece_ledger_pas/7e170ef8/7e170ef8_mus_model.json diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/7fd4d544/7fd4d544_code.scd b/resources/resources_bak_2024_01_03/piece_ledger_pas/7fd4d544/7fd4d544_code.scd new file mode 100644 index 0000000..830a192 --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/7fd4d544/7fd4d544_code.scd @@ -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; +) +*/ + diff --git a/resources/resources_bak_2024_01_03/piece_ledger_pas/7fd4d544/7fd4d544_mus_model.json b/resources/resources_bak_2024_01_03/piece_ledger_pas/7fd4d544/7fd4d544_mus_model.json new file mode 100644 index 0000000..e83ee7f --- /dev/null +++ b/resources/resources_bak_2024_01_03/piece_ledger_pas/7fd4d544/7fd4d544_mus_model.json @@ -0,0 +1,44 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, 0, 1, 0 ] ], 4.75 ], + [ [ [ "Rest" ], [ -1, 0, 0, 1, 1, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 1, 0 ] ], 1.125 ], + [ [ [ 0, 0, 0, -1, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 1, 0 ] ], 1 ], + [ [ [ 0, 0, 0, -1, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ], [ 2, 0, 0, 0, 1, -1 ], [ 1, 0, 0, 0, 1, 0 ] ], 5.125 ], + [ [ [ 0, 0, 0, -1, 1, 0 ], [ "Rest" ], [ 2, 0, 0, 0, 1, -1 ], [ 1, 0, 0, 0, 1, 0 ] ], 1.125 ], + [ [ [ 0, 0, 0, -1, 1, 0 ], [ "Rest" ], [ 2, 0, 0, 0, 1, -1 ], [ "Rest" ] ], 0.875 ], + [ [ [ "Rest" ], [ "Rest" ], [ 2, 0, 0, 0, 1, -1 ], [ "Rest" ] ], 0.875 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 4.375 ] + ] + ] +], +"last_changes": +[ + [ [ 0, -1, 0, 0, 1, 0 ], [ 0, 0, -1, 0, 1, 0 ], [ 1, 0, 1, 0, 1, 0 ], [ 1, 0, 0, 0, 1, 0 ] ], + [ [ 0, -1, 0, 0, 1, 0 ], [ 0, 0, -1, 0, 1, 0 ], [ 2, 0, 0, -1, 1, 0 ], [ 1, 0, 0, 0, 1, 0 ] ], + [ [ 0, -1, 0, 0, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ], [ 2, 0, 0, -1, 1, 0 ], [ 1, 0, 0, 0, 1, 0 ] ], + [ [ 0, 0, 0, -1, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ], [ 2, 0, 0, -1, 1, 0 ], [ 1, 0, 0, 0, 1, 0 ] ], + [ [ 0, 0, 0, -1, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ], [ 2, 0, 0, 0, 1, -1 ], [ 1, 0, 0, 0, 1, 0 ] ] +], +"cur_uid": "7fd4d544", +"ref_uid": "tmp", +"order_seed": 159820, +"dur_seed": 341194, +"motifs_seed": 928268, +"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.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": +[ + [ [ 3 ], [ 1, 0, 2 ], [ ] ] +], +"sus_weights": [ 0.73, 0.23, 0 ], +"order_size": [ 1, 2 ], +"passages_size": [ 0, 1 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates_stitch.json b/resources/resources_bak_2024_01_03/string_quartet_1.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch.json rename to resources/resources_bak_2024_01_03/string_quartet_1.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/4200a90d/4200a90d_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/4200a90d_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4200a90d/4200a90d_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/4200a90d_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/4200a90d/4200a90d_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/4200a90d_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4200a90d/4200a90d_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/4200a90d_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/4200a90d/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/lilypond/part_I.ly similarity index 87% rename from resources/piece_ledger_sq1_candidates_stitch/4200a90d/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/lilypond/part_I.ly index c9737c2..bcf7780 100644 --- a/resources/piece_ledger_sq1_candidates_stitch/4200a90d/lilypond/part_I.ly +++ b/resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/lilypond/part_I.ly @@ -13,10 +13,6 @@ \bar "|" { fis'1 ~ } \bar "|" - { fis'2. ~ fis'16[ r8.] } - \bar "|" - { r1 } - \bar "|" - { r1 } + { fis'2. ~ fis'16[ r8.]} \bar "||" } \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates_stitch/4200a90d/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/lilypond/part_II.ly similarity index 95% rename from resources/piece_ledger_sq1_candidates_stitch/4200a90d/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/lilypond/part_II.ly index 4e08032..b74e7bb 100644 --- a/resources/piece_ledger_sq1_candidates_stitch/4200a90d/lilypond/part_II.ly +++ b/resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/lilypond/part_II.ly @@ -13,10 +13,6 @@ \bar "|" { ais'2 ~ ais'8[ r8] r4 } \bar "|" - { r1 } - \bar "|" - { r1 } - \bar "|" { r1 } \bar "||" } \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates_stitch/4200a90d/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/lilypond/part_III.ly similarity index 75% rename from resources/piece_ledger_sq1_candidates_stitch/4200a90d/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/lilypond/part_III.ly index 09e3721..11cd320 100644 --- a/resources/piece_ledger_sq1_candidates_stitch/4200a90d/lilypond/part_III.ly +++ b/resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/lilypond/part_III.ly @@ -13,10 +13,6 @@ \bar "|" { c'1 ~ } \bar "|" - { c'1 ~ } - \bar "|" - { c'4 ~ c'8[ r8] r2 } - \bar "|" - { r1 } + { c'1} \bar "||" } \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates_stitch/4200a90d/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/lilypond/part_IV.ly similarity index 91% rename from resources/piece_ledger_sq1_candidates_stitch/4200a90d/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/lilypond/part_IV.ly index d7db40f..5e43176 100644 --- a/resources/piece_ledger_sq1_candidates_stitch/4200a90d/lilypond/part_IV.ly +++ b/resources/resources_bak_2024_01_03/string_quartet_1/4200a90d/lilypond/part_IV.ly @@ -13,10 +13,6 @@ \bar "|" { g,1 ~ } \bar "|" - { g,4 ~ g,8[ r8] r2 } - \bar "|" - { r1 } - \bar "|" - { r1 } + { g,1} \bar "||" } \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates_stitch/43b009ff/43b009ff_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/43b009ff/43b009ff_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/43b009ff/43b009ff_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/43b009ff/43b009ff_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/43b009ff/43b009ff_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/43b009ff/43b009ff_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/43b009ff/43b009ff_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/43b009ff/43b009ff_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/43b009ff/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/43b009ff/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/43b009ff/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/43b009ff/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/43b009ff/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/43b009ff/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/43b009ff/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/43b009ff/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/43b009ff/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/43b009ff/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/43b009ff/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/43b009ff/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/43b009ff/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/43b009ff/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/43b009ff/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/43b009ff/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/443ec222/443ec222_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/443ec222/443ec222_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/443ec222/443ec222_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/443ec222/443ec222_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/443ec222/443ec222_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/443ec222/443ec222_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/443ec222/443ec222_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/443ec222/443ec222_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/443ec222/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/443ec222/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/443ec222/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/443ec222/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/443ec222/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/443ec222/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/443ec222/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/443ec222/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/443ec222/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/443ec222/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/443ec222/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/443ec222/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/443ec222/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/443ec222/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/443ec222/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/443ec222/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/4526b76b/4526b76b_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/4526b76b/4526b76b_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4526b76b/4526b76b_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/4526b76b/4526b76b_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/4526b76b/4526b76b_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/4526b76b/4526b76b_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4526b76b/4526b76b_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/4526b76b/4526b76b_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/46985d14/46985d14_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/46985d14/46985d14_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/46985d14/46985d14_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/46985d14/46985d14_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/46985d14/46985d14_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/46985d14/46985d14_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/46985d14/46985d14_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/46985d14/46985d14_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/46985d14/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/46985d14/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/46985d14/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/46985d14/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/46985d14/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/46985d14/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/46985d14/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/46985d14/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/46985d14/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/46985d14/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/46985d14/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/46985d14/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/46985d14/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/46985d14/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/46985d14/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/46985d14/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/490b1e6e/490b1e6e_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/490b1e6e/490b1e6e_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/490b1e6e/490b1e6e_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/490b1e6e/490b1e6e_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/490b1e6e/490b1e6e_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/490b1e6e/490b1e6e_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/490b1e6e/490b1e6e_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/490b1e6e/490b1e6e_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/490b1e6e/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/490b1e6e/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/490b1e6e/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/490b1e6e/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/490b1e6e/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/490b1e6e/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/490b1e6e/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/490b1e6e/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/490b1e6e/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/490b1e6e/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/490b1e6e/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/490b1e6e/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/490b1e6e/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/490b1e6e/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/490b1e6e/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/490b1e6e/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates/4a8a6e53/4a8a6e53_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/4a8a6e53/4a8a6e53_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates/4a8a6e53/4a8a6e53_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/4a8a6e53/4a8a6e53_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/4a8a6e53/4a8a6e53_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/4a8a6e53/4a8a6e53_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4a8a6e53/4a8a6e53_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/4a8a6e53/4a8a6e53_mus_model.json diff --git a/resources/resources_bak_2024_01_03/string_quartet_1/4a8a6e53/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4a8a6e53/lilypond/part_I.ly new file mode 100644 index 0000000..e9e6601 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_1/4a8a6e53/lilypond/part_I.ly @@ -0,0 +1,56 @@ +{ + { r2. e'4^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }} ~ } + \bar "|" + { e'2 e'4^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ e'8.[ f'16^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { f'4 ~ f'8[ g'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ g'4 ~ g'8[ ais'8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ } + \bar "|" + { ais'4 ~ ais'8[ c''8^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ c''2 } + \bar "|" + { gis'4^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ gis'8.[ gis'16^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ gis'4 ~ gis'8[ f'8^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { f'2 e'4^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ e'8[ r8] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r2 r16[ dis'8.^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] ~ dis'4 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'8[ dis'8^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}] ~ dis'2 d'4^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'4 ~ d'8[ ais8^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}] ~ ais2 ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais8.[ b16^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] ~ b2. ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b2 ~ b16[ r8.] r4 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates_stitch/4a8a6e53/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4a8a6e53/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4a8a6e53/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/4a8a6e53/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/4a8a6e53/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4a8a6e53/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4a8a6e53/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/4a8a6e53/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/4a8a6e53/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4a8a6e53/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4a8a6e53/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/4a8a6e53/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/4b7745df/4b7745df_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/4b7745df/4b7745df_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4b7745df/4b7745df_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/4b7745df/4b7745df_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/4b7745df/4b7745df_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/4b7745df/4b7745df_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4b7745df/4b7745df_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/4b7745df/4b7745df_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/4b7745df/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4b7745df/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4b7745df/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/4b7745df/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/4b7745df/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4b7745df/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4b7745df/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/4b7745df/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/4b7745df/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4b7745df/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4b7745df/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/4b7745df/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/4b7745df/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4b7745df/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4b7745df/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/4b7745df/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/4e7d35e5/4e7d35e5_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/4e7d35e5/4e7d35e5_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4e7d35e5/4e7d35e5_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/4e7d35e5/4e7d35e5_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/4e7d35e5/4e7d35e5_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/4e7d35e5/4e7d35e5_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4e7d35e5/4e7d35e5_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/4e7d35e5/4e7d35e5_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/4e7d35e5/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4e7d35e5/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4e7d35e5/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/4e7d35e5/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/4e7d35e5/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4e7d35e5/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4e7d35e5/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/4e7d35e5/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/4e7d35e5/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4e7d35e5/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4e7d35e5/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/4e7d35e5/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/4e7d35e5/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/4e7d35e5/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4e7d35e5/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/4e7d35e5/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/52c9a980/52c9a980_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/52c9a980/52c9a980_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/52c9a980/52c9a980_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/52c9a980/52c9a980_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/52c9a980/52c9a980_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/52c9a980/52c9a980_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/52c9a980/52c9a980_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/52c9a980/52c9a980_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/52c9a980/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/52c9a980/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/52c9a980/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/52c9a980/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/52c9a980/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/52c9a980/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/52c9a980/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/52c9a980/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/52c9a980/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/52c9a980/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/52c9a980/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/52c9a980/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/52c9a980/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/52c9a980/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/52c9a980/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/52c9a980/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/5e54c468/5e54c468_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/5e54c468/5e54c468_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/5e54c468/5e54c468_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/5e54c468/5e54c468_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/5e54c468/5e54c468_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/5e54c468/5e54c468_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/5e54c468/5e54c468_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/5e54c468/5e54c468_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/5e54c468/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/5e54c468/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/5e54c468/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/5e54c468/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/5e54c468/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/5e54c468/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/5e54c468/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/5e54c468/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/5e54c468/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/5e54c468/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/5e54c468/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/5e54c468/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/5e54c468/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/5e54c468/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/5e54c468/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/5e54c468/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/61ce9067/61ce9067_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/61ce9067_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/61ce9067/61ce9067_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/61ce9067_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/61ce9067/61ce9067_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/61ce9067_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/61ce9067/61ce9067_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/61ce9067_mus_model.json diff --git a/resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/lilypond/part_I.ly new file mode 100644 index 0000000..36d5c00 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/lilypond/part_I.ly @@ -0,0 +1,10 @@ +{ + { r2. r16[ a'8.^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { a'2. g'4^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'16[ b'8.^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ b'2.} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/lilypond/part_II.ly new file mode 100644 index 0000000..172d34d --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/lilypond/part_II.ly @@ -0,0 +1,10 @@ +{ + { r4 r8.[ c''16^\markup { \pad-markup #0.2 "-4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ c''2 ~ } + \bar "|" + { c''2 f'2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { f'2 ~ f'8.[ c'16^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ c'4 ~ } + \bar "|" + { c'2 ~ c'8[ dis'8^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}] ~ dis'4} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/lilypond/part_III.ly new file mode 100644 index 0000000..80195eb --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/lilypond/part_III.ly @@ -0,0 +1,10 @@ +{ + { r16[ a8.^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}] ~ a2. } + \bar "|" + { g1^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g8[ b8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ b2. ~ } + \bar "|" + { b8.[ g16^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ g2.} +\bar "||" +} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates_stitch/61ce9067/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/lilypond/part_IV.ly similarity index 71% rename from resources/piece_ledger_sq1_candidates_stitch/61ce9067/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/lilypond/part_IV.ly index 962bfbd..ce0c70d 100644 --- a/resources/piece_ledger_sq1_candidates_stitch/61ce9067/lilypond/part_IV.ly +++ b/resources/resources_bak_2024_01_03/string_quartet_1/61ce9067/lilypond/part_IV.ly @@ -5,8 +5,6 @@ \bar "|" { g,1 ~ } \bar "|" - { g,1 ~ } - \bar "|" - { g,2 ~ g,8[ r8] r4} + { g,1} \bar "||" } \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates_stitch/62820081/62820081_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/62820081/62820081_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/62820081/62820081_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/62820081/62820081_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/62820081/62820081_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/62820081/62820081_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/62820081/62820081_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/62820081/62820081_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/631e2af1/631e2af1_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/631e2af1/631e2af1_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/631e2af1/631e2af1_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/631e2af1/631e2af1_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/631e2af1/631e2af1_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/631e2af1/631e2af1_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/631e2af1/631e2af1_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/631e2af1/631e2af1_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates/66f6a618/66f6a618_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/66f6a618/66f6a618_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates/66f6a618/66f6a618_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/66f6a618/66f6a618_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/66f6a618/66f6a618_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/66f6a618/66f6a618_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/66f6a618/66f6a618_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/66f6a618/66f6a618_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/66f6a618/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/66f6a618/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/66f6a618/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/66f6a618/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/66f6a618/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/66f6a618/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/66f6a618/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/66f6a618/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/66f6a618/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/66f6a618/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/66f6a618/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/66f6a618/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/66f6a618/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/66f6a618/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/66f6a618/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/66f6a618/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/6d635e88/6d635e88_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/6d635e88/6d635e88_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6d635e88/6d635e88_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/6d635e88/6d635e88_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/6d635e88/6d635e88_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/6d635e88/6d635e88_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6d635e88/6d635e88_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/6d635e88/6d635e88_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/6d635e88/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/6d635e88/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6d635e88/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/6d635e88/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/6d635e88/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/6d635e88/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6d635e88/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/6d635e88/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/6d635e88/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/6d635e88/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6d635e88/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/6d635e88/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/6d635e88/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/6d635e88/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6d635e88/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/6d635e88/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/6ed95c4c/6ed95c4c_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/6ed95c4c/6ed95c4c_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6ed95c4c/6ed95c4c_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/6ed95c4c/6ed95c4c_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/6ed95c4c/6ed95c4c_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/6ed95c4c/6ed95c4c_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6ed95c4c/6ed95c4c_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/6ed95c4c/6ed95c4c_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/6ed95c4c/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/6ed95c4c/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6ed95c4c/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/6ed95c4c/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/6ed95c4c/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/6ed95c4c/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6ed95c4c/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/6ed95c4c/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/6ed95c4c/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/6ed95c4c/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6ed95c4c/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/6ed95c4c/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/6ed95c4c/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/6ed95c4c/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6ed95c4c/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/6ed95c4c/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/6fb60ab6/6fb60ab6_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/6fb60ab6/6fb60ab6_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6fb60ab6/6fb60ab6_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/6fb60ab6/6fb60ab6_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/6fb60ab6/6fb60ab6_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/6fb60ab6/6fb60ab6_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6fb60ab6/6fb60ab6_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/6fb60ab6/6fb60ab6_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/6fb60ab6/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/6fb60ab6/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6fb60ab6/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/6fb60ab6/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/6fb60ab6/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/6fb60ab6/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6fb60ab6/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/6fb60ab6/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/6fb60ab6/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/6fb60ab6/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6fb60ab6/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/6fb60ab6/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/6fb60ab6/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/6fb60ab6/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/6fb60ab6/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/6fb60ab6/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/761e4585/761e4585_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/761e4585/761e4585_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/761e4585/761e4585_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/761e4585/761e4585_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/761e4585/761e4585_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/761e4585/761e4585_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/761e4585/761e4585_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/761e4585/761e4585_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/761e4585/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/761e4585/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/761e4585/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/761e4585/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/761e4585/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/761e4585/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/761e4585/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/761e4585/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/761e4585/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/761e4585/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/761e4585/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/761e4585/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/761e4585/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/761e4585/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/761e4585/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/761e4585/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/774ed940/774ed940_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/774ed940/774ed940_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/774ed940/774ed940_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/774ed940/774ed940_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/774ed940/774ed940_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/774ed940/774ed940_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/774ed940/774ed940_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/774ed940/774ed940_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/774ed940/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/774ed940/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/774ed940/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/774ed940/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/774ed940/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/774ed940/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/774ed940/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/774ed940/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/774ed940/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/774ed940/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/774ed940/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/774ed940/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/774ed940/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/774ed940/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/774ed940/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/774ed940/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/784130cc/784130cc_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/784130cc/784130cc_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/784130cc/784130cc_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/784130cc/784130cc_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/784130cc/784130cc_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/784130cc/784130cc_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/784130cc/784130cc_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/784130cc/784130cc_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/784130cc/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/784130cc/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/784130cc/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/784130cc/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/784130cc/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/784130cc/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/784130cc/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/784130cc/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/784130cc/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/784130cc/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/784130cc/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/784130cc/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/784130cc/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/784130cc/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/784130cc/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/784130cc/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/79e0a4a7/79e0a4a7_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/79e0a4a7/79e0a4a7_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/79e0a4a7/79e0a4a7_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/79e0a4a7/79e0a4a7_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/79e0a4a7/79e0a4a7_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/79e0a4a7/79e0a4a7_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/79e0a4a7/79e0a4a7_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/79e0a4a7/79e0a4a7_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/79e0a4a7/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/79e0a4a7/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/79e0a4a7/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/79e0a4a7/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/79e0a4a7/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/79e0a4a7/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/79e0a4a7/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/79e0a4a7/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/79e0a4a7/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/79e0a4a7/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/79e0a4a7/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/79e0a4a7/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/79e0a4a7/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/79e0a4a7/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/79e0a4a7/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/79e0a4a7/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/7d3c9a80/7d3c9a80_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/7d3c9a80/7d3c9a80_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/7d3c9a80/7d3c9a80_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/7d3c9a80/7d3c9a80_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/7d3c9a80/7d3c9a80_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/7d3c9a80/7d3c9a80_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/7d3c9a80/7d3c9a80_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/7d3c9a80/7d3c9a80_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/7d3c9a80/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/7d3c9a80/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/7d3c9a80/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/7d3c9a80/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/7d3c9a80/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/7d3c9a80/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/7d3c9a80/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/7d3c9a80/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/7d3c9a80/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/7d3c9a80/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/7d3c9a80/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/7d3c9a80/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/7d3c9a80/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/7d3c9a80/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/7d3c9a80/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/7d3c9a80/lilypond/part_IV.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/7edbdceb/7edbdceb_code.scd b/resources/resources_bak_2024_01_03/string_quartet_1/7edbdceb/7edbdceb_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/7edbdceb/7edbdceb_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_1/7edbdceb/7edbdceb_code.scd diff --git a/resources/piece_ledger_sq1_candidates_stitch/7edbdceb/7edbdceb_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/7edbdceb/7edbdceb_mus_model.json similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/7edbdceb/7edbdceb_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_1/7edbdceb/7edbdceb_mus_model.json diff --git a/resources/piece_ledger_sq1_candidates_stitch/7edbdceb/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_1/7edbdceb/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/7edbdceb/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/7edbdceb/lilypond/part_I.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/7edbdceb/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_1/7edbdceb/lilypond/part_II.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/7edbdceb/lilypond/part_II.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/7edbdceb/lilypond/part_II.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/7edbdceb/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_1/7edbdceb/lilypond/part_III.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/7edbdceb/lilypond/part_III.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/7edbdceb/lilypond/part_III.ly diff --git a/resources/piece_ledger_sq1_candidates_stitch/7edbdceb/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_1/7edbdceb/lilypond/part_IV.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/7edbdceb/lilypond/part_IV.ly rename to resources/resources_bak_2024_01_03/string_quartet_1/7edbdceb/lilypond/part_IV.ly diff --git a/resources/resources_bak_2024_01_03/string_quartet_1/tmp/tmp_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_1/tmp/tmp_mus_model.json new file mode 100644 index 0000000..1beabb8 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_1/tmp/tmp_mus_model.json @@ -0,0 +1,78 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ 2, -1, 1, -2, 1, 0 ], [ "Rest" ] ], 2.75 ], + [ [ [ 2, -1, 1, -2, 0, 0 ], [ "Rest" ], [ 2, -1, 1, -2, 1, 0 ], [ "Rest" ] ], 0.375 ], + [ [ [ 1, -1, 2, -2, 1, 0 ], [ "Rest" ], [ 2, -1, 1, -2, 1, 0 ], [ "Rest" ] ], 3.75 ] + ], + [ + [ [ [ 1, -1, 2, -2, 1, 0 ], [ "Rest" ], [ 2, -1, 1, -2, 1, 0 ], [ 2, -2, 1, -1, 1, 0 ] ], 0 ], + [ [ [ 1, -1, 2, -2, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 2, -1, 1, -2, 1, 0 ], [ 2, -2, 1, -1, 1, 0 ] ], 3.375 ], + [ [ [ 1, -1, 2, -2, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 3, -3, 1, -2, 0, 0 ], [ 2, -2, 1, -1, 1, 0 ] ], 1 ], + [ [ [ 1, -1, 2, -2, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 2, -2, 1, -1, 1, 0 ] ], 2 ] + ], + [ + [ [ [ 0, 1, 2, -2, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 2, -2, 1, -1, 1, 0 ] ], 1.125 ], + [ [ [ 2, -3, 1, -1, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 2, -2, 1, -1, 1, 0 ] ], 3 ] + ], + [ + [ [ [ 2, -3, 1, -1, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 2, -3, 0, -1, 1, 0 ] ], 0.875 ], + [ [ [ 2, -3, 1, -1, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 1, -3, 1, 0, 1, 0 ] ], 1.375 ] + ], + [ + [ [ [ 1, -3, 1, 0, 0, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 1, -3, 1, 0, 1, 0 ] ], 1.125 ], + [ [ [ 3, -3, 1, -2, 1, -1 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 1, -3, 1, 0, 1, 0 ] ], 1.875 ] + ], + [ + [ [ [ 3, -3, 1, -2, 1, -1 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 1, 0, 1, -2, 1, 0 ] ], 0.875 ], + [ [ [ 3, -3, 1, -2, 1, -1 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 0, 0, 2, -2, 2, 0 ] ], 2.125 ] + ], + [ + [ [ [ 3, -4, 1, -2, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 0, 0, 2, -2, 2, 0 ] ], 0.875 ], + [ [ [ 3, -3, 1, -2, 0, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 0, 0, 2, -2, 2, 0 ] ], 1.625 ], + [ [ [ 3, -3, 1, -2, 0, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ "Rest" ], [ 0, 0, 2, -2, 2, 0 ] ], 0.75 ], + [ [ [ "Rest" ], [ 3, -3, 1, -2, 1, 0 ], [ "Rest" ], [ 0, 0, 2, -2, 2, 0 ] ], 1.125 ], + [ [ [ "Rest" ], [ 3, -3, 1, -2, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 1.25 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 4.75 ] + ] + ] +], +"last_changes": +[ + [ [ 3, -3, 1, -2, 1, -1 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 1, -3, 1, 0, 1, 0 ] ], + [ [ 3, -3, 1, -2, 1, -1 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 1, 0, 1, -2, 1, 0 ] ], + [ [ 3, -3, 1, -2, 1, -1 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 0, 0, 2, -2, 2, 0 ] ], + [ [ 3, -4, 1, -2, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 0, 0, 2, -2, 2, 0 ] ], + [ [ 3, -3, 1, -2, 0, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 0, 0, 2, -2, 2, 0 ] ] +], +"cur_uid": "tmp", +"ref_uid": "6ed95c4c", +"order_seed": 290117, +"dur_seed": 200959, +"motifs_seed": 970117, +"entrances_probs_vals": [ 0.75, 0, 5.0793650793651, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], +"passages_probs_vals": [ 0.27, 0, 2.7380952380952, 0.24725274725275, 1.48, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], +"exits_probs_vals": [ 0.27, 0, 2.7380952380952, 0.24725274725275, 1.48, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], +"ranges": [ [ -1482.3529411765, 542 ], [ -1129.4117647059, 1378 ], [ -256.34674922601, 1601 ], [ -238, 1712.693498452 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.19135802469136, 0.27272727272727, 0.2962962962963, 0, 0.33539094650206, 0, 0.34362139917695, 0, 0.38271604938272, 0.15340909090909, 0.39711934156379, 0.56818181818182, 0.43415637860082, 0, 0.51028806584362, 0, 0.56172839506173, 0.84090909090909, 0.61316872427984, 0, 0.69135802469136, 0.28977272727273, 0.73662551440329, 0, 0.97736625514403, 0 ], +"passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 2 ], [ 0, 0 ], [ 3, 1 ] ], + [ [ 0, 3, 1 ], [ 2, 2 ], [ ] ], + [ [ 1, 3, 2 ], [ 0, 0 ], [ ] ], + [ [ 2, 0, 1 ], [ 3, 3 ], [ ] ], + [ [ 3, 1, 2 ], [ 0, 0 ], [ ] ], + [ [ 0, 2, 1 ], [ 3, 3 ], [ ] ], + [ [ 2, 3, 1 ], [ 0, 0 ], [ ] ] +], +"sus_weights": [ 0.45, 0.3, 0.38 ], +"order_size": [ 6.0510204081633, 15.142857142857 ], +"passages_size": [ 1, 1 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2.json b/resources/resources_bak_2024_01_03/string_quartet_2.json new file mode 100644 index 0000000..56e0507 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2.json @@ -0,0 +1,16 @@ +{ +"ledger": +[ + "5201b8af", + "525274f2", + "41e447bc", + "74307bb4", + "628706ec", + "4c059f33", + "60adbbef", + "74b8f8d9", + "62300302", + "72dc057f", + "76e45e56" +] +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2.json_bak b/resources/resources_bak_2024_01_03/string_quartet_2.json_bak new file mode 100644 index 0000000..d5a6964 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2.json_bak @@ -0,0 +1,15 @@ +{ +"ledger": +[ + "5201b8af", + "525274f2", + "41e447bc", + "74307bb4", + "628706ec", + "4c059f33", + "60adbbef", + "74b8f8d9", + "62300302", + "72dc057f" +] +} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/75638b4d/75638b4d_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/40119c5a/40119c5a_code.scd similarity index 81% rename from resources/piece_ledger_transcribe_test/75638b4d/75638b4d_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_2/40119c5a/40119c5a_code.scd index 3eb3cbd..c194eef 100644 --- a/resources/piece_ledger_transcribe_test/75638b4d/75638b4d_code.scd +++ b/resources/resources_bak_2024_01_03/string_quartet_2/40119c5a/40119c5a_code.scd @@ -33,15 +33,17 @@ var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; // other global vars var popSize, exPath, dir, primes, dims, tuples, -group, player, ledgerPath, ledger, currentlyPlayingUID, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, nameSpaces; -// install JSON quark +// install JSON quark (not used) +/* if(Quarks.isInstalled("JSONlib").not, { Quarks.install("https://github.com/musikinformatik/JSONlib.git"); thisProcess.recompile; //HelpBrowser.openHelpFor("Classes/JSONlib"); }); +*/ //------helper funcs @@ -615,14 +617,23 @@ globalVarsToDict = { loadLedgerFile = {arg path; ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) }; loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; saveLedger = {arg ledger, path; - var file; + var file, curResourceDir; file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); file.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); file.close; }; @@ -640,6 +651,7 @@ tuples = genTuples.value(); group = Group.new; ~group = group; loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); //passagesWeights = [1, 1, 1, 1, 1]; //susWeights = [1, 1, 1]; // order really matters!!!! @@ -692,7 +704,7 @@ OSCdef(\generate, {arg msg, time, addr, port; 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"); + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); lastXChanges = msgInterpret.value(file.readAllString.parseJSON["last_changes"]); }); @@ -744,10 +756,10 @@ OSCdef(\commit, {arg msg, time, addr, port; lastCurUID = curUID.deepCopy; curUID = genUID.value; - File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); - File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); - modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; + modelPath = (resourceDir +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; dict = globalVarsToDict.value; if(musicChanged, { seq = musicData; @@ -810,7 +822,7 @@ OSCdef(\transport, {arg msg, time, addr, port; 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; + path = (resourceDir +/+ 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; @@ -818,7 +830,7 @@ OSCdef(\transport, {arg msg, time, addr, port; }); if(cuedSeek, { var path, file; - path = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; + path = (resourceDir +/+ "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; @@ -847,7 +859,7 @@ OSCdef(\transcribe_motif, {arg msg, time, addr, port; if((refUID != "nil") && (refUID != "tmp"), { var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; file.close; }, { @@ -866,7 +878,7 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; indexEnd = ledger.size - if(cuedSeek, {2}, {1}); //tmp for testing transcription - indexEnd = (indexStart+5); + //indexEnd = (indexStart+5); //ledger.postln; if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { @@ -878,7 +890,7 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; ledger[indexStart..indexEnd].do({arg uid, index; var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; file = File(path, "r"); fileString = file.readAllString; tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); @@ -891,20 +903,20 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; file = File(path, "r"); refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; file.close; }); if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); }); lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); }); }); @@ -930,129 +942,4 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; ) -~transcribe.value(~seq, dir); - -( -//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; - - 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; -) -*/ diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/40119c5a/40119c5a_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/40119c5a/40119c5a_mus_model.json new file mode 100644 index 0000000..776b240 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/40119c5a/40119c5a_mus_model.json @@ -0,0 +1,58 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.875 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 4.875 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 1, 0, 0, 0 ] ], 4.75 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 4.125 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ] +], +"cur_uid": "40119c5a", +"ref_uid": "77b0d2dc", +"order_seed": 921767, +"dur_seed": 954688, +"motifs_seed": 995213, +"entrances_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "true", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates_stitch/66f6a618/66f6a618_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/41e447bc_code.scd similarity index 81% rename from resources/piece_ledger_sq1_candidates_stitch/66f6a618/66f6a618_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/41e447bc_code.scd index 3eb3cbd..c194eef 100644 --- a/resources/piece_ledger_sq1_candidates_stitch/66f6a618/66f6a618_code.scd +++ b/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/41e447bc_code.scd @@ -33,15 +33,17 @@ var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; // other global vars var popSize, exPath, dir, primes, dims, tuples, -group, player, ledgerPath, ledger, currentlyPlayingUID, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, nameSpaces; -// install JSON quark +// install JSON quark (not used) +/* if(Quarks.isInstalled("JSONlib").not, { Quarks.install("https://github.com/musikinformatik/JSONlib.git"); thisProcess.recompile; //HelpBrowser.openHelpFor("Classes/JSONlib"); }); +*/ //------helper funcs @@ -615,14 +617,23 @@ globalVarsToDict = { loadLedgerFile = {arg path; ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) }; loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; saveLedger = {arg ledger, path; - var file; + var file, curResourceDir; file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); file.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); file.close; }; @@ -640,6 +651,7 @@ tuples = genTuples.value(); group = Group.new; ~group = group; loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); //passagesWeights = [1, 1, 1, 1, 1]; //susWeights = [1, 1, 1]; // order really matters!!!! @@ -692,7 +704,7 @@ OSCdef(\generate, {arg msg, time, addr, port; 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"); + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); lastXChanges = msgInterpret.value(file.readAllString.parseJSON["last_changes"]); }); @@ -744,10 +756,10 @@ OSCdef(\commit, {arg msg, time, addr, port; lastCurUID = curUID.deepCopy; curUID = genUID.value; - File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); - File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); - modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; + modelPath = (resourceDir +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; dict = globalVarsToDict.value; if(musicChanged, { seq = musicData; @@ -810,7 +822,7 @@ OSCdef(\transport, {arg msg, time, addr, port; 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; + path = (resourceDir +/+ 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; @@ -818,7 +830,7 @@ OSCdef(\transport, {arg msg, time, addr, port; }); if(cuedSeek, { var path, file; - path = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; + path = (resourceDir +/+ "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; @@ -847,7 +859,7 @@ OSCdef(\transcribe_motif, {arg msg, time, addr, port; if((refUID != "nil") && (refUID != "tmp"), { var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; file.close; }, { @@ -866,7 +878,7 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; indexEnd = ledger.size - if(cuedSeek, {2}, {1}); //tmp for testing transcription - indexEnd = (indexStart+5); + //indexEnd = (indexStart+5); //ledger.postln; if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { @@ -878,7 +890,7 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; ledger[indexStart..indexEnd].do({arg uid, index; var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; file = File(path, "r"); fileString = file.readAllString; tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); @@ -891,20 +903,20 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; file = File(path, "r"); refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; file.close; }); if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); }); lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); }); }); @@ -930,129 +942,4 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; ) -~transcribe.value(~seq, dir); - -( -//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; - - 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; -) -*/ diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/41e447bc_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/41e447bc_mus_model.json new file mode 100644 index 0000000..105ee42 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/41e447bc_mus_model.json @@ -0,0 +1,64 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 2.125 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 4.75 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 1, 0, 0, 0 ] ], 2.875 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 3.375 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 1.375 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 4.625 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ "Rest" ], [ 0, 1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ] +], +"cur_uid": "41e447bc", +"ref_uid": "77b0d2dc", +"order_seed": 921767, +"dur_seed": 954688, +"motifs_seed": 995213, +"entrances_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "true", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/lilypond/part_I.ly new file mode 100644 index 0000000..9aaa7f4 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/lilypond/part_I.ly @@ -0,0 +1,20 @@ +{ + { r1 } + \bar "|" + { r16[ c''8.^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ c''2. ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''4 ~ c''8.[ e'16^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ e'2 ~ } + \bar "|" + { e'2. ~ e'8[ e'8^\markup { \pad-markup #0.2 "-41"}] ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2 ~ e'16[ dis'8.^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ dis'4 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/lilypond/part_II.ly new file mode 100644 index 0000000..2fe1107 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/lilypond/part_II.ly @@ -0,0 +1,20 @@ +{ + { r1 } + \bar "|" + { r16[ e'8.^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ e'2. ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'4 ~ e'8.[ e'16^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ e'2 ~ } + \bar "|" + { e'2. ~ e'8[ f'8^\markup { \pad-markup #0.2 "-2"}] ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/lilypond/part_III.ly new file mode 100644 index 0000000..bfe5f3a --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/lilypond/part_III.ly @@ -0,0 +1,20 @@ +{ + { r1 } + \bar "|" + { r16[ fis'8.^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] ~ fis'2. ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'4 ~ fis'8.[ g'16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ g'2 ~ } + \bar "|" + { g'2. ~ g'8[ gis'8^\markup { \pad-markup #0.2 "+14"}] ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'4 a'2.^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} ~ } + \bar "|" + { a'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/lilypond/part_IV.ly new file mode 100644 index 0000000..0787499 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/41e447bc/lilypond/part_IV.ly @@ -0,0 +1,20 @@ +{ + { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/600e3005/600e3005_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/42c3365b/42c3365b_code.scd similarity index 81% rename from resources/piece_ledger_transcribe_test/600e3005/600e3005_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_2/42c3365b/42c3365b_code.scd index 3eb3cbd..c194eef 100644 --- a/resources/piece_ledger_transcribe_test/600e3005/600e3005_code.scd +++ b/resources/resources_bak_2024_01_03/string_quartet_2/42c3365b/42c3365b_code.scd @@ -33,15 +33,17 @@ var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; // other global vars var popSize, exPath, dir, primes, dims, tuples, -group, player, ledgerPath, ledger, currentlyPlayingUID, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, nameSpaces; -// install JSON quark +// install JSON quark (not used) +/* if(Quarks.isInstalled("JSONlib").not, { Quarks.install("https://github.com/musikinformatik/JSONlib.git"); thisProcess.recompile; //HelpBrowser.openHelpFor("Classes/JSONlib"); }); +*/ //------helper funcs @@ -615,14 +617,23 @@ globalVarsToDict = { loadLedgerFile = {arg path; ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) }; loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; saveLedger = {arg ledger, path; - var file; + var file, curResourceDir; file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); file.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); file.close; }; @@ -640,6 +651,7 @@ tuples = genTuples.value(); group = Group.new; ~group = group; loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); //passagesWeights = [1, 1, 1, 1, 1]; //susWeights = [1, 1, 1]; // order really matters!!!! @@ -692,7 +704,7 @@ OSCdef(\generate, {arg msg, time, addr, port; 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"); + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); lastXChanges = msgInterpret.value(file.readAllString.parseJSON["last_changes"]); }); @@ -744,10 +756,10 @@ OSCdef(\commit, {arg msg, time, addr, port; lastCurUID = curUID.deepCopy; curUID = genUID.value; - File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); - File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); - modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; + modelPath = (resourceDir +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; dict = globalVarsToDict.value; if(musicChanged, { seq = musicData; @@ -810,7 +822,7 @@ OSCdef(\transport, {arg msg, time, addr, port; 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; + path = (resourceDir +/+ 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; @@ -818,7 +830,7 @@ OSCdef(\transport, {arg msg, time, addr, port; }); if(cuedSeek, { var path, file; - path = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; + path = (resourceDir +/+ "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; @@ -847,7 +859,7 @@ OSCdef(\transcribe_motif, {arg msg, time, addr, port; if((refUID != "nil") && (refUID != "tmp"), { var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; file.close; }, { @@ -866,7 +878,7 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; indexEnd = ledger.size - if(cuedSeek, {2}, {1}); //tmp for testing transcription - indexEnd = (indexStart+5); + //indexEnd = (indexStart+5); //ledger.postln; if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { @@ -878,7 +890,7 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; ledger[indexStart..indexEnd].do({arg uid, index; var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; file = File(path, "r"); fileString = file.readAllString; tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); @@ -891,20 +903,20 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; file = File(path, "r"); refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; file.close; }); if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); }); lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); }); }); @@ -930,129 +942,4 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; ) -~transcribe.value(~seq, dir); - -( -//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; - - 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; -) -*/ diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/42c3365b/42c3365b_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/42c3365b/42c3365b_mus_model.json new file mode 100644 index 0000000..710f1b3 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/42c3365b/42c3365b_mus_model.json @@ -0,0 +1,123 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 1.5 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 1.25 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ] ], 0.5 ], + [ [ [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ] ], 0.875 ], + [ [ [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 1 ] ], 1.25 ], + [ [ [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 1 ] ], 0 ] + ], + [ + [ [ [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.75 ], + [ [ [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1.375 ], + [ [ [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.5 ], + [ [ [ 0, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1.375 ], + [ [ [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.75 ], + [ [ [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.125 ], + [ [ [ -1, 0, 0, 0, 1, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1 ], + [ [ [ 0, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1.375 ], + [ [ [ -1, 0, 1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.5 ] + ], + [ + [ [ [ -1, 0, 1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.75 ], + [ [ [ -1, 0, 1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ 2, -1, 0, 0, 0, -1 ] ], 0.125 ], + [ [ [ -1, -1, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ 2, -1, 0, 0, 0, -1 ] ], 1.375 ], + [ [ [ -1, -1, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ 2, -1, 0, -1, 0, 0 ] ], 0.125 ] + ], + [ + [ [ [ -1, -1, 0, 1, 0, 0 ], [ 1, -1, 0, -1, 0, 1 ], [ "Rest" ], [ 2, -1, 0, -1, 0, 0 ] ], 0.75 ], + [ [ [ 0, -1, 0, -1, 0, 1 ], [ 1, -1, 0, -1, 0, 1 ], [ "Rest" ], [ 2, -1, 0, -1, 0, 0 ] ], 0 ], + [ [ [ 0, -1, 0, -1, 0, 1 ], [ 2, -1, -1, -1, 0, 0 ], [ "Rest" ], [ 2, -1, 0, -1, 0, 0 ] ], 0.875 ], + [ [ [ 0, 0, 0, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ "Rest" ], [ 2, -1, 0, -1, 0, 0 ] ], 0.125 ], + [ [ [ 0, 0, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ "Rest" ], [ 2, -1, 0, -1, 0, 0 ] ], 0.75 ], + [ [ [ 1, -1, 0, -1, -1, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ "Rest" ], [ 2, -1, 0, -1, 0, 0 ] ], 1.375 ], + [ [ [ 0, -1, 0, -1, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ "Rest" ], [ 2, -1, 0, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, -1, 0, -1, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ "Rest" ], [ 1, 0, 1, -1, 0, 0 ] ], 1.125 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ "Rest" ], [ 1, 0, 1, -1, 0, 0 ] ], 1.375 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, -1, 0, 1 ], [ 1, 0, 1, -1, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ] ], 0.625 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.375 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 1 ] ], 0.125 ], + [ [ [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 1 ] ], 1.5 ], + [ [ [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 1 ] ], 0.875 ] + ], + [ + [ [ [ -1, 2, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 1 ] ], 0.625 ], + [ [ [ -1, 2, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, 0, -1, 0, 0 ] ], 0.125 ], + [ [ [ -1, 2, 0, -1, 0, 0 ], [ 0, 1, 1, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, 0, -1, 0, 0 ] ], 0.125 ] + ], + [ + [ [ [ -1, 2, 0, -1, 0, 0 ], [ 0, 1, 1, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 2, 0, -1, 0, 0 ] ], 0.375 ], + [ [ [ -1, 2, 0, -1, 0, 0 ], [ 1, 1, 0, -1, 0, -1 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 2, 0, -1, 0, 0 ] ], 0.25 ], + [ [ [ 0, 1, 0, -1, -1, 0 ], [ 1, 1, 0, -1, 0, -1 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 2, 0, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 1, 0, -1, -1, 0 ], [ 1, 1, 0, -1, 0, -1 ], [ 0, 1, 0, -1, 0, 0 ], [ 2, 1, 0, -1, -1, 0 ] ], 1 ], + [ [ [ 0, 1, 0, -1, -1, 0 ], [ 1, 1, 0, -1, 0, -1 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, 0, -1, 1, 0 ] ], 0.875 ], + [ [ [ -1, 1, 0, -1, 1, 0 ], [ 1, 1, 0, -1, 0, -1 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, 0, -1, 1, 0 ] ], 0.875 ], + [ [ [ 0, 0, 0, -1, 0, 0 ], [ 1, 1, 0, -1, 0, -1 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, 0, -1, 1, 0 ] ], 1.25 ], + [ [ [ 0, 1, 0, -1, 0, -1 ], [ 1, 1, 0, -1, 0, -1 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, 0, -1, 1, 0 ] ], 0.375 ], + [ [ [ 0, 1, 0, -1, 0, -1 ], [ 0, 1, 1, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, 0, -1, 1, 0 ] ], 1.5 ], + [ [ [ 0, 1, 0, -2, 0, 0 ], [ 0, 1, 1, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, 0, -1, 1, 0 ] ], 0.375 ], + [ [ [ 0, 1, 0, -2, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, 0, -1, 1, 0 ] ], 0.25 ], + [ [ [ 0, 1, 0, -2, 0, 0 ], [ 0, 1, 0, -1, 1, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, 0, -1, 1, 0 ] ], 0.875 ] + ], + [ + [ [ [ "Rest" ], [ 0, 1, 0, -1, 1, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, 0, -1, 1, 0 ] ], 0.625 ], + [ [ [ "Rest" ], [ 0, 1, 0, -1, 1, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, 0, -1, 1, -1 ] ], 0.5 ], + [ [ [ "Rest" ], [ 0, 1, 0, -1, 1, 0 ], [ -1, 2, 0, -1, 1, 0 ], [ 1, 1, 0, -1, 1, -1 ] ], 1 ], + [ [ [ "Rest" ], [ 0, 1, 0, -1, 1, 0 ], [ 0, 1, -1, -1, 1, 0 ], [ 1, 1, 0, -1, 1, -1 ] ], 1.125 ], + [ [ [ "Rest" ], [ 0, 1, 0, -1, 1, 0 ], [ -1, 1, 0, -1, 1, 1 ], [ 1, 1, 0, -1, 1, -1 ] ], 1.375 ], + [ [ [ "Rest" ], [ 0, 1, 0, -1, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 1, 1, 0, -1, 1, -1 ] ], 0 ], + [ [ [ "Rest" ], [ 0, 1, 0, -1, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 0, 1, 1, -1, 1, 0 ] ], 0.125 ], + [ [ [ "Rest" ], [ 0, 1, 0, -1, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 1, 0 ] ], 1.375 ], + [ [ [ "Rest" ], [ 0, 1, 0, -1, 1, 0 ], [ -1, 2, 0, -1, 1, 0 ], [ 1, 0, 0, -1, 1, 0 ] ], 0.875 ], + [ [ [ "Rest" ], [ 0, 1, 0, -1, 1, 0 ], [ 0, 1, -1, -1, 1, 0 ], [ 1, 0, 0, -1, 1, 0 ] ], 0.375 ], + [ [ [ "Rest" ], [ 0, 1, 0, -1, 1, 0 ], [ 0, 1, -1, -1, 1, 0 ], [ 0, 1, 0, -1, 2, 0 ] ], 0.625 ], + [ [ [ "Rest" ], [ 0, 1, 0, -1, 1, 0 ], [ 0, 1, -1, -1, 1, 0 ], [ "Rest" ] ], 0.5 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, -1, 1, 0 ], [ "Rest" ] ], 0.625 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 5.125 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 1, 0, -2, 0, 0 ], [ 0, 1, 0, -1, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 0, 1, 1, -1, 1, 0 ] ], + [ [ 0, 1, 0, -2, 0, 0 ], [ 0, 1, 0, -1, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 1, 0 ] ], + [ [ 0, 1, 0, -2, 0, 0 ], [ 0, 1, 0, -1, 1, 0 ], [ -1, 2, 0, -1, 1, 0 ], [ 1, 0, 0, -1, 1, 0 ] ], + [ [ 0, 1, 0, -2, 0, 0 ], [ 0, 1, 0, -1, 1, 0 ], [ 0, 1, -1, -1, 1, 0 ], [ 1, 0, 0, -1, 1, 0 ] ], + [ [ 0, 1, 0, -2, 0, 0 ], [ 0, 1, 0, -1, 1, 0 ], [ 0, 1, -1, -1, 1, 0 ], [ 0, 1, 0, -1, 2, 0 ] ] +], +"cur_uid": "42c3365b", +"ref_uid": "nil", +"order_seed": 921767, +"dur_seed": 787806, +"motifs_seed": 995213, +"entrances_probs_vals": [ 0, 0, 0, 0, 1.6208791208791, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 0, 1.6208791208791, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 0, 1.6208791208791, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 1 ], [ 0, 3, 0, 3, 0 ], [ 2 ] ], + [ [ 2 ], [ 0, 1, 1, 1, 0, 0, 0 ], [ 3 ] ], + [ [ 1 ], [ 3, 0, 3 ], [ 2 ] ], + [ [ 3 ], [ 1, 0, 1, 0, 1, 0, 0 ], [ 2 ] ], + [ [ 1 ], [ 3, 0, 2, 2, 3, 3, 0, 2 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 2 ], [ 3, 1, 0, 3, 3, 0, 0, 0, 1, 0, 1, 1 ], [ ] ], + [ [ 1 ], [ 3, 2, 2, 2, 2, 3, 3, 2, 2, 3 ], [ 0 ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/4660b5c4/4660b5c4_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/4660b5c4/4660b5c4_code.scd new file mode 100644 index 0000000..57e638d --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/4660b5c4/4660b5c4_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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 = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).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.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/4660b5c4/4660b5c4_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/4660b5c4/4660b5c4_mus_model.json new file mode 100644 index 0000000..fba5fcb --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/4660b5c4/4660b5c4_mus_model.json @@ -0,0 +1,59 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 4.625 ], + [ [ [ 0, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 3, -2, -2, 1, 0 ] ], 0 ], + [ [ [ 0, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -2, 1, 0 ] ], 0 ], + [ [ [ 0, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -2, 1, 0 ] ], 5.875 ] + ], + [ + [ [ [ 0, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -1, 3, -2, -2, 1, 0 ] ], 0 ], + [ [ [ 0, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 2, 0 ], [ -1, 3, -2, -2, 1, 0 ] ], 0 ], + [ [ [ 0, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 2, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 6.625 ] + ], + [ + [ [ [ 0, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -1, 0, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ 0, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -1, 0, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ 0, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 3, -2, -1, 0, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 4.875 ], + [ [ [ 0, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ "Rest" ], [ -2, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ 0, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ 0, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 6.0 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 2, 0 ], [ -1, 3, -2, -2, 1, 0 ] ], + [ [ 0, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 2, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], + [ [ 0, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -1, 0, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], + [ [ 0, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -1, 0, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], + [ [ 0, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 3, -2, -1, 0, 0 ], [ -2, 3, -1, -1, 1, 0 ] ] +], +"cur_uid": "4660b5c4", +"ref_uid": "4c059f33", +"order_seed": 706160, +"dur_seed": 659279, +"motifs_seed": 885545, +"entrances_probs_vals": [ 1, 0, 5.0793650793651, 0.47, 2.8021978021978, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 2.7380952380952, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 2.7380952380952, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8.0714285714286, 10.091836734694 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/piece_ledger_sq1_candidates_stitch/4a8a6e53/4a8a6e53_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/4a8a6e53_code.scd similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4a8a6e53/4a8a6e53_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/4a8a6e53_code.scd diff --git a/resources/piece_ledger_sq1_candidates/4a8a6e53/4a8a6e53_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/4a8a6e53_mus_model.json similarity index 99% rename from resources/piece_ledger_sq1_candidates/4a8a6e53/4a8a6e53_mus_model.json rename to resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/4a8a6e53_mus_model.json index 715f342..150baf5 100644 --- a/resources/piece_ledger_sq1_candidates/4a8a6e53/4a8a6e53_mus_model.json +++ b/resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/4a8a6e53_mus_model.json @@ -58,7 +58,7 @@ [ [ [ 0, -1, 0, 0, -1, 1 ], [ "Rest" ], [ 2, -2, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 3.375 ], [ [ [ 0, -1, 0, 0, -1, 1 ], [ "Rest" ], [ 2, -2, 0, 0, -1, 0 ], [ "Rest" ] ], 1.5 ], [ [ [ 0, -1, 0, 0, -1, 1 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.375 ], - [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ] + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 2 ] ] ] ], diff --git a/resources/piece_ledger_sq1_candidates_stitch/4a8a6e53/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/lilypond/part_I.ly similarity index 100% rename from resources/piece_ledger_sq1_candidates_stitch/4a8a6e53/lilypond/part_I.ly rename to resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/lilypond/part_I.ly diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/lilypond/part_II.ly new file mode 100644 index 0000000..3c00ff8 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/lilypond/part_II.ly @@ -0,0 +1,56 @@ +{ + { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'4 ~ c'16[ e'8.^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ e'2 ~ } + \bar "|" + { e'2 ~ e'8.[ g'16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ g'4 ~ } + \bar "|" + { g'4 ~ g'8[ ais'8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ ais'2 ~ } + \bar "|" + { ais'4 ~ ais'8.[ gis'16^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}] ~ gis'2 } + \bar "|" + { gis'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ gis'8[ g'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ g'4 ~ } + \bar "|" + { g'8[ f'8^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ f'2. ~ } + \bar "|" + { f'4 ~ f'8[ e'8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}] ~ e'2 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'16[ fis'8.^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ fis'2. ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'16[ a'8.^\markup { \pad-markup #0.2 "-20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ a'2 ~ a'16[ ais'8.^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }}] ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'2 ~ ais'16[ b'8.^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ b'4 ~ } + \bar "|" + { b'2 ~ b'8[ a'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}] ~ a'4 ~ } + \bar "|" + { a'2 ~ a'8.[ fis'16^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}] ~ fis'4 ~ } + \bar "|" + { fis'16[ f'8.^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↑" }}] ~ f'2. ~ } + \bar "|" + { f'4 ~ f'8.[ e'16^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}] ~ e'2 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'4 ~ e'16[ r8.] r2 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/lilypond/part_III.ly new file mode 100644 index 0000000..75dcb1c --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/lilypond/part_III.ly @@ -0,0 +1,56 @@ +{ + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r16[ ais8.^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ ais2. ~ } + \bar "|" + { ais2. gis4^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { gis16[ fis8.^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] ~ fis2. ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis2 ~ fis8.[ r16] r4 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/lilypond/part_IV.ly new file mode 100644 index 0000000..41471e8 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/4a8a6e53/lilypond/part_IV.ly @@ -0,0 +1,56 @@ +{ + { r4 r8.[ c'16^\markup { \pad-markup #0.2 "+0"}] ~ c'2 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 } + \bar "|" + { b1^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b4 ~ b8[ ais8^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}] ~ ais8.[ a16^\markup { \pad-markup #0.2 "-20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }}] ~ a4 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a16[ a8.^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}] ~ a2. } + \bar "|" + { gis1^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }} ~ } + \bar "|" + { gis8.[ gis16^\markup { \pad-markup #0.2 "-40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}] ~ gis2. ~ } + \bar "|" + { gis4 ~ gis8[ f8^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ f4 fis4^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }} ~ } + \bar "|" + { fis2. ~ fis8[ gis8^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }}] ~ } + \bar "|" + { gis1 ~ } + \bar "|" + { gis1 ~ } + \bar "|" + { gis1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/piece_ledger_transcribe_test/57fa6a01/57fa6a01_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/4c059f33_code.scd similarity index 81% rename from resources/piece_ledger_transcribe_test/57fa6a01/57fa6a01_code.scd rename to resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/4c059f33_code.scd index b638147..c194eef 100644 --- a/resources/piece_ledger_transcribe_test/57fa6a01/57fa6a01_code.scd +++ b/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/4c059f33_code.scd @@ -33,15 +33,17 @@ var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; // other global vars var popSize, exPath, dir, primes, dims, tuples, -group, player, ledgerPath, ledger, currentlyPlayingUID, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, nameSpaces; -// install JSON quark +// install JSON quark (not used) +/* if(Quarks.isInstalled("JSONlib").not, { Quarks.install("https://github.com/musikinformatik/JSONlib.git"); thisProcess.recompile; //HelpBrowser.openHelpFor("Classes/JSONlib"); }); +*/ //------helper funcs @@ -615,14 +617,23 @@ globalVarsToDict = { loadLedgerFile = {arg path; ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) }; loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; saveLedger = {arg ledger, path; - var file; + var file, curResourceDir; file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); file.write("{\n\"ledger\":\n" ++ stringifyToDepth.value(ledger, 1) ++ "\n}"); file.close; }; @@ -640,6 +651,7 @@ tuples = genTuples.value(); group = Group.new; ~group = group; loadLedgerFile.value(dir +/+ ".." +/+ "resources" +/+ "piece_ledger.json"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); //passagesWeights = [1, 1, 1, 1, 1]; //susWeights = [1, 1, 1]; // order really matters!!!! @@ -692,7 +704,7 @@ OSCdef(\generate, {arg msg, time, addr, port; 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"); + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); lastXChanges = msgInterpret.value(file.readAllString.parseJSON["last_changes"]); }); @@ -744,10 +756,10 @@ OSCdef(\commit, {arg msg, time, addr, port; lastCurUID = curUID.deepCopy; curUID = genUID.value; - File.mkdir((dir +/+ ".." +/+ "resources" +/+ curUID).standardizePath); - File.copy(exPath, (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); - modelPath = (dir +/+ ".." +/+ "resources" +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; + modelPath = (resourceDir +/+ curUID +/+ curUID ++ "_mus_model" ++ ".json").standardizePath; dict = globalVarsToDict.value; if(musicChanged, { seq = musicData; @@ -776,7 +788,7 @@ OSCdef(\commit, {arg msg, time, addr, port; if(commitType == "add", {ledger = ledger.add(curUID)}); - if(commitType == "insert", {ledger = ledger.insert(commitPos - 1, curUID)}); + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); @@ -810,7 +822,7 @@ OSCdef(\transport, {arg msg, time, addr, port; 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; + path = (resourceDir +/+ 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; @@ -818,7 +830,7 @@ OSCdef(\transport, {arg msg, time, addr, port; }); if(cuedSeek, { var path, file; - path = (dir +/+ ".." +/+ "resources/tmp/tmp_mus_model" ++ ".json").standardizePath; + path = (resourceDir +/+ "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; @@ -847,7 +859,7 @@ OSCdef(\transcribe_motif, {arg msg, time, addr, port; if((refUID != "nil") && (refUID != "tmp"), { var file; - file = File((dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; file.close; }, { @@ -866,7 +878,7 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; indexEnd = ledger.size - if(cuedSeek, {2}, {1}); //tmp for testing transcription - indexEnd = (indexStart+5); + //indexEnd = (indexStart+5); //ledger.postln; if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { @@ -878,7 +890,7 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; ledger[indexStart..indexEnd].do({arg uid, index; var path, file, fileString, tSeq, refUID, refChord; - path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; file = File(path, "r"); fileString = file.readAllString; tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); @@ -891,20 +903,20 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; if(refUID != "nil", { - path = (dir +/+ ".." +/+ "resources" +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; file = File(path, "r"); refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; file.close; }); if(index != indexEnd, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath); + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); }, { - ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); }); lilyPartLedgerFiles.do({arg f, p; - f.write("\\include \".." +/+ ".." +/+ "resources" +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); }); }); @@ -930,129 +942,4 @@ OSCdef(\transcribe_all, {arg msg, time, addr, port; ) -~transcribe.value(~seq, dir); - -( -//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; - - 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; -) -*/ diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/4c059f33_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/4c059f33_mus_model.json new file mode 100644 index 0000000..fd5c9df --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/4c059f33_mus_model.json @@ -0,0 +1,58 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 3, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ] ], 4.875 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -2, 3, -1, -1, 1, 0 ] ], 4.75 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 4.125 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ "Rest" ], [ -1, 3, -3, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ "Rest" ], [ -1, 3, -3, -1, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ 0, 3, -1, -1, 1, 0 ], [ -1, 4, -2, -1, 1, 0 ] ], + [ [ 0, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ 0, 3, -1, -1, 1, 0 ], [ 0, 3, -3, -1, 1, 0 ] ], + [ [ 0, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ 1, 3, -2, -1, 1, -1 ], [ 0, 3, -3, -1, 1, 0 ] ], + [ [ 0, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ 1, 3, -2, -1, 1, -1 ], [ -1, 3, -2, -1, 1, 1 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -2, -1, 1, 1 ] ] +], +"cur_uid": "4c059f33", +"ref_uid": "628706ec", +"order_seed": 706160, +"dur_seed": 146047, +"motifs_seed": 575591, +"entrances_probs_vals": [ 1, 0, 0, 0.47, 2.8021978021978, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0.77, 0, 0, 0, 1.6208791208791, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "true", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/lilypond/part_I.ly new file mode 100644 index 0000000..e46bd01 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/lilypond/part_I.ly @@ -0,0 +1,16 @@ +{ + { r2 a2^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a2. ~ a8.[ cis16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis4 ~ cis16[ cis8.^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ cis2 ~ } + \bar "|" + { cis1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/lilypond/part_II.ly new file mode 100644 index 0000000..c17645f --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/lilypond/part_II.ly @@ -0,0 +1,16 @@ +{ + { r2 cis2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis2. ~ cis8.[ cis16^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis4 ~ cis16[ d8.^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ d2 ~ } + \bar "|" + { d1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/lilypond/part_III.ly new file mode 100644 index 0000000..f07edd8 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/lilypond/part_III.ly @@ -0,0 +1,16 @@ +{ + { r2 e2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e2. ~ e8.[ e16^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e4 ~ e16[ f8.^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ f2 ~ } + \bar "|" + { f1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/lilypond/part_IV.ly new file mode 100644 index 0000000..4db8109 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/4c059f33/lilypond/part_IV.ly @@ -0,0 +1,16 @@ +{ + { a,1^\markup { \pad-markup #0.2 "+16"} ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/5201b8af_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/5201b8af_code.scd new file mode 100644 index 0000000..c194eef --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/5201b8af_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/5201b8af_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/5201b8af_mus_model.json new file mode 100644 index 0000000..aa90760 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/5201b8af_mus_model.json @@ -0,0 +1,58 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 4.875 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 1, 0, 0, 0 ] ], 4.75 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 4.125 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ] +], +"cur_uid": "5201b8af", +"ref_uid": "77b0d2dc", +"order_seed": 921767, +"dur_seed": 954688, +"motifs_seed": 995213, +"entrances_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "true", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/lilypond/part_I.ly new file mode 100644 index 0000000..01ab702 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/lilypond/part_I.ly @@ -0,0 +1,16 @@ +{ + { r2 c''2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''2. ~ c''8.[ e'16^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'4 ~ e'16[ e'8.^\markup { \pad-markup #0.2 "-41"}] ~ e'2 ~ } + \bar "|" + { e'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/lilypond/part_II.ly new file mode 100644 index 0000000..f176e75 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/lilypond/part_II.ly @@ -0,0 +1,16 @@ +{ + { r2 e'2^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2. ~ e'8.[ e'16^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'4 ~ e'16[ f'8.^\markup { \pad-markup #0.2 "-2"}] ~ f'2 ~ } + \bar "|" + { f'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/lilypond/part_III.ly new file mode 100644 index 0000000..5f83063 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/lilypond/part_III.ly @@ -0,0 +1,16 @@ +{ + { r2 fis'2^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'2. ~ fis'8.[ g'16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'4 ~ g'16[ gis'8.^\markup { \pad-markup #0.2 "+14"}] ~ gis'2 ~ } + \bar "|" + { gis'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/lilypond/part_IV.ly new file mode 100644 index 0000000..67fc5d0 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/5201b8af/lilypond/part_IV.ly @@ -0,0 +1,16 @@ +{ + { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/525274f2_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/525274f2_code.scd new file mode 100644 index 0000000..c194eef --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/525274f2_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/525274f2_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/525274f2_mus_model.json new file mode 100644 index 0000000..a8be70b --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/525274f2_mus_model.json @@ -0,0 +1,66 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 3.375 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 1, 0, 0, 0 ] ], 1.25 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 3.125 ] + ], + [ + [ [ [ 1, 0, -1, 0, 0, -1 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 1, 0, -1, 0, 0, -1 ], [ 1, 0, 1, 0, 0, -1 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 2.25 ] + ], + [ + [ [ [ 1, -1, 0, 0, -1, 0 ], [ 1, 0, 1, 0, 0, -1 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 2.625 ], + [ [ [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], + [ [ [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ 2, -1, 0, -1, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ] +], +"cur_uid": "525274f2", +"ref_uid": "77b0d2dc", +"order_seed": 921767, +"dur_seed": 954688, +"motifs_seed": 995213, +"entrances_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "true", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/lilypond/part_I.ly new file mode 100644 index 0000000..a568867 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/lilypond/part_I.ly @@ -0,0 +1,14 @@ +{ + { r2 c''2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''8.[ e'16^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ e'2 ~ e'16[ e'8.^\markup { \pad-markup #0.2 "-41"}] ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/lilypond/part_II.ly new file mode 100644 index 0000000..9a7f7ed --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/lilypond/part_II.ly @@ -0,0 +1,14 @@ +{ + { r2 e'2^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'8.[ e'16^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ e'2 ~ e'16[ f'8.^\markup { \pad-markup #0.2 "-2"}] ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/lilypond/part_III.ly new file mode 100644 index 0000000..ac151b0 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/lilypond/part_III.ly @@ -0,0 +1,14 @@ +{ + { r2 fis'2^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'8.[ g'16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ g'2 ~ g'16[ gis'8.^\markup { \pad-markup #0.2 "+14"}] ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'4 ~ gis'8[ g'8^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }}] ~ g'2 ~ } + \bar "|" + { g'2 g'2^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/lilypond/part_IV.ly new file mode 100644 index 0000000..e646018 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/525274f2/lilypond/part_IV.ly @@ -0,0 +1,14 @@ +{ + { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'4 ~ c'8[ c'8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }}] ~ c'2 ~ } + \bar "|" + { c'2 b2^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/60adbbef_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/60adbbef_code.scd new file mode 100644 index 0000000..57e638d --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/60adbbef_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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 = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).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.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/60adbbef_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/60adbbef_mus_model.json new file mode 100644 index 0000000..748c135 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/60adbbef_mus_model.json @@ -0,0 +1,65 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.75 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 4.75 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 2, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ] ], 7.125 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -2, 3, -2, -1, 2, 0 ], [ -1, 3, -3, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -2, 3, -2, -1, 2, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -2, 3, -2, -1, 2, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], 4.5 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 6.875 ], + [ [ [ "Rest" ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ "Rest" ], [ -1, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 10.75 ] + ] + ] +], +"last_changes": +[ + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -2, 3, -2, -1, 2, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -2, 3, -2, -1, 2, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -1, -1, 1, 0 ] ] +], +"cur_uid": "60adbbef", +"ref_uid": "4c059f33", +"order_seed": 824152, +"dur_seed": 266394, +"motifs_seed": 206072, +"entrances_probs_vals": [ 1, 0, 5.0793650793651, 0.47, 2.8021978021978, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 2.7380952380952, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 2.7380952380952, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8.0714285714286, 10.091836734694 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/lilypond/part_I.ly new file mode 100644 index 0000000..708ce11 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/lilypond/part_I.ly @@ -0,0 +1,38 @@ +{ + { r1 } + \bar "|" + { r2. r8[ e8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e4 f2.^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f2. ~ f16[ cis'8.^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'16[ cis'8.^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ cis'2. ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'2 r2 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/lilypond/part_II.ly new file mode 100644 index 0000000..7fea40e --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/lilypond/part_II.ly @@ -0,0 +1,38 @@ +{ + { r1 } + \bar "|" + { r2. r8[ cis8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis4 d2.^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d2. ~ d16[ dis8.^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis16[ e8.^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] ~ e2. ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e2 r2 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/lilypond/part_III.ly new file mode 100644 index 0000000..dde5fb8 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/lilypond/part_III.ly @@ -0,0 +1,38 @@ +{ + { r1 } + \bar "|" + { r2. r8[ a8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a4 fis2.^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis2. ~ fis16[ g8.^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g16[ a8.^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ a2. ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a2 r2 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/lilypond/part_IV.ly new file mode 100644 index 0000000..98319b9 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/60adbbef/lilypond/part_IV.ly @@ -0,0 +1,38 @@ +{ + { a,1^\markup { \pad-markup #0.2 "+16"} ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,2 r2 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/61e92979/61e92979_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/61e92979/61e92979_code.scd new file mode 100644 index 0000000..c194eef --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/61e92979/61e92979_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/61e92979/61e92979_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/61e92979/61e92979_mus_model.json new file mode 100644 index 0000000..413129a --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/61e92979/61e92979_mus_model.json @@ -0,0 +1,67 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.875 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 3.375 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 1, 0, 0, 0 ] ], 1.25 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 3.125 ] + ], + [ + [ [ [ 1, 0, -1, 0, 0, -1 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 1, 0, -1, 0, 0, -1 ], [ 1, 0, 1, 0, 0, -1 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 2.25 ] + ], + [ + [ [ [ 1, -1, 0, 0, -1, 0 ], [ 1, 0, 1, 0, 0, -1 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 2.625 ], + [ [ [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], + [ [ [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ 2, -1, 0, -1, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 10 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -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 ], [ 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, 0, 1, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ] +], +"cur_uid": "61e92979", +"ref_uid": "nil", +"order_seed": 921767, +"dur_seed": 954688, +"motifs_seed": 995213, +"entrances_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "true", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/62300302/62300302_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/62300302/62300302_code.scd new file mode 100644 index 0000000..57e638d --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/62300302/62300302_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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 = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).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.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/62300302/62300302_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/62300302/62300302_mus_model.json new file mode 100644 index 0000000..dfaef7d --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/62300302/62300302_mus_model.json @@ -0,0 +1,77 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 2.25 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 3, -2, 0, 1, 0 ] ], 1.5 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ 0, 2, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ] ], 1.875 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 2, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ] ], 2.625 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 2, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 3, -2, 0, 1, 0 ] ], 1.25 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 3, -2, 0, 1, 0 ] ], 1.5 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -1, 3, -2, -2, 1, 0 ] ], 2.25 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ 0, 3, -2, -1, 0, 0 ], [ -1, 3, -2, -2, 1, 0 ] ], 1.5 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ 0, 3, -2, -1, 0, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 2 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 0, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 1.75 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 1.375 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 2.125 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -2, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 1.125 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 2, -2, -1, 1, 0 ] ], 2.125 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 2, -2, -1, 1, 0 ] ], 1.75 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -2, 3, -2, -1, 2, 0 ] ], 2 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 3, -2, -1, 0, 0 ] ], 1 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 1 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 1.5 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 0, 0 ] ], 1 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 1.375 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ] + ] + ] +], +"last_changes": +[ + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 2, -2, -1, 1, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -2, 3, -2, -1, 2, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 3, -2, -1, 0, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ] +], +"cur_uid": "62300302", +"ref_uid": "74b8f8d9", +"order_seed": 799630, +"dur_seed": 442647, +"motifs_seed": 452591, +"entrances_probs_vals": [ 1, 0, 2.9365079365079, 0.47, 2.8021978021978, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 2.7380952380952, 0.96, 2.4725274725275, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 2.7380952380952, 0.96, 2.4725274725275, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8.0714285714286, 10.091836734694 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/62300302/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_2/62300302/lilypond/part_I.ly new file mode 100644 index 0000000..f4f96ba --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/62300302/lilypond/part_I.ly @@ -0,0 +1,36 @@ +{ + { r1 } + \bar "|" + { r8[ g8^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ g2. ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g2 b,2^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { b,1 ~ } + \bar "|" + { b,4 ~ b,8[ cis8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ cis2 ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis2. ~ cis8.[ d16^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d2 dis2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + \bar "|" + { dis2 e2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e2. r4} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/62300302/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_2/62300302/lilypond/part_II.ly new file mode 100644 index 0000000..158f676 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/62300302/lilypond/part_II.ly @@ -0,0 +1,36 @@ +{ + { r1 } + \bar "|" + { r2. r8[ d'8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'8[ dis'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ dis'2. ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'2 ~ dis'8[ e'8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ e'4 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'4 b2.^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b2 ~ b16[ cis'8.^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ cis'4 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 } + \bar "|" + { d'1^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { d'4 r2. } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/62300302/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_2/62300302/lilypond/part_III.ly new file mode 100644 index 0000000..cebac3f --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/62300302/lilypond/part_III.ly @@ -0,0 +1,36 @@ +{ + { r1 } + \bar "|" + { r1 } + \bar "|" + { r2. r16[ dis8.^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis2. e4^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e4 ~ e8[ e8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ e2 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 } + \bar "|" + { fis1^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ } + \bar "|" + { fis2 ~ fis8[ g8^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ g4 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g2 a2^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/62300302/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_2/62300302/lilypond/part_IV.ly new file mode 100644 index 0000000..19d2217 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/62300302/lilypond/part_IV.ly @@ -0,0 +1,36 @@ +{ + { a,1^\markup { \pad-markup #0.2 "+16"} ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/628706ec_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/628706ec_code.scd new file mode 100644 index 0000000..c194eef --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/628706ec_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/628706ec_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/628706ec_mus_model.json new file mode 100644 index 0000000..7226160 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/628706ec_mus_model.json @@ -0,0 +1,117 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 1.5 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 1.25 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 2, -1, 0, 0, 0 ] ], 0.5 ], + [ [ [ 1, 2, -1, -1, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 2, -1, 0, 0, 0 ] ], 0.875 ], + [ [ [ 1, 2, -1, -1, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 2, -1, 0, 0, 1 ] ], 1.25 ], + [ [ [ -1, 3, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 2, -1, 0, 0, 1 ] ], 0 ] + ], + [ + [ [ [ -1, 3, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.75 ], + [ [ [ -1, 3, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ] ], 1.375 ], + [ [ [ 0, 2, -1, 0, -1, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ] ], 0.5 ], + [ [ [ 0, 2, -1, 0, -1, 0 ], [ 1, 2, -1, 0, -1, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ] ], 1.375 ], + [ [ [ 0, 2, -1, 0, -1, 0 ], [ 0, 2, -1, 0, 1, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ] ], 0.75 ], + [ [ [ 0, 2, -1, 0, -1, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ] ], 0.125 ], + [ [ [ -1, 2, -1, 0, 1, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ] ], 1 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ] ], 1.375 ], + [ [ [ -1, 2, 0, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ] ], 0.5 ] + ], + [ + [ [ [ -1, 2, 0, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.75 ], + [ [ [ -1, 2, 0, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ "Rest" ], [ 2, 1, -1, 0, 0, -1 ] ], 0.125 ], + [ [ [ -1, 1, -1, 1, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ "Rest" ], [ 2, 1, -1, 0, 0, -1 ] ], 1.375 ], + [ [ [ -1, 1, -1, 1, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ "Rest" ], [ 2, 1, -1, -1, 0, 0 ] ], 0.125 ] + ], + [ + [ [ [ -1, 1, -1, 1, 0, 0 ], [ 1, 1, -1, -1, 0, 1 ], [ "Rest" ], [ 2, 1, -1, -1, 0, 0 ] ], 0.75 ], + [ [ [ 0, 1, -1, -1, 0, 1 ], [ 1, 1, -1, -1, 0, 1 ], [ "Rest" ], [ 2, 1, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -1, -1, 0, 1 ], [ 2, 1, -2, -1, 0, 0 ], [ "Rest" ], [ 2, 1, -1, -1, 0, 0 ] ], 0.875 ], + [ [ [ 0, 2, -1, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ "Rest" ], [ 2, 1, -1, -1, 0, 0 ] ], 0.125 ], + [ [ [ 0, 2, -1, -1, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ "Rest" ], [ 2, 1, -1, -1, 0, 0 ] ], 0.75 ], + [ [ [ 1, 1, -1, -1, -1, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ "Rest" ], [ 2, 1, -1, -1, 0, 0 ] ], 1.375 ], + [ [ [ 0, 1, -1, -1, 1, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ "Rest" ], [ 2, 1, -1, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 1, -1, -1, 1, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ "Rest" ], [ 1, 2, 0, -1, 0, 0 ] ], 1.125 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ "Rest" ], [ 1, 2, 0, -1, 0, 0 ] ], 1.375 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ 0, 2, -1, -1, 0, 1 ], [ 1, 2, 0, -1, 0, 0 ] ], 0.25 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 1, 2, 0, -1, 0, 0 ] ], 0.625 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 1, 2, -1, 0, 0, 0 ] ], 0.375 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 1, 2, -1, -1, 0, 1 ] ], 0.125 ], + [ [ [ 1, 2, -1, -1, -1, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 1, 2, -1, -1, 0, 1 ] ], 1.5 ], + [ [ [ 1, 2, -1, -1, -1, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 2, -1, -1, 0, 1 ] ], 0.875 ] + ], + [ + [ [ [ -1, 4, -1, -1, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 2, -1, -1, 0, 1 ] ], 0.625 ], + [ [ [ -1, 4, -1, -1, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 3, -1, -1, 0, 0 ] ], 0.125 ], + [ [ [ -1, 4, -1, -1, 0, 0 ], [ 0, 3, 0, -1, 0, 0 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 3, -1, -1, 0, 0 ] ], 0.125 ] + ], + [ + [ [ [ -1, 4, -1, -1, 0, 0 ], [ 0, 3, 0, -1, 0, 0 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 4, -1, -1, 0, 0 ] ], 0.375 ], + [ [ [ -1, 4, -1, -1, 0, 0 ], [ 1, 3, -1, -1, 0, -1 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 4, -1, -1, 0, 0 ] ], 0.25 ], + [ [ [ 0, 3, -1, -1, -1, 0 ], [ 1, 3, -1, -1, 0, -1 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 4, -1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 3, -1, -1, -1, 0 ], [ 1, 3, -1, -1, 0, -1 ], [ 0, 3, -1, -1, 0, 0 ], [ 2, 3, -1, -1, -1, 0 ] ], 1 ], + [ [ [ 0, 3, -1, -1, -1, 0 ], [ 1, 3, -1, -1, 0, -1 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 3, -1, -1, 1, 0 ] ], 0.875 ], + [ [ [ -1, 3, -1, -1, 1, 0 ], [ 1, 3, -1, -1, 0, -1 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 3, -1, -1, 1, 0 ] ], 0.875 ], + [ [ [ 0, 2, -1, -1, 0, 0 ], [ 1, 3, -1, -1, 0, -1 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 3, -1, -1, 1, 0 ] ], 1.25 ], + [ [ [ 0, 3, -1, -1, 0, -1 ], [ 1, 3, -1, -1, 0, -1 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 3, -1, -1, 1, 0 ] ], 0.375 ], + [ [ [ 0, 3, -1, -1, 0, -1 ], [ 0, 3, 0, -1, 0, 0 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 3, -1, -1, 1, 0 ] ], 1.5 ], + [ [ [ 0, 3, -1, -2, 0, 0 ], [ 0, 3, 0, -1, 0, 0 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 3, -1, -1, 1, 0 ] ], 0.375 ], + [ [ [ 0, 3, -1, -2, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 3, -1, -1, 1, 0 ] ], 0.25 ], + [ [ [ 0, 3, -1, -2, 0, 0 ], [ 0, 3, -1, -1, 1, 0 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 3, -1, -1, 1, 0 ] ], 0.875 ] + ], + [ + [ [ [ "Rest" ], [ 0, 3, -1, -1, 1, 0 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 3, -1, -1, 1, 0 ] ], 0.625 ], + [ [ [ "Rest" ], [ 0, 3, -1, -1, 1, 0 ], [ 0, 3, -1, -1, 0, 0 ], [ 1, 3, -1, -1, 1, -1 ] ], 0.5 ], + [ [ [ "Rest" ], [ 0, 3, -1, -1, 1, 0 ], [ -1, 4, -1, -1, 1, 0 ], [ 1, 3, -1, -1, 1, -1 ] ], 1 ], + [ [ [ "Rest" ], [ 0, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 1, 0 ], [ 1, 3, -1, -1, 1, -1 ] ], 1.125 ], + [ [ [ "Rest" ], [ 0, 3, -1, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 1 ], [ 1, 3, -1, -1, 1, -1 ] ], 1.375 ], + [ [ [ "Rest" ], [ 0, 3, -1, -1, 1, 0 ], [ -1, 3, -1, 0, 1, 0 ], [ 1, 3, -1, -1, 1, -1 ] ], 0 ], + [ [ [ "Rest" ], [ 0, 3, -1, -1, 1, 0 ], [ -1, 3, -1, 0, 1, 0 ], [ 0, 3, 0, -1, 1, 0 ] ], 0.125 ], + [ [ [ "Rest" ], [ 0, 3, -1, -1, 1, 0 ], [ -1, 3, -1, 0, 1, 0 ], [ 1, 2, -1, -1, 1, 0 ] ], 1.375 ], + [ [ [ "Rest" ], [ 0, 3, -1, -1, 1, 0 ], [ -1, 4, -1, -1, 1, 0 ], [ 1, 2, -1, -1, 1, 0 ] ], 0.875 ], + [ [ [ "Rest" ], [ 0, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 1, 0 ], [ 1, 2, -1, -1, 1, 0 ] ], 0.375 ], + [ [ [ "Rest" ], [ 0, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 1, 0 ], [ 0, 3, -1, -1, 2, 0 ] ], 0.625 ], + [ [ [ "Rest" ], [ 0, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 1, 0 ], [ "Rest" ] ], 0.5 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 3, -2, -1, 1, 0 ], [ "Rest" ] ], 0.625 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], + [ [ 0, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, 0 ] ] +], +"cur_uid": "628706ec", +"ref_uid": "77b0d2dc", +"order_seed": 921767, +"dur_seed": 954688, +"motifs_seed": 995213, +"entrances_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "true", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/lilypond/part_I.ly new file mode 100644 index 0000000..5057e30 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/lilypond/part_I.ly @@ -0,0 +1,46 @@ +{ + { r1 } + \bar "|" + { r4 r8[ ais''8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ ais''2 ~ } + \bar "|" + { ais''16[ g''8.^\markup { \pad-markup #0.2 "-42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}] ~ g''4 ~ g''8.[ r16] r4 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r2. r8.[ g''16^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }}] ~ } + \bar "|" + { g''2 ~ g''8.[ f''16^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }}] ~ f''4 ~ } + \bar "|" + { f''1 ~ } + \bar "|" + { f''2. ~ f''16[ e''8.^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}] ~ } + \bar "|" + { e''1 ~ } + \bar "|" + { e''2 ais''8.^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ a''16^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}] ~ a''4 ~ } + \bar "|" + { a''1 ~ } + \bar "|" + { a''4 gis''8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ dis'''8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ dis'''2 ~ } + \bar "|" + { dis'''8.[ d'''16^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ d'''4 ~ d'''8.[ cis'''16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↑" }}] ~ cis'''4 ~ } + \bar "|" + { cis'''1 ~ } + \bar "|" + { cis'''1 ~ } + \bar "|" + { cis'''1 ~ } + \bar "|" + { cis'''8.[ f''16^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }}] ~ f''2. ~ } + \bar "|" + { f''1 ~ } + \bar "|" + { f''8.[ f''16^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}] fis''2.^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { fis''2 ~ fis''16[ g''8.^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }}] ~ g''8[ r8]} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/lilypond/part_II.ly new file mode 100644 index 0000000..488d911 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/lilypond/part_II.ly @@ -0,0 +1,46 @@ +{ + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r16[ ais'8.^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ ais'2. ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'2 ~ ais'16[ r8.] r4 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r16[ a'8^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }} a'16^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] ~ a'2. ~ } + \bar "|" + { a'2 gis'2^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'4 ~ gis'8.[ gis'16^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ gis'4 ~ gis'8.[ a'16^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] ~ } + \bar "|" + { a'2 a'2^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }} ~ } + \bar "|" + { a'8.[ b'16^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}] ~ b'2 ~ b'8.[ gis'16^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { gis'4 ~ gis'8[ a'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] ~ a'2} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/lilypond/part_III.ly new file mode 100644 index 0000000..e86a63f --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/lilypond/part_III.ly @@ -0,0 +1,46 @@ +{ + { ais'1^\markup { \pad-markup #0.2 "+18"} ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 } + \bar "|" + { f''2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ f''8.[ e''16^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↑" }}] ~ e''4 ~ } + \bar "|" + { e''16[ dis''8.^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] ~ dis''2. ~ } + \bar "|" + { dis''1 ~ } + \bar "|" + { dis''2. d''4^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} ~ } + \bar "|" + { d''8[ d''8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}] ~ d''4 ~ d''8[ c''8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ c''4 ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''4 ~ c''16[ b'8.^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }}] ~ b'16[ b'8.^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }}] ~ b'4 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'4 ~ b'8[ b'8^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }}] ~ b'2 ~ } + \bar "|" + { b'4 ~ b'16[ c''8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} cis''16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ cis''2 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/lilypond/part_IV.ly new file mode 100644 index 0000000..ce23b81 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/628706ec/lilypond/part_IV.ly @@ -0,0 +1,46 @@ +{ + { r2. ais4^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { ais2 ~ ais8[ c''8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }}] ~ c''4 ~ } + \bar "|" + { c''2 ~ c''8.[ f'16^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ f'4 ~ } + \bar "|" + { f'2. f'4^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'8[ e'8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↑" }}] ~ e'4 ~ e'8[ dis'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ dis'4 ~ } + \bar "|" + { dis'4 ~ dis'16[ d'8.^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }}] ~ d'2 } + \bar "|" + { cis'1^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + \bar "|" + { cis'8[ d'8^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ d'4 ~ d'16[ c'8.^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}] ~ c'4 } + \bar "|" + { c'2^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }} ~ c'8.[ b16^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↑" }}] ~ b4 ~ } + \bar "|" + { b4 ~ b8[ ais8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}] ~ ais2 ~ } + \bar "|" + { ais2. g'4^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } + \bar "|" + { g'2. ~ g'8.[ dis'16^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { dis'2 ~ dis'8.[ d'16^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }}] ~ d'4 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'8[ cis'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ cis'4 ~ cis'16[ c'8.^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] ~ c'4 ~ } + \bar "|" + { c'8.[ b16^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ b2. ~ } + \bar "|" + { b8[ ais8^\markup { \pad-markup #0.2 "-18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }}] ~ ais2 ~ ais8[ r8] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/63bf7942/63bf7942_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/63bf7942/63bf7942_code.scd new file mode 100644 index 0000000..c194eef --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/63bf7942/63bf7942_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/63bf7942/63bf7942_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/63bf7942/63bf7942_mus_model.json new file mode 100644 index 0000000..792f760 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/63bf7942/63bf7942_mus_model.json @@ -0,0 +1,67 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 2.125 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 4.75 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 1, 0, 0, 0 ] ], 2.875 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 3.375 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 1.375 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 4.625 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ "Rest" ], [ 0, 1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 9.125 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ] +], +"cur_uid": "63bf7942", +"ref_uid": "nil", +"order_seed": 921767, +"dur_seed": 345812, +"motifs_seed": 995213, +"entrances_probs_vals": [ 1, 0, 0, 0.88, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 0.88, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 0.88, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/6a7a8dd9/6a7a8dd9_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/6a7a8dd9/6a7a8dd9_code.scd new file mode 100644 index 0000000..c194eef --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/6a7a8dd9/6a7a8dd9_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/6a7a8dd9/6a7a8dd9_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/6a7a8dd9/6a7a8dd9_mus_model.json new file mode 100644 index 0000000..bc3aae4 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/6a7a8dd9/6a7a8dd9_mus_model.json @@ -0,0 +1,126 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 0, 0, 0 ] ], 3.875 ], + [ [ [ "Rest" ], [ "Rest" ], [ 1, 1, -1, -1, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ "Rest" ], [ 1, 1, -1, -1, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ 1, 1, -1, 0, -1, 0 ], [ 1, 1, -1, -1, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 4.25 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ 1, 1, -1, 0, -1, 0 ], [ 1, 1, -1, 0, 0, -1 ], [ 0, 1, -1, 0, 0, 0 ] ], 4.375 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ 1, 1, -1, 0, -1, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 4 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ 1, 1, -1, 0, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ 0, 2, -1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ 0, 2, -1, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 3.75 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ 0, 2, -1, 0, 0, 0 ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 2.25 ] + ], + [ + [ [ [ -1, 1, -1, 0, 0, 1 ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 1, -1, 1, 0, -1 ] ], 4.375 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ] ], 2.5 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 0, -1, 1, 0, 0 ] ], 1.375 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 1, -1, 1, 1, 0 ] ], 3.75 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 1, -1, 1, -1, 0 ] ], 1.625 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ] ], 1.125 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 1, -2, 1, 0, 0 ] ], 5 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 1, -1, 1, 0, 1 ] ], 1.625 ] + ], + [ + [ [ [ -2, 1, -1, 2, 0, 0 ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 1, -1, 1, 0, 1 ] ], 0 ], + [ [ [ -2, 1, -1, 2, 0, 0 ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 1, -1, 2, 0, 0 ] ], 5 ], + [ [ [ -2, 1, -1, 2, 0, 0 ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 1, -1, 1, 0, -1 ] ], 2.125 ], + [ [ [ -2, 1, -1, 2, 0, 0 ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 0, -1, 1, 0, 0 ] ], 1.625 ] + ], + [ + [ [ [ -2, 1, -1, 2, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 0, -1, 1, 0, 0 ] ], 4.75 ], + [ [ [ -2, 1, -1, 2, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 3, -1, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 3, -1, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 1, 2, -1, 0, 0, -1 ], [ -1, 3, -1, 0, 0, 0 ] ], 4 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 1, 2, -1, 0, 0, -1 ], [ 0, 2, -2, 0, 0, 0 ] ], 4 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 1, 2, -1, 0, 0, -1 ], [ -1, 2, -1, 0, 0, 1 ] ], 0 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ -1, 2, -1, 0, 0, 1 ] ], 2.75 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ] ], 4.625 ] + ], + [ + [ [ [ -1, 2, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 1, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -1, 1, 0, -1 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 4 ], + [ [ [ -2, 2, 0, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 4.75 ], + [ [ [ -1, 1, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 3.25 ], + [ [ [ -2, 2, -1, 1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 3.75 ], + [ [ [ -1, 2, -1, 1, -1, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 4.125 ], + [ [ [ -2, 3, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 2.625 ], + [ [ [ -3, 2, -1, 1, 0, 1 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 4.5 ], + [ [ [ -2, 2, -2, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 2.625 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 3.375 ] + ], + [ + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -1, 3, -1, 1, -1, 0 ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 0 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -1, 3, -1, 1, -1, 0 ], [ -1, 3, -1, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ] ], 0 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -1, 3, -1, 1, -1, 0 ], [ -1, 3, -1, 1, 0, 0 ], [ -2, 3, 0, 1, 0, 0 ] ], 4.5 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -1, 3, -1, 1, -1, 0 ], [ -1, 3, -1, 1, 0, 0 ], [ -1, 3, -1, 1, 0, -1 ] ], 0 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -1, 3, -1, 1, -1, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 3, -1, 1, 0, -1 ] ], 0 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -2, 4, -1, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 3, -1, 1, 0, -1 ] ], 4.5 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -2, 4, -1, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -2, 3, -1, 2, 0, 0 ] ], 4.875 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -2, 4, -1, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -3, 3, -1, 2, 0, 0 ] ], 4.25 ] + ], + [ + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ], [ -3, 3, -1, 2, 0, 0 ] ], 0 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -3, 3, -1, 2, 0, 0 ] ], 0 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -3, 3, -1, 1, 0, 1 ] ], 2.125 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -3, 4, -1, 1, 0, 0 ] ], 2 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 3, -2, 1, 0, 0 ] ], 1.125 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 3, -1, 1, 0, 0 ] ], 0.875 ] + ], + [ + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ], [ -2, 3, -1, 1, 0, 0 ] ], 1.875 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ], 0 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ], 0 ], + [ [ [ -2, 2, -2, 1, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ], 4.375 ], + [ [ [ -3, 2, -1, 1, 0, 1 ], [ 0, 2, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ], 4.375 ], + [ [ [ -3, 2, -1, 1, 0, 1 ], [ 0, 2, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ 0, 2, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 9.625 ] + ] + ] +], +"last_changes": +[ + [ [ -3, 3, -1, 1, 0, 0 ], [ -2, 4, -1, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -2, 3, -1, 1, 0, 0 ] ], + [ [ -3, 3, -1, 1, 0, 0 ], [ -2, 4, -1, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ], + [ [ -3, 3, -1, 1, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ], + [ [ -2, 2, -2, 1, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ], + [ [ -3, 2, -1, 1, 0, 1 ], [ 0, 2, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ] +], +"cur_uid": "6a7a8dd9", +"ref_uid": "63bf7942", +"order_seed": 327691, +"dur_seed": 667550, +"motifs_seed": 549585, +"entrances_probs_vals": [ 1, 0, 0, 0.88, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 0.88, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 0.88, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 3 ], [ 2, 0, 1, 2, 2, 2, 1, 2, 2 ], [ ] ], + [ [ 2 ], [ 3, 3, 3, 3, 3, 3, 3, 3 ], [ 1, 0 ] ], + [ [ 2 ], [ 0, 3, 3, 3 ], [ 1 ] ], + [ [ 1 ], [ 3, 0, 2, 3, 3, 2, 3 ], [ ] ], + [ [ 3 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 1, 2 ] ], + [ [ 0 ], [ 1, 2, 3, 3, 2, 1, 3, 3 ], [ ] ], + [ [ 0 ], [ 3, 3, 3, 3 ], [ 1, 2 ] ], + [ [ 2 ], [ 3, 1, 0, 0 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/71add9fc/71add9fc_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/71add9fc/71add9fc_code.scd new file mode 100644 index 0000000..c194eef --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/71add9fc/71add9fc_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/71add9fc/71add9fc_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/71add9fc/71add9fc_mus_model.json new file mode 100644 index 0000000..ab65a8d --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/71add9fc/71add9fc_mus_model.json @@ -0,0 +1,210 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.875 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 4.875 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 1, 0, 0, 0 ] ], 4.75 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 4.125 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 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, 1 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 4.875 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, -1, 0, 0, 0 ] ], 4.125 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ -1, 1, 0, 0, 0, 1 ] ], 0 ], + [ [ [ -1, 1, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ -1, 1, 0, 0, 0, 1 ] ], 0 ], + [ [ [ -1, 1, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 1 ] ], 4.875 ] + ], + [ + [ [ [ -1, 1, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ] ], 0 ], + [ [ [ 0, 1, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ] ], 0 ], + [ [ [ 0, 1, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 1 ], [ -1, 1, 0, 1, 0, 0 ] ], 4 ] + ], + [ + [ [ [ 0, 1, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 1, 0 ], [ -1, 1, 0, 0, 0, 1 ], [ -1, 1, 0, 1, 0, 0 ] ], 3.75 ], + [ [ [ 0, 1, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 1, 0 ], [ -1, 1, 0, 0, 0, 1 ], [ 0, 1, 0, 0, 1, -1 ] ], 0 ], + [ [ [ 0, 1, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 1, 0 ], [ -1, 1, 1, 0, 1, 0 ], [ 0, 1, 0, 0, 1, -1 ] ], 0 ], + [ [ [ 0, 1, 0, 0, 0, -1 ], [ -1, 1, 0, 1, 1, 0 ], [ -1, 1, 1, 0, 1, 0 ], [ 0, 1, 0, 0, 1, -1 ] ], 4.25 ] + ], + [ + [ [ [ 0, 1, 0, 0, 0, -1 ], [ -1, 1, 0, 1, 1, 0 ], [ -1, 1, 1, 0, 1, 0 ], [ -2, 2, 0, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 1, 0 ], [ -1, 1, 1, 0, 1, 0 ], [ -2, 2, 0, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 1, 2, 0 ], [ -2, 2, 0, 1, 1, 0 ] ], 4.625 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 1, 2, 0 ], [ -1, 1, 0, 1, 0, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 0, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 0, 0 ] ], 4.625 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ], [ -2, 1, 0, 1, 2, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ -1, 1, 0, 1, 1, -1 ], [ -2, 1, 0, 1, 2, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 1, 1, 1 ], [ -1, 1, 0, 1, 1, -1 ], [ -2, 1, 0, 1, 2, 0 ] ], 4.875 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 1, 1, 1 ], [ -1, 1, 0, 0, 1, 0 ], [ -2, 1, 0, 1, 2, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 1, 1, 1 ], [ -1, 1, 0, 0, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, -1, 1, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ] ], 4.125 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, -1, 1, 1, 0 ], [ 0, 1, 0, 1, 0, 0 ], [ -1, 0, 0, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, -1, 1, 1, 0 ], [ 0, 1, 0, 1, 0, 0 ], [ -2, 1, 1, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 1, 0 ], [ 0, 1, 0, 1, 0, 0 ], [ -2, 1, 1, 1, 1, 0 ] ], 4 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ 0, 1, 0, 1, 0, 0 ], [ -2, 1, 1, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ 0, 1, 0, 1, 0, 0 ], [ -1, 1, 0, 1, 1, -1 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 1, 0, 1, 2, 0 ], [ -1, 1, 0, 1, 1, -1 ] ], 4.25 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ 0, 0, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 1, -1 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ 0, 0, 0, 1, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 1, 0 ], [ 0, 0, 0, 1, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ] ], 4 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 1, 0 ], [ 0, 1, 0, 1, 1, -1 ], [ -1, 1, 0, 0, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 1, 0 ], [ 0, 1, 0, 1, 1, -1 ], [ -2, 1, 0, 2, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, -1, 1, 1, 0 ], [ 0, 1, 0, 1, 1, -1 ], [ -2, 1, 0, 2, 1, 0 ] ], 4.375 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 1, 1, 1 ], [ 0, 1, 0, 1, 1, -1 ], [ -2, 1, 0, 2, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 1, 1, 1 ], [ -1, 1, 1, 1, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 1, 1, 1 ], [ -1, 1, 1, 1, 1, 0 ], [ -1, 1, 0, 1, 1, -1 ] ], 4 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 1, 1, 1 ], [ 0, 0, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 1, -1 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 1, 1, 1 ], [ 0, 0, 0, 1, 1, 0 ], [ -2, 1, 1, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 1, 0 ], [ 0, 0, 0, 1, 1, 0 ], [ -2, 1, 1, 1, 1, 0 ] ], 4.625 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 1, 0 ], [ 0, 0, 0, 1, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, -1, 1, 1, 0 ], [ 0, 0, 0, 1, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, -1, 1, 1, 0 ], [ -1, 1, 0, 1, 2, 0 ], [ -1, 0, 0, 1, 1, 0 ] ], 4.625 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, -1, 1, 1, 0 ], [ 0, 1, 0, 1, 0, 0 ], [ -1, 0, 0, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 1, 1, 1 ], [ 0, 1, 0, 1, 0, 0 ], [ -1, 0, 0, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 1, 1, 1 ], [ 0, 1, 0, 1, 0, 0 ], [ -2, 1, 0, 1, 2, 0 ] ], 4.5 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ 0, 1, 0, 1, 0, 0 ], [ -2, 1, 0, 1, 2, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ 0, 0, 0, 1, 1, 0 ], [ -2, 1, 0, 1, 2, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ 0, 0, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 1, 0 ] ], 4.375 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ 0, 0, 0, 1, 1, 0 ], [ -1, 1, -1, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 1, -1 ], [ 0, 0, 0, 1, 1, 0 ], [ -1, 1, -1, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 1, -1 ], [ -1, 1, 1, 1, 1, 0 ], [ -1, 1, -1, 1, 1, 0 ] ], 4.125 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 1, -1 ], [ -1, 1, 1, 1, 1, 0 ], [ -2, 1, 0, 1, 1, 1 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ -1, 1, 1, 1, 1, 0 ], [ -2, 1, 0, 1, 1, 1 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 0, 1, 0, 1, 1, -1 ], [ -2, 1, 0, 1, 1, 1 ] ], 4.5 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 0, 1, 0, 1, 1, -1 ], [ -2, 2, 0, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ -1, 1, 0, 1, 2, 0 ], [ -2, 2, 0, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 2, 0 ], [ -2, 2, 0, 1, 1, 0 ] ], 3.875 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 1, 0, 1, 2, 0 ], [ -2, 2, 0, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 1, 0, 1, 2, 0 ], [ -1, 1, -1, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ 0, 0, 0, 1, 1, 0 ], [ -1, 1, -1, 1, 1, 0 ] ], 3.75 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ 0, 1, 0, 1, 1, -1 ], [ -1, 1, -1, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ 0, 1, 0, 1, 1, -1 ], [ -2, 1, 0, 1, 1, 1 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 1, 0 ], [ 0, 1, 0, 1, 1, -1 ], [ -2, 1, 0, 1, 1, 1 ] ], 4.5 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 1, 0 ], [ -1, 1, 1, 1, 1, 0 ], [ -2, 1, 0, 1, 1, 1 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 1, 1, 1, 0 ], [ -1, 1, 1, 1, 1, 0 ], [ -2, 1, 0, 1, 1, 1 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 1, 1, 1, 0 ], [ -1, 1, 1, 1, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ] ], 4.75 ] + ], + [ + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ], [ -1, 1, 1, 1, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ], [ -1, 1, 1, 1, 1, 0 ], [ 0, 0, 0, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ], [ 0, 1, 0, 1, 1, -1 ], [ 0, 0, 0, 1, 1, 0 ] ], 4.75 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ], [ 0, 1, 0, 1, 1, -1 ], [ "Rest" ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ "Rest" ], [ 0, 1, 0, 1, 1, -1 ], [ "Rest" ] ], 0 ], + [ [ [ -2, 1, 0, 1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 5.25 ] + ] + ] +], +"last_changes": +[ + [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 1, 1, 1, 0 ], [ -1, 1, 1, 1, 1, 0 ], [ -2, 1, 0, 1, 1, 1 ] ], + [ [ -2, 1, 0, 1, 1, 0 ], [ -2, 1, 1, 1, 1, 0 ], [ -1, 1, 1, 1, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ] ], + [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ], [ -1, 1, 1, 1, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ] ], + [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ], [ -1, 1, 1, 1, 1, 0 ], [ 0, 0, 0, 1, 1, 0 ] ], + [ [ -2, 1, 0, 1, 1, 0 ], [ -1, 0, 0, 1, 1, 0 ], [ 0, 1, 0, 1, 1, -1 ], [ 0, 0, 0, 1, 1, 0 ] ] +], +"cur_uid": "71add9fc", +"ref_uid": "nil", +"order_seed": 921767, +"dur_seed": 954688, +"motifs_seed": 995213, +"entrances_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 1 ], [ 3, 2, 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 1, 2, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 1, 2, 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/72dc057f_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/72dc057f_code.scd new file mode 100644 index 0000000..57e638d --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/72dc057f_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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 = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).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.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/72dc057f_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/72dc057f_mus_model.json new file mode 100644 index 0000000..5541d17 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/72dc057f_mus_model.json @@ -0,0 +1,59 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 5 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 6.875 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 3.875 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 6.125 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 6.125 ] + ] + ] +], +"last_changes": +[ + [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ] +], +"cur_uid": "72dc057f", +"ref_uid": 62300302, +"order_seed": 209649, +"dur_seed": 795391, +"motifs_seed": 821280, +"entrances_probs_vals": [ 1, 0, 2.9365079365079, 0.47, 2.8021978021978, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 2.7380952380952, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 2.7380952380952, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.35390946502058, 0, 0.5, 0.5, 0.62139917695473, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8.0714285714286, 10.091836734694 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/lilypond/part_I.ly new file mode 100644 index 0000000..91049e5 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/lilypond/part_I.ly @@ -0,0 +1,30 @@ +{ + { r1 } + \bar "|" + { r1 } + \bar "|" + { r2 e2^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e2. ~ e8.[ e16^\markup { \pad-markup #0.2 "-36"}] ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e2. ~ e8[ d8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d2. ~ d8.[ r16] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/lilypond/part_II.ly new file mode 100644 index 0000000..80a76d1 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/lilypond/part_II.ly @@ -0,0 +1,30 @@ +{ + { r1 } + \bar "|" + { r1 } + \bar "|" + { r2 dis'2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'2. ~ dis'8.[ cis'16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'2. ~ cis'8[ d'8^\markup { \pad-markup #0.2 "+14"}] ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'2. ~ d'8.[ r16] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/lilypond/part_III.ly new file mode 100644 index 0000000..0b76537 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/lilypond/part_III.ly @@ -0,0 +1,30 @@ +{ + { r1 } + \bar "|" + { r1 } + \bar "|" + { r2 cis2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis2. ~ cis8.[ cis16^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis2. ~ cis8[ f8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f2. ~ f8.[ r16] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/lilypond/part_IV.ly new file mode 100644 index 0000000..e37440b --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/72dc057f/lilypond/part_IV.ly @@ -0,0 +1,30 @@ +{ + { a,1^\markup { \pad-markup #0.2 "+16"} ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,2. ~ a,8.[ r16] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/74307bb4_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/74307bb4_code.scd new file mode 100644 index 0000000..c194eef --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/74307bb4_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/74307bb4_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/74307bb4_mus_model.json new file mode 100644 index 0000000..6d6bd44 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/74307bb4_mus_model.json @@ -0,0 +1,120 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 0, 0, 0 ] ], 3.875 ], + [ [ [ "Rest" ], [ "Rest" ], [ 1, 1, -1, -1, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ "Rest" ], [ 1, 1, -1, -1, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ 1, 1, -1, 0, -1, 0 ], [ 1, 1, -1, -1, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 4.25 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ 1, 1, -1, 0, -1, 0 ], [ 1, 1, -1, 0, 0, -1 ], [ 0, 1, -1, 0, 0, 0 ] ], 4.375 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ 1, 1, -1, 0, -1, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 4 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ 1, 1, -1, 0, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ 0, 2, -1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ 0, 2, -1, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 3.75 ], + [ [ [ -1, 1, -1, 0, 0, 1 ], [ 0, 2, -1, 0, 0, 0 ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 2.25 ] + ], + [ + [ [ [ -1, 1, -1, 0, 0, 1 ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 1, -1, 1, 0, -1 ] ], 4.375 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ] ], 2.5 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 0, -1, 1, 0, 0 ] ], 1.375 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 1, -1, 1, 1, 0 ] ], 3.75 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 1, -1, 1, -1, 0 ] ], 1.625 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ] ], 1.125 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 1, -2, 1, 0, 0 ] ], 5 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 1, -1, 1, 0, 1 ] ], 1.625 ] + ], + [ + [ [ [ -2, 1, -1, 2, 0, 0 ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 1, -1, 1, 0, 1 ] ], 0 ], + [ [ [ -2, 1, -1, 2, 0, 0 ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 1, -1, 2, 0, 0 ] ], 5 ], + [ [ [ -2, 1, -1, 2, 0, 0 ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 1, -1, 1, 0, -1 ] ], 2.125 ], + [ [ [ -2, 1, -1, 2, 0, 0 ], [ "Rest" ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 0, -1, 1, 0, 0 ] ], 1.625 ] + ], + [ + [ [ [ -2, 1, -1, 2, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 0, -1, 1, 0, 0 ] ], 4.75 ], + [ [ [ -2, 1, -1, 2, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 3, -1, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 0, 1, -1, 1, 0, 0 ], [ -1, 3, -1, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 1, 2, -1, 0, 0, -1 ], [ -1, 3, -1, 0, 0, 0 ] ], 4 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 1, 2, -1, 0, 0, -1 ], [ 0, 2, -2, 0, 0, 0 ] ], 4 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 1, 2, -1, 0, 0, -1 ], [ -1, 2, -1, 0, 0, 1 ] ], 0 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ -1, 2, -1, 0, 0, 1 ] ], 2.75 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ] ], 4.625 ] + ], + [ + [ [ [ -1, 2, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 1, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -1, 1, 0, -1 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 4 ], + [ [ [ -2, 2, 0, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 4.75 ], + [ [ [ -1, 1, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 3.25 ], + [ [ [ -2, 2, -1, 1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 3.75 ], + [ [ [ -1, 2, -1, 1, -1, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 4.125 ], + [ [ [ -2, 3, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 2.625 ], + [ [ [ -3, 2, -1, 1, 0, 1 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 4.5 ], + [ [ [ -2, 2, -2, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 2.625 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 3.375 ] + ], + [ + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -1, 3, -1, 1, -1, 0 ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ] ], 0 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -1, 3, -1, 1, -1, 0 ], [ -1, 3, -1, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ] ], 0 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -1, 3, -1, 1, -1, 0 ], [ -1, 3, -1, 1, 0, 0 ], [ -2, 3, 0, 1, 0, 0 ] ], 4.5 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -1, 3, -1, 1, -1, 0 ], [ -1, 3, -1, 1, 0, 0 ], [ -1, 3, -1, 1, 0, -1 ] ], 0 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -1, 3, -1, 1, -1, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 3, -1, 1, 0, -1 ] ], 0 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -2, 4, -1, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 3, -1, 1, 0, -1 ] ], 4.5 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -2, 4, -1, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -2, 3, -1, 2, 0, 0 ] ], 4.875 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ -2, 4, -1, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -3, 3, -1, 2, 0, 0 ] ], 4.25 ] + ], + [ + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ], [ -3, 3, -1, 2, 0, 0 ] ], 0 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -3, 3, -1, 2, 0, 0 ] ], 0 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -3, 3, -1, 1, 0, 1 ] ], 2.125 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -3, 4, -1, 1, 0, 0 ] ], 2 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 3, -2, 1, 0, 0 ] ], 1.125 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 3, -1, 1, 0, 0 ] ], 0.875 ] + ], + [ + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ], [ -2, 3, -1, 1, 0, 0 ] ], 1.875 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ "Rest" ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ], 0 ], + [ [ [ -3, 3, -1, 1, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ], 0 ], + [ [ [ -2, 2, -2, 1, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ], 4.375 ], + [ [ [ -3, 2, -1, 1, 0, 1 ], [ 0, 2, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ], 4.375 ], + [ [ [ -3, 2, -1, 1, 0, 1 ], [ 0, 2, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ 0, 2, -1, 0, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ] +], +"cur_uid": "74307bb4", +"ref_uid": "77b0d2dc", +"order_seed": 921767, +"dur_seed": 954688, +"motifs_seed": 995213, +"entrances_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "true", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/lilypond/part_I.ly new file mode 100644 index 0000000..8b64a06 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/lilypond/part_I.ly @@ -0,0 +1,142 @@ +{ + { dis'1^\markup { \pad-markup #0.2 "+16"} ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'2. e'4^\markup { \pad-markup #0.2 "+44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2. ~ e'8.[ f'16^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }}] ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'8.[ fis'16^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] ~ fis'2 ~ fis'8[ fis'8^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↑" }}] ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'2. g'4^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } + \bar "|" + { g'2 ~ g'16[ gis'8.^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] ~ gis'4 ~ } + \bar "|" + { gis'8[ a'8^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] ~ a'2. ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'2 ~ a'8[ a'8^\markup { \pad-markup #0.2 "+25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }}] ~ a'4 ~ } + \bar "|" + { a'4 ~ a'8.[ b'16^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ b'2 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'2. ~ b'8.[ e'16^\markup { \pad-markup #0.2 "+44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }}] ~ } + \bar "|" + { e'1 } + \bar "|" + { fis'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'8.[ f'16^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ f'2. ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'8.[ fis'16^\markup { \pad-markup #0.2 "+31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ fis'2. ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'8.[ g'16^\markup { \pad-markup #0.2 "-42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}] ~ g'2. ~ } + \bar "|" + { g'2 ~ g'16[ gis'8.^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ gis'4 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'4 ~ gis'8[ g'8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ g'2 ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'2 ~ g'8[ fis'8^\markup { \pad-markup #0.2 "+48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ fis'4 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'2. ~ fis'8[ cis''8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''4 ~ cis''16[ cis'8.^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ cis'2 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'4 ~ cis'8.[ b16^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}] ~ b2 ~ } + \bar "|" + { b2 ais2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { ais2 b2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { b16[ dis'8.^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ dis'2. ~ } + \bar "|" + { dis'4 ~ dis'8.[ e'16^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] ~ e'2 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/lilypond/part_II.ly new file mode 100644 index 0000000..222dcb4 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/lilypond/part_II.ly @@ -0,0 +1,142 @@ +{ + { r1 } + \bar "|" + { r2. r8.[ f'16^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}] ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'16[ g'8.^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }}] ~ g'2. ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'4 gis'2.^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'4 g'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} dis''4^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { dis''1 ~ } + \bar "|" + { dis''2 ~ dis''8[ cis''8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}] ~ cis''4 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''8.[ d''16^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ d''2. ~ } + \bar "|" + { d''1 ~ } + \bar "|" + { d''1 ~ } + \bar "|" + { d''1 ~ } + \bar "|" + { d''8.[ dis''16^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ dis''2. ~ } + \bar "|" + { dis''1 ~ } + \bar "|" + { dis''1 ~ } + \bar "|" + { dis''2. ~ dis''8[ r8] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r4 r8[ dis''8^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ dis''2 ~ } + \bar "|" + { dis''1 ~ } + \bar "|" + { dis''2 ~ dis''8[ gis'8^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ gis'4 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'4 ~ gis'8.[ r16] r2 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r2 gis'2^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/lilypond/part_III.ly new file mode 100644 index 0000000..0991a78 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/lilypond/part_III.ly @@ -0,0 +1,142 @@ +{ + { r1 } + \bar "|" + { r2. r8.[ ais'16^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }}] ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'4 ais'2.^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'2. r4 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r2. r16[ ais'8.^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'2. ~ ais'8[ r8] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r4 r8[ a'8^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] ~ a'2 ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'2 ~ a'8[ ais'8^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ ais'4 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'4 ~ ais'8.[ r16] r2 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r4 r8.[ ais'16^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }}] ~ ais'2 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/lilypond/part_IV.ly new file mode 100644 index 0000000..0d3677b --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/74307bb4/lilypond/part_IV.ly @@ -0,0 +1,142 @@ +{ + { r1 } + \bar "|" + { r2. r8.[ c'16^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }}] ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'2. r4 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r4 r8.[ b16^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }}] ~ b2 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b8.[ ais16^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ ais2. ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais2. ~ ais8[ b8^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }}] ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b2. ~ b8[ c'8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }}] ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'4 cis'2.^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } + \bar "|" + { cis'2. ~ cis'8[ cis'8^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↑" }}] ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'2. d'4^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'2. ~ d'16[ dis'8.^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'8[ e8^\markup { \pad-markup #0.2 "+27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }}] ~ e2. ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e4 ~ e8[ e8^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}] ~ e2 ~ } + \bar "|" + { e2 ~ e8.[ dis16^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}] ~ dis4 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis4 ~ dis8.[ e16^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ e2 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e2 ~ e8[ e8^\markup { \pad-markup #0.2 "+27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }}] ~ e4 ~ } + \bar "|" + { e1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/74b8f8d9_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/74b8f8d9_code.scd new file mode 100644 index 0000000..57e638d --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/74b8f8d9_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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 = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).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.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/74b8f8d9_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/74b8f8d9_mus_model.json new file mode 100644 index 0000000..c472d47 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/74b8f8d9_mus_model.json @@ -0,0 +1,77 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.75 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 4.75 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 2, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ] ], 7.125 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -2, 3, -2, -1, 2, 0 ], [ -1, 3, -3, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -2, 3, -2, -1, 2, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -2, 3, -2, -1, 2, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], 4.5 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 6.875 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ] ], 5.25 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -3, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -3, -1, 1, 0 ] ], 6.125 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ -1, 2, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 10.125 ] + ] + ] +], +"last_changes": +[ + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -3, -1, 1, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -3, -1, 1, 0 ] ] +], +"cur_uid": "74b8f8d9", +"ref_uid": "4c059f33", +"order_seed": 824152, +"dur_seed": 266394, +"motifs_seed": 206072, +"entrances_probs_vals": [ 1, 0, 5.0793650793651, 0.47, 2.8021978021978, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 2.7380952380952, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 2.7380952380952, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8.0714285714286, 10.091836734694 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/lilypond/part_I.ly new file mode 100644 index 0000000..2d48723 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/lilypond/part_I.ly @@ -0,0 +1,50 @@ +{ + { r1 } + \bar "|" + { r2. r8[ e8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e4 f2.^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f2. ~ f16[ cis'8.^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'16[ cis'8.^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ cis'2. ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'2 d'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'8[ f8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ f2. ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f8.[ r16] r2. } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/lilypond/part_II.ly new file mode 100644 index 0000000..1c284cd --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/lilypond/part_II.ly @@ -0,0 +1,50 @@ +{ + { r1 } + \bar "|" + { r2. r8[ cis8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis4 d2.^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d2. ~ d16[ dis8.^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis16[ e8.^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] ~ e2. ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e2 e2^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e8[ fis8^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}] ~ fis2. ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis8.[ r16] r2. } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/lilypond/part_III.ly new file mode 100644 index 0000000..ecf1ce2 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/lilypond/part_III.ly @@ -0,0 +1,50 @@ +{ + { r1 } + \bar "|" + { r2. r8[ a8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a4 fis2.^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis2. ~ fis16[ g8.^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g16[ a8.^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ a2. ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a2 cis2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis8[ d8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ d2. ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d8.[ r16] r2. } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/lilypond/part_IV.ly new file mode 100644 index 0000000..eca3efa --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/74b8f8d9/lilypond/part_IV.ly @@ -0,0 +1,50 @@ +{ + { a,1^\markup { \pad-markup #0.2 "+16"} ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,8.[ r16] r2. } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/76e45e56_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/76e45e56_code.scd new file mode 100644 index 0000000..57e638d --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/76e45e56_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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 = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).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.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/76e45e56_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/76e45e56_mus_model.json new file mode 100644 index 0000000..e1d66b2 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/76e45e56_mus_model.json @@ -0,0 +1,71 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 7 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 5.5 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 4 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -2, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 5.625 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 6.5 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ "Rest" ], [ -2, 3, -2, 0, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 6.375 ] + ] + ] +], +"last_changes": +[ + [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -2, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ] +], +"cur_uid": "76e45e56", +"ref_uid": 62300302, +"order_seed": 209649, +"dur_seed": 306774, +"motifs_seed": 821280, +"entrances_probs_vals": [ 1, 0, 2.9365079365079, 0.47, 2.8021978021978, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 2.7380952380952, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 2.7380952380952, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.35390946502058, 0, 0.5, 0.5, 0.62139917695473, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8.0714285714286, 10.091836734694 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/lilypond/part_I.ly new file mode 100644 index 0000000..7efbb7f --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/lilypond/part_I.ly @@ -0,0 +1,38 @@ +{ + { r2 e2^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 } + \bar "|" + { e1^\markup { \pad-markup #0.2 "-36"} ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e2. d4^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d2. cis4^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis2 ~ cis16[ cis8.^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ cis4 ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis2. ~ cis16[ r8.] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/lilypond/part_II.ly new file mode 100644 index 0000000..36f4169 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/lilypond/part_II.ly @@ -0,0 +1,38 @@ +{ + { r2 dis'2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 } + \bar "|" + { cis'1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'2. d'4^\markup { \pad-markup #0.2 "+14"} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'2. b4^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b2 ~ b16[ a8.^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ a4 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a2. ~ a16[ r8.] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/lilypond/part_III.ly new file mode 100644 index 0000000..9a96093 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/lilypond/part_III.ly @@ -0,0 +1,38 @@ +{ + { r2 cis2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis1 } + \bar "|" + { cis1^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }} ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis2. f4^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f2. fis4^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis2 ~ fis16[ g8.^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ g4 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g2. ~ g16[ r8.] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/lilypond/part_IV.ly new file mode 100644 index 0000000..c9189fc --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/76e45e56/lilypond/part_IV.ly @@ -0,0 +1,38 @@ +{ + { a,1^\markup { \pad-markup #0.2 "+16"} ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,2. ~ a,16[ r8.] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/77b0d2dc/77b0d2dc_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/77b0d2dc/77b0d2dc_code.scd new file mode 100644 index 0000000..c194eef --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/77b0d2dc/77b0d2dc_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/77b0d2dc/77b0d2dc_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/77b0d2dc/77b0d2dc_mus_model.json new file mode 100644 index 0000000..6f0561e --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/77b0d2dc/77b0d2dc_mus_model.json @@ -0,0 +1,59 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.875 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 4.875 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 1, 0, 0, 0 ] ], 4.75 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 4.125 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 9.625 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -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 ], [ 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, 0, 1, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ] +], +"cur_uid": "77b0d2dc", +"ref_uid": "nil", +"order_seed": 921767, +"dur_seed": 954688, +"motifs_seed": 995213, +"entrances_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/7bb0e931/7bb0e931_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/7bb0e931/7bb0e931_code.scd new file mode 100644 index 0000000..c194eef --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/7bb0e931/7bb0e931_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/7bb0e931/7bb0e931_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/7bb0e931/7bb0e931_mus_model.json new file mode 100644 index 0000000..97c68b2 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/7bb0e931/7bb0e931_mus_model.json @@ -0,0 +1,69 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.875 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 3.375 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 1, 0, 0, 0 ] ], 1.25 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 3.125 ] + ], + [ + [ [ [ 1, 0, -1, 0, 0, -1 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 1, 0, -1, 0, 0, -1 ], [ 1, 0, 1, 0, 0, -1 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 2.25 ] + ], + [ + [ [ [ 1, -1, 0, 0, -1, 0 ], [ 1, 0, 1, 0, 0, -1 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 2.625 ], + [ [ [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], + [ [ [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ 2, -1, 0, -1, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 10.0 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 1, 0, -1, 0, 0, -1 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 1, 0, -1, 0, 0, -1 ], [ 1, 0, 1, 0, 0, -1 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 1, -1, 0, 0, -1, 0 ], [ 1, 0, 1, 0, 0, -1 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ] +], +"cur_uid": "7bb0e931", +"ref_uid": "nil", +"order_seed": 921767, +"dur_seed": 233566, +"motifs_seed": 995213, +"entrances_probs_vals": [ 1, 0, 0, 0.88, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 0.88, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 0.88, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/7df3df4c/7df3df4c_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/7df3df4c/7df3df4c_code.scd new file mode 100644 index 0000000..c194eef --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/7df3df4c/7df3df4c_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/7df3df4c/7df3df4c_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/7df3df4c/7df3df4c_mus_model.json new file mode 100644 index 0000000..e06a740 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/7df3df4c/7df3df4c_mus_model.json @@ -0,0 +1,59 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.875 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 4.875 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 4.75 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -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, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 4.125 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], + [ [ [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], + [ [ [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 9.625 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ] +], +"cur_uid": "7df3df4c", +"ref_uid": "77b0d2dc", +"order_seed": 921767, +"dur_seed": 954688, +"motifs_seed": 995213, +"entrances_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/7fe1da13/7fe1da13_code.scd b/resources/resources_bak_2024_01_03/string_quartet_2/7fe1da13/7fe1da13_code.scd new file mode 100644 index 0000000..c194eef --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/7fe1da13/7fe1da13_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/7fe1da13/7fe1da13_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/7fe1da13/7fe1da13_mus_model.json new file mode 100644 index 0000000..61971c6 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/7fe1da13/7fe1da13_mus_model.json @@ -0,0 +1,198 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 4.25 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 4.25 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 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, 1, 0, 0, 0 ] ], 4.875 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, 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, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 4.875 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 1, 0 ], [ -1, 0, 0, 1, 0, 1 ] ], 0 ], + [ [ [ 0, -1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 1, 0 ], [ -1, 0, 0, 1, 0, 1 ] ], 0 ], + [ [ [ 0, -1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 1 ], [ -1, 0, 0, 0, 0, 2 ], [ -1, 0, 0, 1, 0, 1 ] ], 3.875 ] + ], + [ + [ [ [ 0, -1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 1 ], [ -1, 0, 0, 0, 0, 2 ], [ 0, 0, 0, 0, 1, 1 ] ], 0 ], + [ [ [ -1, 0, 1, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 1 ], [ -1, 0, 0, 0, 0, 2 ], [ 0, 0, 0, 0, 1, 1 ] ], 0 ], + [ [ [ -1, 0, 1, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 1 ], [ -1, 1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 1, 1 ] ], 4.125 ] + ], + [ + [ [ [ -1, 0, 1, 0, 0, 1 ], [ -1, 0, 0, 1, 0, 1 ], [ -1, 1, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 1, 1 ] ], 4.875 ], + [ [ [ -1, 0, 1, 0, 0, 1 ], [ -1, 0, 0, 1, 0, 1 ], [ -1, 1, 0, 0, 0, 1 ], [ -1, 0, 0, 1, 0, 2 ] ], 0 ], + [ [ [ -1, 0, 1, 0, 0, 1 ], [ -1, 0, 0, 1, 0, 1 ], [ -2, 0, 0, 1, 0, 2 ], [ -1, 0, 0, 1, 0, 2 ] ], 0 ], + [ [ [ -1, 0, 1, 0, 0, 1 ], [ 0, 0, -1, 1, 0, 1 ], [ -2, 0, 0, 1, 0, 2 ], [ -1, 0, 0, 1, 0, 2 ] ], 4.375 ] + ], + [ + [ [ [ -1, 0, 1, 0, 0, 1 ], [ 0, 0, -1, 1, 0, 1 ], [ -2, 0, 0, 1, 0, 2 ], [ 0, -1, -1, 1, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ 0, 0, -1, 1, 0, 1 ], [ -2, 0, 0, 1, 0, 2 ], [ 0, -1, -1, 1, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ 0, 0, -1, 1, 0, 1 ], [ -1, 0, -1, 1, 0, 1 ], [ 0, -1, -1, 1, 0, 1 ] ], 3.875 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ 0, 0, -1, 1, 0, 1 ], [ -1, 0, -1, 1, 0, 1 ], [ -2, 0, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ 0, 0, -1, 1, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -2, 0, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 1, -1, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -2, 0, -1, 2, 0, 2 ] ], 4.875 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 1, -1, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -1, 0, -2, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 1, -1, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ], [ -1, 0, -2, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 2, -1, 1 ], [ -2, 0, 0, 2, 0, 1 ], [ -1, 0, -2, 2, 0, 1 ] ], 4.125 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 2, -1, 1 ], [ -1, -1, -1, 2, 0, 1 ], [ -1, 0, -2, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 2, -1, 1 ], [ -1, -1, -1, 2, 0, 1 ], [ -2, 1, -1, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 1, 1 ], [ -1, -1, -1, 2, 0, 1 ], [ -2, 1, -1, 2, 0, 1 ] ], 4.75 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 1, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -2, 1, -1, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 1, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -1, 0, -1, 2, -1, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, -1, -1, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -1, 0, -1, 2, -1, 1 ] ], 4.875 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -1, 0, -1, 2, -1, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -2, 0, -1, 2, 1, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ], [ -1, -1, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 1, 1 ] ], 4.375 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ], [ -1, 0, -1, 2, -1, 1 ], [ -2, 0, -1, 2, 1, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ], [ -1, 0, -1, 2, -1, 1 ], [ -1, -1, -1, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -1, 0, -1, 2, -1, 1 ], [ -1, -1, -1, 2, 0, 1 ] ], 5 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -2, 1, -1, 2, 0, 1 ], [ -1, -1, -1, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -2, 1, -1, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, -1, -1, 2, 0, 1 ], [ -2, 1, -1, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ] ], 4.25 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 1, 1 ], [ -2, 1, -1, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 1, 1 ], [ -1, 0, -2, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 1, 1 ], [ -1, 0, -2, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ] ], 3.875 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 1, 1 ], [ -2, 0, -1, 2, 0, 2 ], [ -1, 0, -1, 2, 0, 0 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 1, 1 ], [ -2, 0, -1, 2, 0, 2 ], [ -1, 0, -1, 1, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, -1, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 0, 2 ], [ -1, 0, -1, 1, 0, 1 ] ], 4.375 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, -1, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 0, 2 ], [ -1, 0, -2, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -2, 0, -1, 2, 0, 2 ], [ -1, 0, -2, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -2, 1, -1, 2, 0, 1 ], [ -1, 0, -2, 2, 0, 1 ] ], 4.375 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -1, 0, -1, 2, -1, 1 ], [ -1, 0, -2, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 1, 0, 1 ], [ -1, 0, -1, 2, -1, 1 ], [ -1, 0, -2, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 1, 0, 1 ], [ -1, 0, -1, 2, -1, 1 ], [ -2, 1, -1, 2, 0, 1 ] ], 4.125 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ], [ -1, 0, -1, 2, -1, 1 ], [ -2, 1, -1, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ], [ -2, 0, -1, 2, 1, 1 ], [ -2, 1, -1, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ], [ -2, 0, -1, 2, 1, 1 ], [ -1, 0, -1, 2, -1, 1 ] ], 3.875 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ], [ -2, 0, -1, 2, 1, 1 ], [ 0, 0, -1, 1, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -2, 0, -1, 2, 1, 1 ], [ 0, 0, -1, 1, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -1, -1, -1, 2, 0, 1 ], [ 0, 0, -1, 1, 0, 1 ] ], 4.5 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -1, -1, -1, 2, 0, 1 ], [ 0, 0, -1, 2, 0, 0 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 1, 0, 1 ], [ -1, -1, -1, 2, 0, 1 ], [ 0, 0, -1, 2, 0, 0 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 1, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ], [ 0, 0, -1, 2, 0, 0 ] ], 4.625 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 1, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ], [ 0, -1, -1, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -1, 1, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ 0, -1, -1, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 0, 2 ], [ -1, 0, -1, 2, 0, 0 ], [ 0, -1, -1, 2, 0, 1 ] ], 4.875 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -2, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ 0, -1, -1, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -2, 2, 0, 1 ], [ -1, 0, -1, 2, 0, 0 ], [ -1, 0, 0, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -2, 2, 0, 1 ], [ -1, -1, -1, 2, 0, 1 ], [ -1, 0, 0, 2, 0, 1 ] ], 4.25 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -2, 2, 0, 1 ], [ -2, 0, -1, 2, 1, 1 ], [ -1, 0, 0, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -1, 0, -2, 2, 0, 1 ], [ -2, 0, -1, 2, 1, 1 ], [ 0, 0, -1, 2, 0, 0 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 1, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 1, 1 ], [ 0, 0, -1, 2, 0, 0 ] ], 4.875 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 1, -1, 2, 0, 1 ], [ -1, 0, -1, 2, -1, 1 ], [ 0, 0, -1, 2, 0, 0 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 0, 2 ], [ -1, 0, -1, 2, -1, 1 ], [ 0, 0, -1, 2, 0, 0 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 0, 2 ], [ -1, 0, -1, 2, -1, 1 ], [ 0, 0, -1, 1, 0, 1 ] ], 4.5 ] + ], + [ + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 3, 0, 1 ], [ -1, 0, -1, 2, -1, 1 ], [ 0, 0, -1, 1, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 3, 0, 1 ], [ -1, 0, -1, 2, -1, 1 ], [ -2, 0, 0, 2, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 3, 0, 1 ], [ -2, 1, -1, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ] ], 3.875 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 3, 0, 1 ], [ -2, 1, -1, 2, 0, 1 ], [ "Rest" ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 3, 0, 1 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ -2, 0, -1, 2, 0, 1 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 8.5 ] + ] + ] +], +"last_changes": +[ + [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 0, 2 ], [ -1, 0, -1, 2, -1, 1 ], [ 0, 0, -1, 2, 0, 0 ] ], + [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 2, 0, 2 ], [ -1, 0, -1, 2, -1, 1 ], [ 0, 0, -1, 1, 0, 1 ] ], + [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 3, 0, 1 ], [ -1, 0, -1, 2, -1, 1 ], [ 0, 0, -1, 1, 0, 1 ] ], + [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 3, 0, 1 ], [ -1, 0, -1, 2, -1, 1 ], [ -2, 0, 0, 2, 0, 1 ] ], + [ [ -2, 0, -1, 2, 0, 1 ], [ -2, 0, -1, 3, 0, 1 ], [ -2, 1, -1, 2, 0, 1 ], [ -2, 0, 0, 2, 0, 1 ] ] +], +"cur_uid": "7fe1da13", +"ref_uid": "nil", +"order_seed": 962045, +"dur_seed": 299387, +"motifs_seed": 678579, +"entrances_probs_vals": [ 1, 0, 0, 3.8461538461538, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 3.8461538461538, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 3.8461538461538, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 1 ], [ 3, 2, 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 1, 2, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 1, 2, 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_2/tmp/tmp_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_2/tmp/tmp_mus_model.json new file mode 100644 index 0000000..d270a25 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_2/tmp/tmp_mus_model.json @@ -0,0 +1,71 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 7 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 5.5 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 4 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -2, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 5.625 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 6.5 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ "Rest" ], [ -2, 3, -2, 0, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 6.375 ] + ] + ] +], +"last_changes": +[ + [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -2, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], + [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ] +], +"cur_uid": "tmp", +"ref_uid": 62300302, +"order_seed": 209649, +"dur_seed": 306774, +"motifs_seed": 821280, +"entrances_probs_vals": [ 1, 0, 2.9365079365079, 0.47, 2.8021978021978, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 2.7380952380952, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 2.7380952380952, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.35390946502058, 0, 0.5, 0.5, 0.62139917695473, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8.0714285714286, 10.091836734694 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3.json b/resources/resources_bak_2024_01_03/string_quartet_3.json new file mode 100644 index 0000000..f4e9aa1 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3.json @@ -0,0 +1,21 @@ +{ +"ledger": +[ + "5201b8af", + "781442dc", + "6f0f638f", + "577cf188", + "7c2de94c", + "5488f7e9", + "5ec14635", + "726a40c7", + "55f9b81e", + "45fa07e8", + "6a9928d6", + "55bd25a1", + "75316bf0", + "69c568c6", + "4ff624b0", + "7e230015" +] +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3.json_bak b/resources/resources_bak_2024_01_03/string_quartet_3.json_bak new file mode 100644 index 0000000..4417271 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3.json_bak @@ -0,0 +1,20 @@ +{ +"ledger": +[ + "5201b8af", + "781442dc", + "6f0f638f", + "577cf188", + "7c2de94c", + "5488f7e9", + "5ec14635", + "726a40c7", + "55f9b81e", + "45fa07e8", + "6a9928d6", + "55bd25a1", + "75316bf0", + "69c568c6", + "4ff624b0" +] +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/45fa07e8/45fa07e8_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/45fa07e8/45fa07e8_code.scd new file mode 100644 index 0000000..92aa171 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/45fa07e8/45fa07e8_code.scd @@ -0,0 +1,966 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + if(pDistance < 0, {stepFunc.value(abs(pDistance))}, {0.001}); + //stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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); + + + if(rangeScore.value(candidate, [0, 0, 0, 0, 0, 0], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate, candidate.collect({0}), ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + }, { + 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/45fa07e8/45fa07e8_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/45fa07e8/45fa07e8_mus_model.json new file mode 100644 index 0000000..10b6bb0 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/45fa07e8/45fa07e8_mus_model.json @@ -0,0 +1,443 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ 2, -5, 0, 3, -1, -1 ], [ "Rest" ], [ "Rest" ] ], 1.5 ], + [ [ [ "Rest" ], [ 2, -5, 0, 3, -1, -1 ], [ "Rest" ], [ 4, -5, -1, 2, -1, -1 ] ], 1.75 ], + [ [ [ 2, -5, -1, 3, -1, -1 ], [ 2, -5, 0, 3, -1, -1 ], [ "Rest" ], [ 4, -5, -1, 2, -1, -1 ] ], 1 ], + [ [ [ 2, -5, -1, 3, -1, -1 ], [ 2, -5, 0, 3, -1, -1 ], [ 4, -5, -1, 2, 0, -1 ], [ 4, -5, -1, 2, -1, -1 ] ], 1.375 ] + ], + [ + [ [ [ 2, -5, -1, 3, -1, -1 ], [ 4, -5, -1, 1, -1, -1 ], [ 4, -5, -1, 2, 0, -1 ], [ 4, -5, -1, 2, -1, -1 ] ], 0.875 ] + ], + [ + [ [ [ 2, -5, -1, 3, -1, -1 ], [ 4, -5, -1, 1, -1, -1 ], [ 4, -5, -1, 2, 0, -1 ], [ 3, -4, -1, 2, 0, -1 ] ], 1.625 ] + ], + [ + [ [ [ 2, -5, -1, 3, -1, -1 ], [ 3, -5, -1, 3, -1, -1 ], [ 4, -5, -1, 2, 0, -1 ], [ 3, -4, -1, 2, 0, -1 ] ], 0.75 ] + ], + [ + [ [ [ 2, -5, -1, 3, -1, -1 ], [ 4, -6, -1, 2, 0, -1 ], [ 4, -5, -1, 2, 0, -1 ], [ 3, -4, -1, 2, 0, -1 ] ], 1.75 ] + ], + [ + [ [ [ 3, -6, -1, 2, 0, -1 ], [ 4, -6, -1, 2, 0, -1 ], [ 4, -5, -1, 2, 0, -1 ], [ 3, -4, -1, 2, 0, -1 ] ], 1.375 ] + ], + [ + [ [ [ 3, -6, -1, 2, 0, -1 ], [ 4, -5, -1, 2, -1, -1 ], [ 4, -5, -1, 2, 0, -1 ], [ 3, -4, -1, 2, 0, -1 ] ], 1.125 ] + ], + [ + [ [ [ 3, -6, -1, 2, 0, -1 ], [ 4, -5, -1, 2, -1, -1 ], [ 3, -4, -1, 2, 1, -1 ], [ 3, -4, -1, 2, 0, -1 ] ], 1.625 ] + ], + [ + [ [ [ 3, -6, -1, 2, 0, -1 ], [ 4, -5, -1, 2, -1, -1 ], [ 3, -4, -1, 2, 1, -1 ], [ 2, -3, -1, 2, 1, -1 ] ], 1.125 ] + ], + [ + [ [ [ 3, -6, -1, 2, 0, -1 ], [ 4, -5, -1, 2, -1, -1 ], [ 3, -4, -1, 2, 1, -1 ], [ 3, -4, -2, 2, 1, -1 ] ], 1.5 ] + ], + [ + [ [ [ 3, -6, -1, 2, 0, -1 ], [ 4, -5, -1, 2, -1, -1 ], [ 4, -5, -2, 2, 1, -1 ], [ 3, -4, -2, 2, 1, -1 ] ], 1.375 ] + ], + [ + [ [ [ 3, -5, -2, 2, 0, -1 ], [ 4, -5, -1, 2, -1, -1 ], [ 4, -5, -2, 2, 1, -1 ], [ 3, -4, -2, 2, 1, -1 ] ], 1.5 ] + ], + [ + [ [ [ 3, -5, -2, 2, 0, -1 ], [ 4, -5, -2, 2, 0, -1 ], [ 4, -5, -2, 2, 1, -1 ], [ 3, -4, -2, 2, 1, -1 ] ], 1.625 ] + ], + [ + [ [ [ 3, -5, -2, 2, 0, -1 ], [ 4, -5, -2, 2, 0, -1 ], [ 4, -5, -2, 2, 1, -1 ], [ 5, -5, -2, 1, 0, -1 ] ], 1.25 ] + ], + [ + [ [ [ 3, -5, -2, 2, 0, -1 ], [ 4, -5, -3, 2, 1, -1 ], [ 4, -5, -2, 2, 1, -1 ], [ 5, -5, -2, 1, 0, -1 ] ], 1.75 ] + ], + [ + [ [ [ 3, -5, -2, 2, 0, -1 ], [ 4, -5, -3, 2, 1, -1 ], [ 4, -5, -2, 2, 1, -1 ], [ 3, -5, -2, 3, 1, -1 ] ], 0.875 ] + ], + [ + [ [ [ 3, -5, -2, 2, 0, -1 ], [ 5, -5, -2, 1, 0, -1 ], [ 4, -5, -2, 2, 1, -1 ], [ 3, -5, -2, 3, 1, -1 ] ], 0.625 ] + ], + [ + [ [ [ 3, -5, -2, 2, 0, -1 ], [ 5, -6, -2, 2, 0, -1 ], [ 4, -5, -2, 2, 1, -1 ], [ 3, -5, -2, 3, 1, -1 ] ], 0.75 ] + ], + [ + [ [ [ 3, -5, -2, 2, 0, -1 ], [ 5, -6, -2, 2, 0, -1 ], [ 4, -5, -2, 2, 1, -1 ], [ 5, -5, -2, 2, 0, -2 ] ], 1.125 ] + ], + [ + [ [ [ 3, -5, -2, 2, 0, -1 ], [ 6, -5, -2, 1, 0, -2 ], [ 4, -5, -2, 2, 1, -1 ], [ 5, -5, -2, 2, 0, -2 ] ], 1.5 ] + ], + [ + [ [ [ 4, -4, -2, 1, 0, -2 ], [ 6, -5, -2, 1, 0, -2 ], [ 4, -5, -2, 2, 1, -1 ], [ 5, -5, -2, 2, 0, -2 ] ], 1.375 ] + ], + [ + [ [ [ 4, -4, -2, 1, 0, -2 ], [ 6, -4, -2, 1, -1, -2 ], [ 4, -5, -2, 2, 1, -1 ], [ 5, -5, -2, 2, 0, -2 ] ], 1.625 ] + ], + [ + [ [ [ 4, -4, -2, 1, 0, -2 ], [ 6, -4, -2, 1, -1, -2 ], [ 6, -5, -2, 2, 0, -3 ], [ 5, -5, -2, 2, 0, -2 ] ], 1.375 ] + ], + [ + [ [ [ 5, -4, -2, 1, -2, -2 ], [ 6, -4, -2, 1, -1, -2 ], [ 6, -5, -2, 2, 0, -3 ], [ 5, -5, -2, 2, 0, -2 ] ], 0.75 ] + ], + [ + [ [ [ 5, -4, -2, 1, -2, -2 ], [ 6, -4, -2, 1, -1, -2 ], [ 5, -5, -1, 2, 0, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 1.375 ] + ], + [ + [ [ [ 5, -4, -2, 1, -2, -2 ], [ 6, -4, -2, 1, -1, -2 ], [ 5, -5, -2, 1, -1, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 1 ] + ], + [ + [ [ [ 5, -4, -2, 1, -2, -2 ], [ 6, -4, -2, 1, -1, -2 ], [ 4, -4, -2, 1, 0, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 1.625 ] + ], + [ + [ [ [ 5, -4, -2, 1, -2, -2 ], [ 6, -4, -2, 1, -1, -2 ], [ 4, -3, -2, 1, -1, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 1.625 ] + ], + [ + [ [ [ 5, -4, -2, 1, -2, -2 ], [ 5, -3, -2, 1, -2, -2 ], [ 4, -3, -2, 1, -1, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 1 ] + ], + [ + [ [ [ 4, -5, -2, 2, 0, -2 ], [ 5, -3, -2, 1, -2, -2 ], [ 4, -3, -2, 1, -1, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 1.125 ] + ], + [ + [ [ [ 4, -5, -2, 2, 0, -2 ], [ 5, -3, -2, 1, -2, -2 ], [ 5, -3, -2, 1, -3, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 0.75 ] + ], + [ + [ [ [ 4, -5, -2, 2, 0, -2 ], [ 5, -5, -2, 2, -1, -2 ], [ 5, -3, -2, 1, -3, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 1.5 ] + ], + [ + [ [ [ 4, -5, -2, 1, -1, -2 ], [ 5, -5, -2, 2, -1, -2 ], [ 5, -3, -2, 1, -3, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 0.875 ] + ], + [ + [ [ [ 4, -5, -2, 1, -1, -2 ], [ 4, -4, -2, 2, 0, -2 ], [ 5, -3, -2, 1, -3, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 1.75 ] + ], + [ + [ [ [ 4, -5, -2, 1, -1, -2 ], [ 4, -4, -2, 2, 0, -2 ], [ 5, -5, -2, 1, 0, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 0.875 ] + ], + [ + [ [ [ 4, -5, -2, 1, -1, -2 ], [ 4, -4, -2, 2, 0, -2 ], [ 5, -4, -2, 1, -1, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 0.875 ] + ], + [ + [ [ [ 4, -5, -2, 1, -1, -2 ], [ 4, -4, -2, 2, 0, -2 ], [ 4, -5, -1, 2, 0, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 1.5 ] + ], + [ + [ [ [ 4, -5, -2, 1, -1, -2 ], [ 4, -4, -2, 2, 0, -2 ], [ 5, -6, -2, 2, 0, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 0.875 ] + ], + [ + [ [ [ 4, -5, -2, 1, -1, -2 ], [ 4, -5, -2, 2, 0, -1 ], [ 5, -6, -2, 2, 0, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 1.625 ] + ], + [ + [ [ [ 4, -5, -2, 1, -1, -2 ], [ 4, -5, -2, 2, 0, -1 ], [ 5, -5, -2, 2, -1, -2 ], [ 5, -5, -2, 2, 0, -2 ] ], 1.125 ] + ], + [ + [ [ [ 4, -5, -2, 1, -1, -2 ], [ 4, -5, -2, 2, 0, -1 ], [ 5, -5, -2, 2, -1, -2 ], [ 5, -4, -2, 2, -1, -2 ] ], 1.5 ] + ], + [ + [ [ [ 4, -5, -2, 1, -1, -2 ], [ 5, -4, -3, 2, -1, -2 ], [ 5, -5, -2, 2, -1, -2 ], [ 5, -4, -2, 2, -1, -2 ] ], 0.875 ] + ], + [ + [ [ [ 4, -5, -2, 1, -1, -2 ], [ 5, -4, -3, 2, -1, -2 ], [ 5, -5, -2, 2, -1, -2 ], [ 6, -5, -3, 2, -1, -2 ] ], 1.5 ] + ], + [ + [ [ [ 4, -5, -2, 1, -1, -2 ], [ 5, -4, -3, 2, -1, -2 ], [ 6, -6, -3, 2, -1, -2 ], [ 6, -5, -3, 2, -1, -2 ] ], 1.25 ] + ], + [ + [ [ [ 4, -5, -2, 1, -1, -2 ], [ 5, -4, -3, 2, -1, -2 ], [ 6, -5, -2, 1, -1, -2 ], [ 6, -5, -3, 2, -1, -2 ] ], 1.5 ] + ], + [ + [ [ [ 4, -5, -2, 1, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ], [ 6, -5, -2, 1, -1, -2 ], [ 6, -5, -3, 2, -1, -2 ] ], 0.75 ] + ], + [ + [ [ [ 4, -5, -2, 1, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ], [ 6, -5, -2, 1, -1, -2 ], [ 6, -4, -2, 1, -1, -2 ] ], 0.75 ] + ], + [ + [ [ [ 5, -5, -2, 0, -1, -2 ], [ 7, -5, -2, 0, -1, -2 ], [ 6, -5, -2, 1, -1, -2 ], [ 6, -4, -2, 1, -1, -2 ] ], 1.125 ] + ], + [ + [ [ [ 5, -5, -2, 1, -1, -3 ], [ 7, -5, -2, 0, -1, -2 ], [ 6, -5, -2, 1, -1, -2 ], [ 6, -4, -2, 1, -1, -2 ] ], 1.625 ] + ], + [ + [ [ [ 5, -5, -2, 1, -1, -3 ], [ 6, -4, -3, 1, -1, -2 ], [ 6, -5, -2, 1, -1, -2 ], [ 6, -4, -2, 1, -1, -2 ] ], 1.75 ] + ], + [ + [ [ [ 5, -5, -2, 1, -1, -3 ], [ 6, -4, -3, 1, -1, -2 ], [ 5, -3, -2, 1, -1, -2 ], [ 6, -4, -2, 1, -1, -2 ] ], 0.875 ] + ], + [ + [ [ [ 4, -4, -2, 1, -1, -2 ], [ 6, -4, -3, 1, -1, -2 ], [ 5, -3, -2, 1, -1, -2 ], [ 6, -4, -2, 1, -1, -2 ] ], 1.25 ] + ], + [ + [ [ [ 4, -4, -2, 1, -1, -2 ], [ 6, -4, -3, 1, -1, -2 ], [ 5, -4, -2, 1, -1, -2 ], [ 6, -4, -2, 1, -1, -2 ] ], 1.625 ] + ], + [ + [ [ [ 4, -4, -2, 1, -1, -2 ], [ 5, -4, -2, 2, -1, -2 ], [ 5, -4, -2, 1, -1, -2 ], [ 6, -4, -2, 1, -1, -2 ] ], 1.875 ] + ], + [ + [ [ [ 4, -4, -2, 1, -1, -2 ], [ 3, -3, -2, 1, -1, -2 ], [ 5, -4, -2, 1, -1, -2 ], [ 6, -4, -2, 1, -1, -2 ] ], 1.625 ] + ], + [ + [ [ [ 4, -4, -2, 1, -1, -2 ], [ 4, -4, -3, 1, -1, -2 ], [ 5, -4, -2, 1, -1, -2 ], [ 6, -4, -2, 1, -1, -2 ] ], 1.5 ] + ], + [ + [ [ [ 4, -4, -2, 1, -1, -2 ], [ 4, -4, -3, 1, -1, -2 ], [ 5, -4, -2, 1, -1, -2 ], [ 5, -4, -3, 1, -1, -2 ] ], 0.625 ] + ], + [ + [ [ [ 4, -4, -2, 1, -1, -2 ], [ 3, -4, -2, 2, -1, -2 ], [ 5, -4, -2, 1, -1, -2 ], [ 5, -4, -3, 1, -1, -2 ] ], 1.625 ] + ], + [ + [ [ [ 4, -4, -2, 1, -1, -2 ], [ 5, -4, -3, 0, -1, -2 ], [ 5, -4, -2, 1, -1, -2 ], [ 5, -4, -3, 1, -1, -2 ] ], 1.625 ] + ], + [ + [ [ [ 5, -4, -3, 1, -2, -2 ], [ 5, -4, -3, 0, -1, -2 ], [ 5, -4, -2, 1, -1, -2 ], [ 5, -4, -3, 1, -1, -2 ] ], 0.875 ] + ], + [ + [ [ [ 5, -4, -3, 1, -2, -2 ], [ 5, -4, -3, 0, -1, -2 ], [ 6, -5, -3, 1, -1, -2 ], [ 5, -4, -3, 1, -1, -2 ] ], 1.125 ] + ], + [ + [ [ [ 4, -3, -3, 1, -1, -2 ], [ 5, -4, -3, 0, -1, -2 ], [ 6, -5, -3, 1, -1, -2 ], [ 5, -4, -3, 1, -1, -2 ] ], 1 ] + ], + [ + [ [ [ 4, -3, -3, 1, -1, -2 ], [ 5, -4, -3, 0, -1, -2 ], [ 6, -5, -3, 1, -1, -2 ], [ 6, -5, -4, 1, -1, -2 ] ], 1.5 ] + ], + [ + [ [ [ 5, -5, -2, 1, -1, -2 ], [ 5, -4, -3, 0, -1, -2 ], [ 6, -5, -3, 1, -1, -2 ], [ 6, -5, -4, 1, -1, -2 ] ], 1 ] + ], + [ + [ [ [ 5, -5, -2, 1, -1, -2 ], [ 5, -4, -3, 0, -1, -2 ], [ 6, -5, -3, 1, -1, -2 ], [ 5, -5, -3, 1, -1, -1 ] ], 1.25 ] + ], + [ + [ [ [ 5, -5, -2, 1, -1, -2 ], [ 5, -4, -3, 0, -1, -2 ], [ 5, -5, -2, 1, -1, -1 ], [ 5, -5, -3, 1, -1, -1 ] ], 1.375 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -4, -3, 0, -1, -2 ], [ 5, -5, -2, 1, -1, -1 ], [ 5, -5, -3, 1, -1, -1 ] ], 1.375 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -4, -3, 0, -1, -2 ], [ 5, -5, -2, 1, -1, -1 ], [ 4, -5, -2, 2, -1, -1 ] ], 1.5 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -4, -3, 0, -1, -2 ], [ 5, -5, -2, 1, -1, -1 ], [ 6, -7, -2, 1, -1, -1 ] ], 1.375 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -4, -3, 0, -1, -2 ], [ 5, -5, -2, 1, -1, -1 ], [ 6, -6, -2, 1, -2, -1 ] ], 1.625 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -4, -3, 0, -1, -2 ], [ 6, -6, -3, 1, -1, -1 ], [ 6, -6, -2, 1, -2, -1 ] ], 1.125 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -4, -3, 0, -1, -2 ], [ 5, -6, -2, 2, -1, -1 ], [ 6, -6, -2, 1, -2, -1 ] ], 1.125 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -4, -3, 0, -1, -2 ], [ 5, -6, -2, 2, -1, -1 ], [ 6, -4, -2, 0, -1, -2 ] ], 0.625 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -4, -3, 0, -1, -2 ], [ 7, -4, -2, -1, -1, -2 ], [ 6, -4, -2, 0, -1, -2 ] ], 1 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -7, -2, 1, -1, -1 ], [ 7, -4, -2, -1, -1, -2 ], [ 6, -4, -2, 0, -1, -2 ] ], 1.5 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 4, -4, -2, 1, -1, -2 ], [ 7, -4, -2, -1, -1, -2 ], [ 6, -4, -2, 0, -1, -2 ] ], 1.25 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 4, -5, -2, 1, -1, -1 ], [ 7, -4, -2, -1, -1, -2 ], [ 6, -4, -2, 0, -1, -2 ] ], 1.625 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 4, -5, -2, 1, -1, -1 ], [ 7, -4, -2, -1, -1, -2 ], [ 5, -6, -2, 1, -1, 0 ] ], 1 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 4, -5, -2, 1, -1, -1 ], [ 6, -6, -2, 1, -1, -1 ], [ 5, -6, -2, 1, -1, 0 ] ], 1.625 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 4, -5, -2, 1, -1, -1 ], [ 5, -6, -1, 1, -1, 0 ], [ 5, -6, -2, 1, -1, 0 ] ], 1.25 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 4, -5, -2, 1, -1, -1 ], [ 5, -6, -1, 1, -1, 0 ], [ 5, -6, -2, 2, -1, -1 ] ], 1 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 4, -5, -2, 1, -1, -1 ], [ 5, -6, -1, 1, -1, 0 ], [ 5, -5, -1, 1, -1, -1 ] ], 1.625 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 4, -6, -1, 1, -1, -1 ], [ 5, -6, -1, 1, -1, 0 ], [ 5, -5, -1, 1, -1, -1 ] ], 1.25 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -7, -2, 1, -1, -1 ], [ 5, -6, -1, 1, -1, 0 ], [ 5, -5, -1, 1, -1, -1 ] ], 0.875 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -7, -2, 1, -1, -1 ], [ 6, -5, -1, 0, -1, -1 ], [ 5, -5, -1, 1, -1, -1 ] ], 1.25 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -7, -2, 1, -1, -1 ], [ 6, -5, -1, 0, -1, -1 ], [ 6, -6, -2, 1, -1, -1 ] ], 0.75 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -7, -2, 1, -1, -1 ], [ 7, -7, -2, 1, -1, -1 ], [ 6, -6, -2, 1, -1, -1 ] ], 1.125 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -7, -2, 1, -1, -1 ], [ 4, -6, -2, 1, -1, -1 ], [ 6, -6, -2, 1, -1, -1 ] ], 1.625 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -7, -2, 1, -1, -1 ], [ 4, -6, -2, 1, -1, -1 ], [ 7, -7, -3, 1, -1, -1 ] ], 1.125 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -7, -2, 1, -1, -1 ], [ 4, -6, -2, 1, -1, -1 ], [ 6, -7, -2, 1, -1, 0 ] ], 1.375 ] + ], + [ + [ [ [ 5, -6, -2, 1, -1, -1 ], [ 5, -7, -2, 1, -1, -1 ], [ 4, -6, -2, 1, -1, -1 ], [ 6, -6, -1, 1, -1, -1 ] ], 1.75 ] + ], + [ + [ [ [ 4, -6, -1, 1, -1, 0 ], [ 5, -7, -2, 1, -1, -1 ], [ 4, -6, -2, 1, -1, -1 ], [ 6, -6, -1, 1, -1, -1 ] ], 1.125 ] + ], + [ + [ [ [ 4, -6, -1, 1, -1, 0 ], [ 5, -7, -2, 1, -1, -1 ], [ 4, -6, -2, 1, -1, -1 ], [ 7, -7, -2, 1, -1, -1 ] ], 1.25 ] + ], + [ + [ [ [ 4, -6, -1, 1, -1, 0 ], [ 5, -7, -2, 1, -1, -1 ], [ 4, -7, -2, 1, -1, 0 ], [ 7, -7, -2, 1, -1, -1 ] ], 0.75 ] + ], + [ + [ [ [ 4, -6, -1, 1, -1, 0 ], [ 5, -7, -2, 1, -1, -1 ], [ 4, -7, -2, 1, -1, 0 ], [ 6, -7, -1, 1, -1, 0 ] ], 1 ] + ], + [ + [ [ [ 4, -6, -1, 1, -1, 0 ], [ 5, -7, -2, 1, -1, -1 ], [ 4, -7, -2, 1, -1, 0 ], [ 5, -6, -1, 1, 0, 0 ] ], 1.125 ] + ], + [ + [ [ [ 4, -6, -1, 1, -1, 0 ], [ 4, -7, -1, 1, -1, 0 ], [ 4, -7, -2, 1, -1, 0 ], [ 5, -6, -1, 1, 0, 0 ] ], 0.625 ] + ], + [ + [ [ [ 4, -6, -1, 1, -1, 0 ], [ 4, -7, -1, 1, -1, 0 ], [ 3, -5, -1, 1, 0, 0 ], [ 5, -6, -1, 1, 0, 0 ] ], 1.25 ] + ], + [ + [ [ [ 4, -6, -1, 1, -1, 0 ], [ 4, -7, -1, 1, -1, 0 ], [ 3, -5, -1, 1, 0, 0 ], [ 5, -6, -2, 1, -1, 0 ] ], 1.25 ] + ], + [ + [ [ [ 4, -6, -1, 1, -1, 0 ], [ 4, -7, -1, 1, -1, 0 ], [ 3, -5, -1, 1, 0, 0 ], [ 6, -7, -1, 1, -1, -1 ] ], 1 ], + [ [ [ 4, -6, -1, 1, -1, 0 ], [ "Rest" ], [ 3, -5, -1, 1, 0, 0 ], [ 6, -7, -1, 1, -1, -1 ] ], 1.375 ], + [ [ [ 4, -6, -1, 1, -1, 0 ], [ "Rest" ], [ 3, -5, -1, 1, 0, 0 ], [ "Rest" ] ], 1.125 ], + [ [ [ "Rest" ], [ "Rest" ], [ 3, -5, -1, 1, 0, 0 ], [ "Rest" ] ], 1.5 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 6.375 ] + ] + ] +], +"last_changes": +[ + [ [ 4, -6, -1, 1, -1, 0 ], [ 5, -7, -2, 1, -1, -1 ], [ 4, -7, -2, 1, -1, 0 ], [ 5, -6, -1, 1, 0, 0 ] ], + [ [ 4, -6, -1, 1, -1, 0 ], [ 4, -7, -1, 1, -1, 0 ], [ 4, -7, -2, 1, -1, 0 ], [ 5, -6, -1, 1, 0, 0 ] ], + [ [ 4, -6, -1, 1, -1, 0 ], [ 4, -7, -1, 1, -1, 0 ], [ 3, -5, -1, 1, 0, 0 ], [ 5, -6, -1, 1, 0, 0 ] ], + [ [ 4, -6, -1, 1, -1, 0 ], [ 4, -7, -1, 1, -1, 0 ], [ 3, -5, -1, 1, 0, 0 ], [ 5, -6, -2, 1, -1, 0 ] ], + [ [ 4, -6, -1, 1, -1, 0 ], [ 4, -7, -1, 1, -1, 0 ], [ 3, -5, -1, 1, 0, 0 ], [ 6, -7, -1, 1, -1, -1 ] ] +], +"cur_uid": "45fa07e8", +"ref_uid": "55f9b81e", +"order_seed": 921383, +"dur_seed": 545846, +"motifs_seed": 212473, +"entrances_probs_vals": [ 0, 0, 0, 0.66, 1.8406593406593, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 0.66, 1.8406593406593, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 0.66, 1.8406593406593, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2467, 2400 ], [ -1167, 2400 ], [ -702, 2400 ], [ -702, 2400 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.090534979423868, 0.92613636363636, 0.17489711934156, 0.079545454545455, 0.37037037037037, 0, 0.7201646090535, 0, 1, 0 ], +"passages_weights": [ 0.63, 0.62, 1, 0.41, 1 ], +"hd_exp": 6, +"hd_invert": 0, +"order": +[ + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ] +], +"sus_weights": [ 0, 0, 0.61 ], +"order_size": [ 100, 100 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/4ff624b0/4ff624b0_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/4ff624b0/4ff624b0_code.scd new file mode 100644 index 0000000..0d8c24b --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/4ff624b0/4ff624b0_code.scd @@ -0,0 +1,975 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/4ff624b0/4ff624b0_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/4ff624b0/4ff624b0_mus_model.json new file mode 100644 index 0000000..0ef2a04 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/4ff624b0/4ff624b0_mus_model.json @@ -0,0 +1,552 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 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 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 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 ] ], 1 ], + [ [ [ 1, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 1, -1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 1, 0, -1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 1, 0, -1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 1, 0, -1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 1, 0, -1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, -1, 0 ] ], 1 ] + ], + [ + [ [ [ 1, 0, -1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 1, -1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 1, -1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 1, -1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 1 ], + [ [ [ 1, -1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 1, 0, 0, 0, 0 ], [ -2, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ -2, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ -2, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ -2, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -1, 2, 0, 0, 0, 0 ], [ -2, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -1, 2, 0, 0, 0, 0 ], [ -1, 1, -1, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 2, 0, 0, 0, 0 ], [ -1, 1, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ] ], 1 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ -1, 1, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 1, -1, 0, 0, 0 ], [ 0, 1, -1, -1, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ] ], 1 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ 0, 1, -1, -1, 0, 0 ], [ -1, 2, -1, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 3, -1, 0, 0, 0 ], [ 0, 1, -1, -1, 0, 0 ], [ -1, 2, -1, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 3, -1, 0, 0, 0 ], [ 0, 1, -1, -1, 0, 0 ], [ -1, 2, -1, 0, 0, 0 ], [ -2, 3, -1, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 3, -1, 0, 0, 0 ], [ 0, 1, -1, -1, 0, 0 ], [ -1, 3, -1, 0, -1, 0 ], [ -2, 3, -1, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 3, -1, 0, 0, 0 ], [ -1, 3, -1, -1, 0, 0 ], [ -1, 3, -1, 0, -1, 0 ], [ -2, 3, -1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 3, -1, 0, 0, 0 ], [ -1, 3, -1, -1, 0, 0 ], [ -1, 3, -1, 0, -1, 0 ], [ -2, 4, -1, 0, -1, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 3, -1, 0, 0, 0 ], [ -1, 3, -1, -1, 0, 0 ], [ -1, 3, -1, 0, -1, 0 ], [ 0, 3, 0, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 3, -1, -1, 0, 0 ], [ -1, 3, -1, -1, 0, 0 ], [ -1, 3, -1, 0, -1, 0 ], [ 0, 3, 0, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 3, -1, -1, 0, 0 ], [ -1, 3, -1, -1, 0, 0 ], [ 0, 2, -1, -1, 0, 0 ], [ 0, 3, 0, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 3, -1, -1, 0, 0 ], [ -1, 3, -1, -1, 0, 0 ], [ -1, 4, -1, -1, 0, 0 ], [ 0, 3, 0, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 3, -1, -1, 0, 0 ], [ -1, 3, -1, -1, 0, 0 ], [ -1, 4, -1, -1, 0, 0 ], [ 0, 2, -1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 3, -1, -1, 0, 0 ], [ -1, 2, -1, -1, 0, 0 ], [ -1, 4, -1, -1, 0, 0 ], [ 0, 2, -1, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 3, -1, -1, 0, 0 ], [ -2, 4, -1, -1, 0, 0 ], [ -1, 4, -1, -1, 0, 0 ], [ 0, 2, -1, -1, 0, 0 ] ], 1 ], + [ [ [ -2, 5, -1, -1, 0, 0 ], [ -2, 4, -1, -1, 0, 0 ], [ -1, 4, -1, -1, 0, 0 ], [ 0, 2, -1, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 5, -1, -1, 0, 0 ], [ -2, 4, -1, -1, 0, 0 ], [ -1, 4, -1, -1, 0, 0 ], [ -1, 3, -1, -1, 0, 0 ] ], 1 ], + [ [ [ -2, 5, -1, -1, 0, 0 ], [ -3, 6, -1, -1, 0, 0 ], [ -1, 4, -1, -1, 0, 0 ], [ -1, 3, -1, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 5, -1, -1, 0, 0 ], [ -3, 6, -1, -1, 0, 0 ], [ -1, 4, -1, -1, 0, 0 ], [ -3, 7, -1, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 5, -1, -1, 0, 0 ], [ -3, 6, -1, -1, 0, 0 ], [ -2, 6, -1, -1, 0, 0 ], [ -3, 7, -1, -1, 0, 0 ] ], 1 ], + [ [ [ -2, 5, -1, -1, 0, 0 ], [ -4, 8, -1, -1, 0, 0 ], [ -2, 6, -1, -1, 0, 0 ], [ -3, 7, -1, -1, 0, 0 ] ], 1 ], + [ [ [ -3, 6, -1, -1, 0, 0 ], [ -4, 8, -1, -1, 0, 0 ], [ -2, 6, -1, -1, 0, 0 ], [ -3, 7, -1, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 7, -1, -1, 0, 0 ], [ -4, 8, -1, -1, 0, 0 ], [ -2, 6, -1, -1, 0, 0 ], [ -3, 7, -1, -1, 0, 0 ] ], 1 ], + [ [ [ -4, 7, -1, -1, 0, 0 ], [ -2, 7, -1, -1, 0, 0 ], [ -2, 6, -1, -1, 0, 0 ], [ -3, 7, -1, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 6, -1, -1, 0, 0 ], [ -2, 7, -1, -1, 0, 0 ], [ -2, 6, -1, -1, 0, 0 ], [ -3, 7, -1, -1, 0, 0 ] ], 1 ], + [ [ [ -4, 6, -1, -1, 0, 0 ], [ -2, 7, -1, -1, 0, 0 ], [ -3, 8, -1, -1, 0, 0 ], [ -3, 7, -1, -1, 0, 0 ] ], 1 ], + [ [ [ -4, 6, -1, -1, 0, 0 ], [ -2, 6, -1, -1, 0, 0 ], [ -3, 8, -1, -1, 0, 0 ], [ -3, 7, -1, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 6, -1, -1, 0, 0 ], [ -2, 6, -1, -1, 0, 0 ], [ -3, 8, -1, -1, 0, 0 ], [ -3, 7, -1, -1, 0, 0 ] ], 1 ], + [ [ [ -3, 6, -1, -1, 0, 0 ], [ -2, 6, -1, -1, 0, 0 ], [ -3, 7, -1, -1, 0, 1 ], [ -3, 7, -1, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 6, -1, -1, 0, 0 ], [ -2, 6, -1, -1, 0, 0 ], [ -3, 7, -1, -1, 0, 1 ], [ -3, 6, -1, -1, 0, 1 ] ], 1 ], + [ [ [ -3, 6, -1, -1, 0, 0 ], [ -4, 7, -1, 0, 0, 1 ], [ -3, 7, -1, -1, 0, 1 ], [ -3, 6, -1, -1, 0, 1 ] ], 1 ], + [ [ [ -5, 7, -1, 0, 0, 1 ], [ -4, 7, -1, 0, 0, 1 ], [ -3, 7, -1, -1, 0, 1 ], [ -3, 6, -1, -1, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -4, 7, -1, -1, 0, 1 ], [ -4, 7, -1, 0, 0, 1 ], [ -3, 7, -1, -1, 0, 1 ], [ -3, 6, -1, -1, 0, 1 ] ], 1 ], + [ [ [ -4, 7, -1, -1, 0, 1 ], [ -4, 7, -1, 0, 0, 1 ], [ -4, 7, 0, 0, 0, 1 ], [ -3, 6, -1, -1, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -4, 7, -1, -1, 0, 1 ], [ -4, 7, -1, 0, 0, 1 ], [ -3, 6, -1, 0, 0, 1 ], [ -3, 6, -1, -1, 0, 1 ] ], 1 ], + [ [ [ -4, 7, -1, -1, 0, 1 ], [ -3, 7, -1, -1, 0, 1 ], [ -3, 6, -1, 0, 0, 1 ], [ -3, 6, -1, -1, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -3, 5, -1, -1, 0, 1 ], [ -3, 7, -1, -1, 0, 1 ], [ -3, 6, -1, 0, 0, 1 ], [ -3, 6, -1, -1, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -3, 5, -1, -1, 0, 1 ], [ -3, 7, -1, -1, 0, 1 ], [ -3, 6, -1, 0, 0, 1 ], [ -3, 5, -1, 0, 0, 1 ] ], 1 ], + [ [ [ -3, 5, -1, -1, 0, 1 ], [ -2, 5, -1, -1, 0, 1 ], [ -3, 6, -1, 0, 0, 1 ], [ -3, 5, -1, 0, 0, 1 ] ], 1 ], + [ [ [ -3, 5, -1, -1, 0, 1 ], [ -2, 5, -1, -1, 0, 1 ], [ -2, 5, 0, -1, 0, 1 ], [ -3, 5, -1, 0, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -3, 5, -1, -1, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -2, 5, 0, -1, 0, 1 ], [ -3, 5, -1, 0, 0, 1 ] ], 1 ], + [ [ [ -3, 5, -1, -1, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -1, 4, -1, -1, 0, 1 ], [ -3, 5, -1, 0, 0, 1 ] ], 1 ], + [ [ [ -3, 5, -1, -1, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -1, 4, -1, -1, 0, 1 ], [ -2, 5, -1, -1, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -2, 5, -1, -2, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -1, 4, -1, -1, 0, 1 ], [ -2, 5, -1, -1, 0, 1 ] ], 1 ], + [ [ [ -2, 5, -1, -2, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -1, 4, -1, -2, 0, 1 ], [ -2, 5, -1, -1, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -2, 5, -1, -2, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -2, 6, -1, -2, 0, 1 ], [ -2, 5, -1, -1, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -2, 5, -1, -2, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -1, 5, -2, -2, 0, 1 ], [ -2, 5, -1, -1, 0, 1 ] ], 1 ], + [ [ [ -2, 4, -1, -2, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -1, 5, -2, -2, 0, 1 ], [ -2, 5, -1, -1, 0, 1 ] ], 1 ], + [ [ [ -2, 4, -1, -2, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -1, 5, -2, -2, 0, 1 ], [ -1, 4, -1, -2, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -3, 6, -1, -2, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -1, 5, -2, -2, 0, 1 ], [ -1, 4, -1, -2, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -3, 6, -1, -2, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -1, 5, -2, -2, 0, 1 ], [ -2, 6, -1, -2, 0, 1 ] ], 1 ], + [ [ [ -3, 6, -1, -2, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -2, 5, -1, -2, 0, 1 ], [ -2, 6, -1, -2, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -3, 6, -1, -2, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -2, 5, -1, -2, 0, 1 ], [ -1, 5, -2, -2, 0, 1 ] ], 1 ], + [ [ [ -3, 6, -1, -2, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -1, 5, -1, -3, 0, 1 ], [ -1, 5, -2, -2, 0, 1 ] ], 1 ], + [ [ [ -2, 5, -2, -2, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -1, 5, -1, -3, 0, 1 ], [ -1, 5, -2, -2, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -2, 5, -2, -3, 0, 1 ], [ -1, 5, -1, -2, 0, 1 ], [ -1, 5, -1, -3, 0, 1 ], [ -1, 5, -2, -2, 0, 1 ] ], 1 ], + [ [ [ -2, 5, -2, -3, 0, 1 ], [ 0, 5, -1, -3, 0, 1 ], [ -1, 5, -1, -3, 0, 1 ], [ -1, 5, -2, -2, 0, 1 ] ], 1 ], + [ [ [ -2, 5, -2, -3, 0, 1 ], [ 0, 5, -1, -3, 0, 1 ], [ -1, 5, -1, -3, 0, 1 ], [ -1, 6, -1, -3, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -2, 5, -2, -3, 0, 1 ], [ 0, 5, -1, -3, 0, 1 ], [ -1, 5, -1, -3, 0, 1 ], [ -1, 5, -2, -3, 0, 1 ] ], 1 ], + [ [ [ -2, 5, -2, -3, 0, 1 ], [ 1, 4, -2, -3, 0, 1 ], [ -1, 5, -1, -3, 0, 1 ], [ -1, 5, -2, -3, 0, 1 ] ], 1 ], + [ [ [ -2, 5, -2, -3, 0, 1 ], [ 1, 4, -2, -3, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ -1, 5, -2, -3, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -2, 5, -2, -3, 0, 1 ], [ 0, 5, -2, -3, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ -1, 5, -2, -3, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -2, 5, -2, -3, 0, 1 ], [ 1, 5, -2, -4, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ -1, 5, -2, -3, 0, 1 ] ], 1 ], + [ [ [ -1, 5, -2, -4, 0, 1 ], [ 1, 5, -2, -4, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ -1, 5, -2, -3, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -1, 5, -2, -4, 0, 1 ], [ 1, 5, -2, -4, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 0, 5, -2, -4, 0, 1 ] ], 1 ], + [ [ [ -1, 5, -2, -4, 0, 1 ], [ 0, 6, -2, -4, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 0, 5, -2, -4, 0, 1 ] ], 1 ], + [ [ [ -1, 5, -2, -4, 0, 1 ], [ 0, 6, -2, -4, 0, 1 ], [ 0, 5, -1, -4, 0, 1 ], [ 0, 5, -2, -4, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -2, 5, -1, -4, 0, 1 ], [ 0, 6, -2, -4, 0, 1 ], [ 0, 5, -1, -4, 0, 1 ], [ 0, 5, -2, -4, 0, 1 ] ], 1 ], + [ [ [ -2, 5, -1, -4, 0, 1 ], [ 0, 5, -1, -4, 1, 1 ], [ 0, 5, -1, -4, 0, 1 ], [ 0, 5, -2, -4, 0, 1 ] ], 1 ], + [ [ [ -2, 5, -1, -4, 0, 1 ], [ 0, 5, -1, -4, 1, 1 ], [ 0, 5, -1, -4, 0, 1 ], [ -1, 5, -1, -4, 1, 1 ] ], 1 ] + ], + [ + [ [ [ -2, 5, -1, -4, 0, 1 ], [ -1, 6, -1, -4, 0, 1 ], [ 0, 5, -1, -4, 0, 1 ], [ -1, 5, -1, -4, 1, 1 ] ], 1 ], + [ [ [ -1, 5, -1, -5, 0, 1 ], [ -1, 6, -1, -4, 0, 1 ], [ 0, 5, -1, -4, 0, 1 ], [ -1, 5, -1, -4, 1, 1 ] ], 1 ] + ], + [ + [ [ [ -1, 5, -1, -5, 0, 1 ], [ -1, 6, -1, -4, 0, 1 ], [ 0, 5, -1, -4, 0, 1 ], [ 1, 4, -1, -5, 0, 1 ] ], 1 ], + [ [ [ -1, 5, -1, -5, 0, 1 ], [ 0, 6, -1, -5, 0, 1 ], [ 0, 5, -1, -4, 0, 1 ], [ 1, 4, -1, -5, 0, 1 ] ], 1 ], + [ [ [ -1, 5, -1, -5, 0, 1 ], [ 0, 6, -1, -5, 0, 1 ], [ 1, 5, -1, -5, 0, 1 ], [ 1, 4, -1, -5, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -1, 5, -1, -5, 0, 1 ], [ 0, 5, -1, -5, 0, 1 ], [ 1, 5, -1, -5, 0, 1 ], [ 1, 4, -1, -5, 0, 1 ] ], 1 ], + [ [ [ 0, 4, -1, -5, 0, 1 ], [ 0, 5, -1, -5, 0, 1 ], [ 1, 5, -1, -5, 0, 1 ], [ 1, 4, -1, -5, 0, 1 ] ], 1 ], + [ [ [ 0, 4, -1, -5, 0, 1 ], [ 0, 5, -1, -5, 0, 1 ], [ 2, 4, -1, -5, 0, 1 ], [ 1, 4, -1, -5, 0, 1 ] ], 1 ] + ], + [ + [ [ [ 0, 4, -1, -5, 0, 1 ], [ 0, 5, -1, -5, 0, 1 ], [ 2, 4, -1, -5, 0, 1 ], [ 0, 6, -1, -5, 0, 1 ] ], 1 ], + [ [ [ 0, 4, -1, -5, 0, 1 ], [ 0, 5, -1, -5, 0, 1 ], [ 1, 6, -1, -5, 0, 1 ], [ 0, 6, -1, -5, 0, 1 ] ], 1 ] + ], + [ + [ [ [ 0, 4, -1, -5, 0, 1 ], [ 0, 5, -1, -5, 0, 1 ], [ 1, 6, -1, -5, 0, 1 ], [ 2, 4, -1, -5, 0, 0 ] ], 1 ], + [ [ [ 0, 4, -1, -5, 0, 1 ], [ 1, 4, -2, -5, 0, 1 ], [ 1, 6, -1, -5, 0, 1 ], [ 2, 4, -1, -5, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 4, -1, -5, 0, 1 ], [ 1, 4, -2, -5, 0, 1 ], [ 1, 6, -1, -5, 0, 1 ], [ 1, 6, -1, -5, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 4, -1, -5, 0, 1 ], [ 1, 5, -1, -5, 0, 0 ], [ 1, 6, -1, -5, 0, 1 ], [ 1, 6, -1, -5, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 4, -1, -5, 0, 1 ], [ 1, 4, -1, -5, 0, 1 ], [ 1, 6, -1, -5, 0, 1 ], [ 1, 6, -1, -5, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 5, -1, -5, 0, 1 ], [ 1, 4, -1, -5, 0, 1 ], [ 1, 6, -1, -5, 0, 1 ], [ 1, 6, -1, -5, 0, 0 ] ], 1 ], + [ [ [ -1, 5, -1, -5, 0, 1 ], [ 1, 4, -1, -5, 0, 1 ], [ 3, 4, -1, -5, 0, 0 ], [ 1, 6, -1, -5, 0, 0 ] ], 1 ], + [ [ [ -1, 5, -1, -5, 0, 1 ], [ 1, 4, -1, -5, 0, 1 ], [ 3, 4, -1, -5, 0, 0 ], [ 1, 5, -1, -5, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -1, 5, -1, -5, 0, 1 ], [ 1, 5, -1, -5, -1, 1 ], [ 3, 4, -1, -5, 0, 0 ], [ 1, 5, -1, -5, 0, 1 ] ], 1 ], + [ [ [ 0, 4, -1, -5, 1, 0 ], [ 1, 5, -1, -5, -1, 1 ], [ 3, 4, -1, -5, 0, 0 ], [ 1, 5, -1, -5, 0, 1 ] ], 1 ] + ], + [ + [ [ [ 0, 4, -1, -5, 1, 0 ], [ 1, 5, -1, -5, -1, 1 ], [ 2, 4, -1, -5, -1, 1 ], [ 1, 5, -1, -5, 0, 1 ] ], 1 ], + [ [ [ 0, 4, -1, -5, 1, 0 ], [ 1, 5, -1, -5, -1, 1 ], [ 2, 4, -1, -5, -1, 1 ], [ 0, 5, -1, -4, -1, 1 ] ], 1 ], + [ [ [ -1, 5, -1, -4, -1, 1 ], [ 1, 5, -1, -5, -1, 1 ], [ 2, 4, -1, -5, -1, 1 ], [ 0, 5, -1, -4, -1, 1 ] ], 1 ] + ], + [ + [ [ [ -1, 5, -1, -4, -1, 1 ], [ 1, 5, -1, -5, -1, 1 ], [ 2, 4, -1, -5, -1, 1 ], [ -1, 5, -1, -3, -1, 1 ] ], 1 ], + [ [ [ -1, 5, -1, -4, -1, 1 ], [ 1, 5, -1, -5, -1, 1 ], [ 0, 5, -1, -3, -1, 1 ], [ -1, 5, -1, -3, -1, 1 ] ], 1 ] + ], + [ + [ [ [ -1, 5, -1, -4, -1, 1 ], [ 1, 5, -1, -5, -1, 1 ], [ 1, 5, -1, -4, -1, 1 ], [ -1, 5, -1, -3, -1, 1 ] ], 1 ], + [ [ [ -1, 5, -1, -4, -1, 1 ], [ 1, 5, -1, -5, -1, 1 ], [ 1, 5, -1, -4, -1, 1 ], [ 0, 5, -1, -4, -1, 1 ] ], 1 ] + ], + [ + [ [ [ -1, 5, -1, -4, -1, 1 ], [ 1, 5, -1, -5, -1, 1 ], [ 2, 5, -1, -5, -1, 1 ], [ 0, 5, -1, -4, -1, 1 ] ], 1 ] + ], + [ + [ [ [ -1, 5, -1, -4, -1, 1 ], [ 1, 5, -1, -5, -1, 1 ], [ 2, 5, -1, -5, -1, 1 ], [ 1, 6, -1, -5, -1, 1 ] ], 1 ], + [ [ [ 0, 5, -1, -5, -1, 1 ], [ 1, 5, -1, -5, -1, 1 ], [ 2, 5, -1, -5, -1, 1 ], [ 1, 6, -1, -5, -1, 1 ] ], 1 ], + [ [ [ 0, 5, -1, -5, -1, 1 ], [ 1, 5, -1, -5, -1, 1 ], [ 2, 5, -1, -5, -2, 1 ], [ 1, 6, -1, -5, -1, 1 ] ], 1 ] + ], + [ + [ [ [ 0, 5, -1, -5, -1, 1 ], [ 1, 6, -1, -5, -2, 1 ], [ 2, 5, -1, -5, -2, 1 ], [ 1, 6, -1, -5, -1, 1 ] ], 1 ] + ], + [ + [ [ [ 0, 6, -1, -5, -2, 1 ], [ 1, 6, -1, -5, -2, 1 ], [ 2, 5, -1, -5, -2, 1 ], [ 1, 6, -1, -5, -1, 1 ] ], 1 ] + ], + [ + [ [ [ 0, 6, -1, -5, -2, 1 ], [ 0, 6, -1, -5, -1, 1 ], [ 2, 5, -1, -5, -2, 1 ], [ 1, 6, -1, -5, -1, 1 ] ], 1 ], + [ [ [ 0, 6, -2, -5, -1, 1 ], [ 0, 6, -1, -5, -1, 1 ], [ 2, 5, -1, -5, -2, 1 ], [ 1, 6, -1, -5, -1, 1 ] ], 1 ], + [ [ [ 0, 6, -2, -5, -1, 1 ], [ 0, 6, -1, -5, -1, 1 ], [ 1, 6, -2, -5, -1, 1 ], [ 1, 6, -1, -5, -1, 1 ] ], 1 ] + ], + [ + [ [ [ 0, 6, -2, -5, -1, 1 ], [ 0, 6, -1, -5, -1, 1 ], [ 1, 6, -2, -5, -1, 1 ], [ 2, 5, -2, -5, -1, 1 ] ], 1 ], + [ [ [ -1, 7, -2, -5, -1, 1 ], [ 0, 6, -1, -5, -1, 1 ], [ 1, 6, -2, -5, -1, 1 ], [ 2, 5, -2, -5, -1, 1 ] ], 1 ] + ], + [ + [ [ [ -1, 7, -2, -5, -1, 1 ], [ 0, 6, -1, -5, -1, 1 ], [ 1, 6, -2, -5, -1, 1 ], [ 0, 7, -2, -5, -1, 1 ] ], 1 ], + [ [ [ -1, 7, -2, -5, -1, 1 ], [ 0, 6, -1, -5, -1, 1 ], [ 1, 5, -1, -5, -1, 1 ], [ 0, 7, -2, -5, -1, 1 ] ], 1 ] + ], + [ + [ [ [ -1, 7, -2, -5, -1, 1 ], [ -1, 8, -2, -5, -1, 1 ], [ 1, 5, -1, -5, -1, 1 ], [ 0, 7, -2, -5, -1, 1 ] ], 1 ], + [ [ [ -1, 7, -2, -5, -1, 1 ], [ -1, 8, -2, -5, -1, 1 ], [ 0, 8, -2, -5, -1, 1 ], [ 0, 7, -2, -5, -1, 1 ] ], 1 ] + ], + [ + [ [ [ -2, 8, -2, -5, -1, 1 ], [ -1, 8, -2, -5, -1, 1 ], [ 0, 8, -2, -5, -1, 1 ], [ 0, 7, -2, -5, -1, 1 ] ], 1 ], + [ [ [ -2, 8, -2, -5, -1, 1 ], [ 0, 8, -2, -6, -1, 1 ], [ 0, 8, -2, -5, -1, 1 ], [ 0, 7, -2, -5, -1, 1 ] ], 1 ], + [ [ [ -2, 8, -2, -5, -1, 1 ], [ 0, 8, -2, -6, -1, 1 ], [ 0, 8, -2, -5, -1, 1 ], [ -1, 9, -2, -5, -1, 1 ] ], 1 ] + ], + [ + [ [ [ -1, 8, -2, -6, -1, 1 ], [ 0, 8, -2, -6, -1, 1 ], [ 0, 8, -2, -5, -1, 1 ], [ -1, 9, -2, -5, -1, 1 ] ], 1 ], + [ [ [ -1, 8, -2, -6, -1, 1 ], [ 0, 8, -2, -6, -1, 1 ], [ 0, 8, -2, -5, -1, 1 ], [ 0, 8, -3, -5, -1, 1 ] ], 1 ] + ], + [ + [ [ [ -1, 8, -2, -6, -1, 1 ], [ 0, 8, -2, -6, -1, 1 ], [ 1, 8, -2, -6, -1, 1 ], [ 0, 8, -3, -5, -1, 1 ] ], 1 ] + ], + [ + [ [ [ -1, 8, -2, -6, -1, 1 ], [ 0, 8, -2, -6, -1, 1 ], [ 0, 9, -3, -5, -1, 1 ], [ 0, 8, -3, -5, -1, 1 ] ], 1 ], + [ [ [ -2, 8, -3, -5, -1, 2 ], [ 0, 8, -2, -6, -1, 1 ], [ 0, 9, -3, -5, -1, 1 ], [ 0, 8, -3, -5, -1, 1 ] ], 1 ], + [ [ [ -2, 8, -3, -5, -1, 2 ], [ -1, 8, -3, -5, -1, 2 ], [ 0, 9, -3, -5, -1, 1 ], [ 0, 8, -3, -5, -1, 1 ] ], 1 ] + ], + [ + [ [ [ -2, 8, -3, -5, -1, 2 ], [ -1, 8, -3, -5, -1, 2 ], [ 0, 8, -3, -5, -1, 2 ], [ 0, 8, -3, -5, -1, 1 ] ], 1 ], + [ [ [ -2, 8, -3, -5, -1, 2 ], [ -1, 8, -3, -5, -1, 2 ], [ 0, 8, -3, -5, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -2, 8, -3, -5, -1, 2 ], [ -1, 8, -3, -5, -1, 2 ], [ 1, 8, -3, -6, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ], + [ [ [ -1, 8, -3, -6, -1, 2 ], [ -1, 8, -3, -5, -1, 2 ], [ 1, 8, -3, -6, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 7, -3, -6, -1, 2 ], [ -1, 8, -3, -5, -1, 2 ], [ 1, 8, -3, -6, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ], + [ [ [ -1, 7, -3, -6, -1, 2 ], [ -1, 8, -3, -5, -1, 2 ], [ -1, 8, -2, -5, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 7, -3, -6, -1, 2 ], [ -2, 8, -2, -4, -1, 2 ], [ -1, 8, -2, -5, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ], + [ [ [ -2, 7, -2, -5, -1, 2 ], [ -2, 8, -2, -4, -1, 2 ], [ -1, 8, -2, -5, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -2, 7, -2, -5, -1, 2 ], [ -2, 8, -1, -5, -1, 2 ], [ -1, 8, -2, -5, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -2, 7, -2, -5, -1, 2 ], [ -1, 7, -2, -5, -1, 2 ], [ -1, 8, -2, -5, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ], + [ [ [ -3, 9, -2, -5, -1, 2 ], [ -1, 7, -2, -5, -1, 2 ], [ -1, 8, -2, -5, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -3, 9, -2, -5, -1, 2 ], [ 0, 6, -3, -5, -1, 2 ], [ -1, 8, -2, -5, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ], + [ [ [ -3, 9, -2, -5, -1, 2 ], [ 0, 6, -3, -5, -1, 2 ], [ -1, 8, -3, -5, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ], + [ [ [ -2, 8, -3, -5, -1, 2 ], [ 0, 6, -3, -5, -1, 2 ], [ -1, 8, -3, -5, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -2, 7, -3, -5, -1, 2 ], [ 0, 6, -3, -5, -1, 2 ], [ -1, 8, -3, -5, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ], + [ [ [ -2, 7, -3, -5, -1, 2 ], [ 0, 6, -3, -5, -1, 2 ], [ 0, 7, -4, -5, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 7, -3, -6, -1, 2 ], [ 0, 6, -3, -5, -1, 2 ], [ 0, 7, -4, -5, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ], + [ [ [ -1, 7, -3, -6, -1, 2 ], [ -1, 8, -3, -5, -1, 2 ], [ 0, 7, -4, -5, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ], + [ [ [ -1, 7, -3, -6, -1, 2 ], [ -1, 8, -3, -5, -1, 2 ], [ -1, 7, -3, -4, -1, 2 ], [ 0, 7, -3, -5, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 7, -3, -6, -1, 2 ], [ -1, 8, -3, -5, -1, 2 ], [ -1, 7, -3, -4, -1, 2 ], [ -1, 7, -2, -4, -1, 2 ] ], 1 ], + [ [ [ -1, 7, -3, -6, -1, 2 ], [ -1, 6, -3, -4, -1, 2 ], [ -1, 7, -3, -4, -1, 2 ], [ -1, 7, -2, -4, -1, 2 ] ], 1 ], + [ [ [ -2, 6, -3, -4, -1, 2 ], [ -1, 6, -3, -4, -1, 2 ], [ -1, 7, -3, -4, -1, 2 ], [ -1, 7, -2, -4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -2, 6, -3, -4, -1, 2 ], [ -1, 6, -3, -4, -1, 2 ], [ 0, 6, -4, -4, -1, 2 ], [ -1, 7, -2, -4, -1, 2 ] ], 1 ], + [ [ [ -1, 6, -3, -5, -1, 2 ], [ -1, 6, -3, -4, -1, 2 ], [ 0, 6, -4, -4, -1, 2 ], [ -1, 7, -2, -4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 6, -3, -5, -1, 2 ], [ -1, 6, -3, -4, -1, 2 ], [ -1, 6, -3, -3, -1, 2 ], [ -1, 7, -2, -4, -1, 2 ] ], 1 ], + [ [ [ -1, 5, -3, -4, -1, 2 ], [ -1, 6, -3, -4, -1, 2 ], [ -1, 6, -3, -3, -1, 2 ], [ -1, 7, -2, -4, -1, 2 ] ], 1 ], + [ [ [ -1, 5, -3, -4, -1, 2 ], [ -1, 6, -3, -4, -1, 2 ], [ -1, 6, -3, -3, -1, 2 ], [ 0, 6, -3, -4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 5, -3, -4, -1, 2 ], [ 0, 5, -4, -4, -1, 2 ], [ -1, 6, -3, -3, -1, 2 ], [ 0, 6, -3, -4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 5, -3, -4, -1, 2 ], [ 0, 5, -4, -4, -1, 2 ], [ 0, 5, -3, -4, -1, 2 ], [ 0, 6, -3, -4, -1, 2 ] ], 1 ], + [ [ [ -1, 5, -3, -4, -1, 2 ], [ 0, 5, -4, -4, -1, 2 ], [ 0, 5, -3, -4, -1, 2 ], [ 1, 5, -4, -4, -1, 2 ] ], 1 ], + [ [ [ -1, 5, -3, -4, -1, 2 ], [ -1, 5, -3, -3, -1, 2 ], [ 0, 5, -3, -4, -1, 2 ], [ 1, 5, -4, -4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 5, -3, -4, -1, 2 ], [ 1, 5, -3, -4, -1, 2 ], [ 0, 5, -3, -4, -1, 2 ], [ 1, 5, -4, -4, -1, 2 ] ], 1 ], + [ [ [ -1, 5, -3, -4, -1, 2 ], [ 1, 5, -3, -4, -1, 2 ], [ 0, 5, -3, -4, -1, 2 ], [ 0, 5, -2, -4, -1, 2 ] ], 1 ], + [ [ [ -1, 5, -3, -4, -1, 2 ], [ 1, 5, -3, -4, -1, 2 ], [ 1, 5, -3, -5, -1, 2 ], [ 0, 5, -2, -4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 5, -3, -4, -1, 2 ], [ 1, 5, -3, -4, -1, 2 ], [ 1, 4, -3, -4, -1, 2 ], [ 0, 5, -2, -4, -1, 2 ] ], 1 ], + [ [ [ -1, 5, -3, -4, -1, 2 ], [ 1, 5, -3, -4, -1, 2 ], [ 1, 4, -3, -4, -1, 2 ], [ 0, 5, -3, -4, -1, 2 ] ], 1 ], + [ [ [ -1, 5, -3, -4, -1, 2 ], [ 0, 6, -3, -4, -1, 2 ], [ 1, 4, -3, -4, -1, 2 ], [ 0, 5, -3, -4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ 0, 4, -4, -4, -1, 2 ], [ 0, 6, -3, -4, -1, 2 ], [ 1, 4, -3, -4, -1, 2 ], [ 0, 5, -3, -4, -1, 2 ] ], 1 ], + [ [ [ 0, 4, -4, -4, -1, 2 ], [ 1, 4, -4, -4, -1, 2 ], [ 1, 4, -3, -4, -1, 2 ], [ 0, 5, -3, -4, -1, 2 ] ], 1 ], + [ [ [ 0, 4, -4, -4, -1, 2 ], [ 1, 4, -4, -4, -1, 2 ], [ 1, 4, -3, -4, -1, 2 ], [ 2, 4, -4, -4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ 0, 3, -3, -4, -1, 2 ], [ 1, 4, -4, -4, -1, 2 ], [ 1, 4, -3, -4, -1, 2 ], [ 2, 4, -4, -4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ 0, 3, -4, -4, -1, 2 ], [ 1, 4, -4, -4, -1, 2 ], [ 1, 4, -3, -4, -1, 2 ], [ 2, 4, -4, -4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ 0, 4, -3, -5, -1, 2 ], [ 1, 4, -4, -4, -1, 2 ], [ 1, 4, -3, -4, -1, 2 ], [ 2, 4, -4, -4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ 0, 4, -3, -5, -1, 2 ], [ 1, 4, -4, -4, -1, 2 ], [ 1, 4, -3, -4, -1, 2 ], [ 1, 4, -3, -3, -1, 2 ] ], 1 ], + [ [ [ -1, 4, -2, -4, -1, 2 ], [ 1, 4, -4, -4, -1, 2 ], [ 1, 4, -3, -4, -1, 2 ], [ 1, 4, -3, -3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 4, -2, -4, -1, 2 ], [ 1, 4, -4, -4, -1, 2 ], [ 1, 4, -3, -4, -1, 2 ], [ 1, 5, -2, -4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 4, -2, -4, -1, 2 ], [ 1, 4, -4, -4, -1, 2 ], [ 1, 4, -3, -4, -1, 2 ], [ 1, 4, -2, -4, -1, 2 ] ], 1 ], + [ [ [ -1, 4, -2, -4, -1, 2 ], [ 1, 4, -4, -4, -1, 2 ], [ 2, 3, -4, -4, -1, 2 ], [ 1, 4, -2, -4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 4, -2, -4, -1, 2 ], [ 1, 4, -4, -4, -1, 2 ], [ 2, 3, -4, -4, -1, 2 ], [ 1, 3, -2, -4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 4, -2, -4, -1, 2 ], [ 1, 4, -4, -4, -1, 2 ], [ 2, 3, -4, -4, -1, 2 ], [ 1, 4, -2, -5, -1, 2 ] ], 1 ], + [ [ [ -1, 4, -2, -4, -1, 2 ], [ 0, 4, -2, -4, 0, 2 ], [ 2, 3, -4, -4, -1, 2 ], [ 1, 4, -2, -5, -1, 2 ] ], 1 ], + [ [ [ -1, 4, -2, -4, -1, 2 ], [ 0, 4, -2, -4, 0, 2 ], [ 0, 5, -2, -4, -1, 2 ], [ 1, 4, -2, -5, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 4, -2, -4, -1, 2 ], [ 0, 4, -2, -4, 0, 2 ], [ 1, 4, -2, -4, 0, 1 ], [ 1, 4, -2, -5, -1, 2 ] ], 1 ], + [ [ [ -1, 4, -2, -4, -1, 2 ], [ 0, 4, -2, -4, 0, 2 ], [ 1, 4, -2, -4, 0, 1 ], [ 1, 4, -2, -4, -1, 1 ] ], 1 ] + ], + [ + [ [ [ 0, 3, -2, -4, 0, 1 ], [ 0, 4, -2, -4, 0, 2 ], [ 1, 4, -2, -4, 0, 1 ], [ 1, 4, -2, -4, -1, 1 ] ], 1 ] + ], + [ + [ [ [ -1, 4, -2, -4, 0, 1 ], [ 0, 4, -2, -4, 0, 2 ], [ 1, 4, -2, -4, 0, 1 ], [ 1, 4, -2, -4, -1, 1 ] ], 1 ], + [ [ [ -1, 4, -2, -4, 0, 1 ], [ 0, 4, -2, -4, 0, 2 ], [ 1, 4, -2, -4, 0, 1 ], [ 0, 4, -3, -4, 0, 2 ] ], 1 ], + [ [ [ -1, 4, -2, -4, 0, 1 ], [ 0, 4, -2, -4, 0, 2 ], [ 1, 3, -2, -4, 0, 2 ], [ 0, 4, -3, -4, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 4, -2, -4, 0, 1 ], [ 0, 4, -2, -4, 0, 2 ], [ 0, 5, -2, -4, 0, 2 ], [ 0, 4, -3, -4, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -1, 3, -2, -4, 0, 2 ], [ 0, 4, -2, -4, 0, 2 ], [ 0, 5, -2, -4, 0, 2 ], [ 0, 4, -3, -4, 0, 2 ] ], 1 ], + [ [ [ -1, 3, -2, -4, 0, 2 ], [ "Rest" ], [ 0, 5, -2, -4, 0, 2 ], [ 0, 4, -3, -4, 0, 2 ] ], 1 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 5, -2, -4, 0, 2 ], [ 0, 4, -3, -4, 0, 2 ] ], 1 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 4, -3, -4, 0, 2 ] ], 1 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -1, 4, -2, -4, 0, 1 ], [ 0, 4, -2, -4, 0, 2 ], [ 1, 4, -2, -4, 0, 1 ], [ 1, 4, -2, -4, -1, 1 ] ], + [ [ -1, 4, -2, -4, 0, 1 ], [ 0, 4, -2, -4, 0, 2 ], [ 1, 4, -2, -4, 0, 1 ], [ 0, 4, -3, -4, 0, 2 ] ], + [ [ -1, 4, -2, -4, 0, 1 ], [ 0, 4, -2, -4, 0, 2 ], [ 1, 3, -2, -4, 0, 2 ], [ 0, 4, -3, -4, 0, 2 ] ], + [ [ -1, 4, -2, -4, 0, 1 ], [ 0, 4, -2, -4, 0, 2 ], [ 0, 5, -2, -4, 0, 2 ], [ 0, 4, -3, -4, 0, 2 ] ], + [ [ -1, 3, -2, -4, 0, 2 ], [ 0, 4, -2, -4, 0, 2 ], [ 0, 5, -2, -4, 0, 2 ], [ 0, 4, -3, -4, 0, 2 ] ] +], +"cur_uid": "4ff624b0", +"ref_uid": "nil", +"order_seed": 492048, +"dur_seed": 518010, +"motifs_seed": 626337, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ -1200, 1200, 0.0020576131687243, 0.068181818181818, 0.074074074074074, 0.0625, 0.20576131687243, 0.0625, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61316872427983, 0, 0.98971193415638, 0 ], +"passages_weights": [ 0.48, 0.46, 0.48, 1, 1 ], +"hd_exp": 9, +"hd_invert": 0, +"order": +[ + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 1, 2 ], [ 0, 3 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 1 ], [ 0, 2, 3 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 3, 1 ], [ 2, 0 ], [ ] ], + [ [ 3, 0 ], [ 1, 2 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 2, 0 ], [ 3, 1 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 3 ], [ 0, 2, 1 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 3, 0 ], [ 2, 1 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 0 ], [ 1, 2, 3 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 0, 2 ], [ 3, 1 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 1 ], [ 0, 2, 3 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 0, 3 ], [ 1, 2 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 1, 2 ], [ 0, 3 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 3 ], [ 2, 0, 1 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 100, 100 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/5201b8af_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/5201b8af_code.scd new file mode 100644 index 0000000..c194eef --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/5201b8af_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/5201b8af_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/5201b8af_mus_model.json new file mode 100644 index 0000000..aa90760 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/5201b8af_mus_model.json @@ -0,0 +1,58 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 4.875 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 1, 0, 0, 0 ] ], 4.75 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 4.125 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], + [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ] +], +"cur_uid": "5201b8af", +"ref_uid": "77b0d2dc", +"order_seed": 921767, +"dur_seed": 954688, +"motifs_seed": 995213, +"entrances_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 3.68, 5, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315.1702786378, 338.08049535604 ], [ -200.61919504644, 1452.6315789474 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 8, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "true", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/lilypond/part_I.ly new file mode 100644 index 0000000..01ab702 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/lilypond/part_I.ly @@ -0,0 +1,16 @@ +{ + { r2 c''2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''2. ~ c''8.[ e'16^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'4 ~ e'16[ e'8.^\markup { \pad-markup #0.2 "-41"}] ~ e'2 ~ } + \bar "|" + { e'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/lilypond/part_II.ly new file mode 100644 index 0000000..f176e75 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/lilypond/part_II.ly @@ -0,0 +1,16 @@ +{ + { r2 e'2^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2. ~ e'8.[ e'16^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'4 ~ e'16[ f'8.^\markup { \pad-markup #0.2 "-2"}] ~ f'2 ~ } + \bar "|" + { f'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/lilypond/part_III.ly new file mode 100644 index 0000000..5f83063 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/lilypond/part_III.ly @@ -0,0 +1,16 @@ +{ + { r2 fis'2^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'2. ~ fis'8.[ g'16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'4 ~ g'16[ gis'8.^\markup { \pad-markup #0.2 "+14"}] ~ gis'2 ~ } + \bar "|" + { gis'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/lilypond/part_IV.ly new file mode 100644 index 0000000..67fc5d0 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/5201b8af/lilypond/part_IV.ly @@ -0,0 +1,16 @@ +{ + { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/5488f7e9/5488f7e9_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/5488f7e9/5488f7e9_code.scd new file mode 100644 index 0000000..e5197a1 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/5488f7e9/5488f7e9_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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 = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + if(pDistance < 0, {stepFunc.value(pDistance)}, {0.001}); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/5488f7e9/5488f7e9_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/5488f7e9/5488f7e9_mus_model.json new file mode 100644 index 0000000..cf2a424 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/5488f7e9/5488f7e9_mus_model.json @@ -0,0 +1,163 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ -3, -2, 0, 1, 0, -2 ], [ "Rest" ], [ "Rest" ] ], 0.75 ], + [ [ [ "Rest" ], [ -3, -2, 0, 1, 0, -2 ], [ -3, -1, 0, 0, 0, -1 ], [ "Rest" ] ], 0.75 ], + [ [ [ -3, -1, 0, 1, 0, -2 ], [ -3, -2, 0, 1, 0, -2 ], [ -3, -1, 0, 0, 0, -1 ], [ "Rest" ] ], 0.5 ], + [ [ [ -3, -1, 0, 1, 0, -2 ], [ -3, -2, 0, 1, 0, -2 ], [ -3, -1, 0, 0, 0, -1 ], [ 0, -1, 0, 2, 0, -2 ] ], 0.5 ] + ], + [ + [ [ [ -3, -1, 0, 1, 0, -2 ], [ 0, -1, 0, 1, 0, -1 ], [ -3, -1, 0, 0, 0, -1 ], [ 0, -1, 0, 2, 0, -2 ] ], 0.75 ] + ], + [ + [ [ [ -3, -1, 0, 1, 0, -2 ], [ 2, -1, 0, 2, -1, -2 ], [ -3, -1, 0, 0, 0, -1 ], [ 0, -1, 0, 2, 0, -2 ] ], 0.5 ] + ], + [ + [ [ [ -3, -1, 0, 1, 0, -2 ], [ 2, -1, 0, 2, -1, -2 ], [ 2, -1, 0, 1, 0, -2 ], [ 0, -1, 0, 2, 0, -2 ] ], 0.875 ] + ], + [ + [ [ [ 0, 0, 0, 1, 0, -2 ], [ 2, -1, 0, 2, -1, -2 ], [ 2, -1, 0, 1, 0, -2 ], [ 0, -1, 0, 2, 0, -2 ] ], 0.5 ] + ], + [ + [ [ [ 0, 0, 0, 1, 0, -2 ], [ 2, -1, 0, 2, -1, -2 ], [ 2, -1, 0, 1, 0, -2 ], [ 1, 0, 0, 1, 0, -2 ] ], 0.5 ] + ], + [ + [ [ [ 0, 0, 0, 1, 0, -2 ], [ 2, -1, 0, 2, -1, -2 ], [ 2, -1, 0, 1, 0, -2 ], [ 0, 0, 0, 2, 0, -2 ] ], 1.25 ] + ], + [ + [ [ [ 0, 0, 0, 1, 0, -2 ], [ 2, -1, 0, 2, -1, -2 ], [ 2, -1, 0, 1, 0, -2 ], [ 1, 1, 0, 1, 0, -2 ] ], 0.875 ] + ], + [ + [ [ [ 0, 0, 0, 1, 0, -2 ], [ 2, 0, 0, 1, -1, -2 ], [ 2, -1, 0, 1, 0, -2 ], [ 1, 1, 0, 1, 0, -2 ] ], 1.125 ] + ], + [ + [ [ [ 0, 0, 0, 1, 0, -2 ], [ 2, 0, 0, 1, -1, -2 ], [ 1, 1, 0, 1, 1, -2 ], [ 1, 1, 0, 1, 0, -2 ] ], 0.125 ] + ], + [ + [ [ [ 0, 0, 0, 1, 0, -2 ], [ 0, 1, 0, 1, -1, -2 ], [ 1, 1, 0, 1, 1, -2 ], [ 1, 1, 0, 1, 0, -2 ] ], 0.625 ] + ], + [ + [ [ [ 0, 0, 0, 1, 0, -2 ], [ 0, 1, 0, 1, -1, -2 ], [ 0, 1, -1, 1, 0, -2 ], [ 1, 1, 0, 1, 0, -2 ] ], 1.125 ] + ], + [ + [ [ [ 0, 0, 0, 1, 0, -2 ], [ 0, 1, 0, 1, -1, -2 ], [ 1, 0, 0, 0, 0, -2 ], [ 1, 1, 0, 1, 0, -2 ] ], 0.875 ] + ], + [ + [ [ [ 0, 0, 0, 1, 0, -2 ], [ 0, 1, 0, 1, 0, -3 ], [ 1, 0, 0, 0, 0, -2 ], [ 1, 1, 0, 1, 0, -2 ] ], 0.25 ] + ], + [ + [ [ [ 0, 0, 0, 1, 0, -2 ], [ 2, -1, 0, 1, 0, -2 ], [ 1, 0, 0, 0, 0, -2 ], [ 1, 1, 0, 1, 0, -2 ] ], 1.125 ] + ], + [ + [ [ [ 0, 0, 0, 1, 0, -2 ], [ 2, -1, 0, 1, 0, -2 ], [ 1, -1, 0, 1, -1, -2 ], [ 1, 1, 0, 1, 0, -2 ] ], 0.25 ] + ], + [ + [ [ [ 0, 0, 0, 1, 0, -2 ], [ 1, -1, 0, 2, -1, -2 ], [ 1, -1, 0, 1, -1, -2 ], [ 1, 1, 0, 1, 0, -2 ] ], 0.875 ] + ], + [ + [ [ [ 0, 1, 0, 1, 0, -1 ], [ 1, -1, 0, 2, -1, -2 ], [ 1, -1, 0, 1, -1, -2 ], [ 1, 1, 0, 1, 0, -2 ] ], 0.75 ] + ], + [ + [ [ [ 0, 1, 0, 1, 0, -1 ], [ 1, -1, 0, 2, -1, -2 ], [ -1, 1, 1, 1, 0, -2 ], [ 1, 1, 0, 1, 0, -2 ] ], 0.75 ] + ], + [ + [ [ [ 0, 1, 1, 1, 0, -3 ], [ 1, -1, 0, 2, -1, -2 ], [ -1, 1, 1, 1, 0, -2 ], [ 1, 1, 0, 1, 0, -2 ] ], 1 ] + ], + [ + [ [ [ 0, 1, 1, 1, 0, -3 ], [ 1, -1, 0, 2, -1, -2 ], [ 1, 1, 1, 1, -1, -3 ], [ 1, 1, 0, 1, 0, -2 ] ], 1.125 ] + ], + [ + [ [ [ 0, 1, 1, 1, 0, -3 ], [ 1, -1, 0, 2, -1, -2 ], [ 2, -1, 0, 2, -1, -3 ], [ 1, 1, 0, 1, 0, -2 ] ], 0.375 ] + ], + [ + [ [ [ 2, -1, 0, 3, -1, -3 ], [ 1, -1, 0, 2, -1, -2 ], [ 2, -1, 0, 2, -1, -3 ], [ 1, 1, 0, 1, 0, -2 ] ], 0.75 ] + ], + [ + [ [ [ 2, -1, 0, 3, -1, -3 ], [ 1, -1, 0, 2, -1, -2 ], [ 2, -1, 0, 2, -1, -3 ], [ 3, -1, 0, 1, -1, -2 ] ], 1.125 ] + ], + [ + [ [ [ 2, -1, 0, 3, -1, -3 ], [ 2, -2, 0, 3, -1, -3 ], [ 2, -1, 0, 2, -1, -3 ], [ 3, -1, 0, 1, -1, -2 ] ], 0.375 ] + ], + [ + [ [ [ 2, -1, 0, 3, -1, -3 ], [ 2, -2, 0, 3, -1, -3 ], [ 2, -1, 0, 2, -1, -3 ], [ 2, -2, 1, 3, -1, -3 ] ], 0.625 ] + ], + [ + [ [ [ 2, -1, 0, 3, -1, -3 ], [ 2, -2, 0, 3, -1, -3 ], [ 2, -1, 0, 2, -1, -3 ], [ 2, -2, 0, 2, -1, -3 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, -1, 2, -1, -3 ], [ 2, -2, 0, 3, -1, -3 ], [ 2, -1, 0, 2, -1, -3 ], [ 2, -2, 0, 2, -1, -3 ] ], 1.125 ] + ], + [ + [ [ [ 1, -1, -1, 2, -1, -3 ], [ 2, -2, 0, 3, -1, -3 ], [ 2, -1, 0, 2, -1, -3 ], [ 2, -1, -1, 2, -1, -2 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, -1, 2, -1, -3 ], [ 2, -1, -1, 3, -1, -3 ], [ 2, -1, 0, 2, -1, -3 ], [ 2, -1, -1, 2, -1, -2 ] ], 0.875 ], + [ [ [ "Rest" ], [ 2, -1, -1, 3, -1, -3 ], [ 2, -1, 0, 2, -1, -3 ], [ 2, -1, -1, 2, -1, -2 ] ], 0 ], + [ [ [ "Rest" ], [ 2, -1, -1, 3, -1, -3 ], [ 2, -1, 0, 2, -1, -3 ], [ "Rest" ] ], 0.5 ], + [ [ [ "Rest" ], [ "Rest" ], [ 2, -1, 0, 2, -1, -3 ], [ "Rest" ] ], 0.375 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 6.625 ] + ] + ] +], +"last_changes": +[ + [ [ 2, -1, 0, 3, -1, -3 ], [ 2, -2, 0, 3, -1, -3 ], [ 2, -1, 0, 2, -1, -3 ], [ 2, -2, 1, 3, -1, -3 ] ], + [ [ 2, -1, 0, 3, -1, -3 ], [ 2, -2, 0, 3, -1, -3 ], [ 2, -1, 0, 2, -1, -3 ], [ 2, -2, 0, 2, -1, -3 ] ], + [ [ 1, -1, -1, 2, -1, -3 ], [ 2, -2, 0, 3, -1, -3 ], [ 2, -1, 0, 2, -1, -3 ], [ 2, -2, 0, 2, -1, -3 ] ], + [ [ 1, -1, -1, 2, -1, -3 ], [ 2, -2, 0, 3, -1, -3 ], [ 2, -1, 0, 2, -1, -3 ], [ 2, -1, -1, 2, -1, -2 ] ], + [ [ 1, -1, -1, 2, -1, -3 ], [ 2, -1, -1, 3, -1, -3 ], [ 2, -1, 0, 2, -1, -3 ], [ 2, -1, -1, 2, -1, -2 ] ] +], +"cur_uid": "5488f7e9", +"ref_uid": "7c2de94c", +"order_seed": 199804, +"dur_seed": 927098, +"motifs_seed": 741655, +"entrances_probs_vals": [ 0, 0, 0, 0, 1.2087912087912, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 0, 1.2087912087912, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 0, 1.2087912087912, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1147.9876160991, 1638 ], [ -1240.866873065, 1453 ], [ -980.80495356037, 1768 ], [ -850.77399380805, 1843 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 1, 0.34, 0.98, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ] +], +"sus_weights": [ 0, 0, 0.61 ], +"order_size": [ 30, 30 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/55bd25a1/55bd25a1_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/55bd25a1/55bd25a1_code.scd new file mode 100644 index 0000000..49436ca --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/55bd25a1/55bd25a1_code.scd @@ -0,0 +1,973 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + + + //isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/55bd25a1/55bd25a1_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/55bd25a1/55bd25a1_mus_model.json new file mode 100644 index 0000000..b0cec78 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/55bd25a1/55bd25a1_mus_model.json @@ -0,0 +1,548 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ 7, -5, -2, -1, -3, -2 ], [ "Rest" ], [ "Rest" ] ], 1.125 ], + [ [ [ "Rest" ], [ 7, -5, -2, -1, -3, -2 ], [ "Rest" ], [ 6, -6, -2, 0, -1, -2 ] ], 1.25 ], + [ [ [ 5, -5, -2, 0, -2, -2 ], [ 7, -5, -2, -1, -3, -2 ], [ "Rest" ], [ 6, -6, -2, 0, -1, -2 ] ], 1.25 ], + [ [ [ 5, -5, -2, 0, -2, -2 ], [ 7, -5, -2, -1, -3, -2 ], [ 6, -5, -2, 0, -1, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], 1.5 ] + ], + [ + [ [ [ 5, -5, -2, 0, -2, -2 ], [ 6, -6, -2, 0, -2, -2 ], [ 6, -5, -2, 0, -1, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], 0.625 ], + [ [ [ 5, -5, -2, 0, -2, -2 ], [ 6, -6, -2, 0, -2, -2 ], [ 6, -4, -2, 0, -2, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], 0.5 ] + ], + [ + [ [ [ 4, -3, -2, 0, -2, -2 ], [ 6, -6, -2, 0, -2, -2 ], [ 6, -4, -2, 0, -2, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], 0.625 ], + [ [ [ 4, -3, -2, 0, -2, -2 ], [ 5, -4, -2, 0, -2, -2 ], [ 6, -4, -2, 0, -2, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], 1 ] + ], + [ + [ [ [ 4, -3, -2, 0, -2, -2 ], [ 5, -4, -2, 0, -2, -2 ], [ 7, -4, -2, -1, -2, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], 1 ], + [ [ [ 5, -4, -3, 0, -2, -2 ], [ 5, -4, -2, 0, -2, -2 ], [ 7, -4, -2, -1, -2, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], 0.75 ], + [ [ [ 5, -4, -3, 0, -2, -2 ], [ 5, -4, -2, 0, -2, -2 ], [ 7, -4, -2, -1, -2, -2 ], [ 6, -5, -2, 0, -2, -2 ] ], 0.5 ] + ], + [ + [ [ [ 6, -6, -2, 0, -2, -2 ], [ 5, -4, -2, 0, -2, -2 ], [ 7, -4, -2, -1, -2, -2 ], [ 6, -5, -2, 0, -2, -2 ] ], 0.625 ], + [ [ [ 6, -6, -2, 0, -2, -2 ], [ 6, -5, -3, 0, -2, -2 ], [ 7, -4, -2, -1, -2, -2 ], [ 6, -5, -2, 0, -2, -2 ] ], 1.25 ], + [ [ [ 6, -6, -2, 0, -2, -2 ], [ 6, -5, -3, 0, -2, -2 ], [ 7, -5, -3, 0, -2, -2 ], [ 6, -5, -2, 0, -2, -2 ] ], 1.5 ] + ], + [ + [ [ [ 6, -6, -2, 0, -2, -2 ], [ 6, -5, -3, 0, -2, -2 ], [ 6, -5, -2, 1, -2, -2 ], [ 6, -5, -2, 0, -2, -2 ] ], 0.625 ] + ], + [ + [ [ [ 6, -5, -2, 0, -3, -2 ], [ 6, -5, -3, 0, -2, -2 ], [ 6, -5, -2, 1, -2, -2 ], [ 6, -5, -2, 0, -2, -2 ] ], 0.5 ], + [ [ [ 6, -5, -2, 0, -3, -2 ], [ 5, -5, -2, 1, -2, -2 ], [ 6, -5, -2, 1, -2, -2 ], [ 6, -5, -2, 0, -2, -2 ] ], 0.75 ], + [ [ [ 6, -5, -2, 0, -3, -2 ], [ 5, -5, -2, 1, -2, -2 ], [ 6, -4, -2, 0, -2, -2 ], [ 6, -5, -2, 0, -2, -2 ] ], 0.75 ] + ], + [ + [ [ [ 5, -5, -1, 0, -2, -2 ], [ 5, -5, -2, 1, -2, -2 ], [ 6, -4, -2, 0, -2, -2 ], [ 6, -5, -2, 0, -2, -2 ] ], 0.875 ], + [ [ [ 5, -5, -1, 0, -2, -2 ], [ 5, -4, -2, 0, -2, -2 ], [ 6, -4, -2, 0, -2, -2 ], [ 6, -5, -2, 0, -2, -2 ] ], 0.875 ], + [ [ [ 5, -5, -1, 0, -2, -2 ], [ 5, -4, -2, 0, -2, -2 ], [ 6, -5, -2, 0, -2, -1 ], [ 6, -5, -2, 0, -2, -2 ] ], 0.875 ] + ], + [ + [ [ [ 5, -5, -1, 0, -2, -2 ], [ 5, -4, -2, 0, -2, -2 ], [ 6, -5, -2, 0, -2, -1 ], [ 5, -5, -1, 1, -2, -2 ] ], 1.625 ], + [ [ [ 5, -5, -1, 0, -2, -2 ], [ 6, -6, -1, 0, -2, -2 ], [ 6, -5, -2, 0, -2, -1 ], [ 5, -5, -1, 1, -2, -2 ] ], 0.75 ] + ], + [ + [ [ [ 5, -5, -1, 0, -2, -2 ], [ 6, -6, -1, 0, -2, -2 ], [ 6, -5, -2, 0, -2, -1 ], [ 6, -5, -1, 0, -2, -2 ] ], 1.75 ] + ], + [ + [ [ [ 5, -5, -1, 0, -2, -2 ], [ 5, -4, -1, 0, -2, -2 ], [ 6, -5, -2, 0, -2, -1 ], [ 6, -5, -1, 0, -2, -2 ] ], 1.75 ], + [ [ [ 6, -5, -1, -1, -2, -2 ], [ 5, -4, -1, 0, -2, -2 ], [ 6, -5, -2, 0, -2, -1 ], [ 6, -5, -1, 0, -2, -2 ] ], 1.125 ], + [ [ [ 6, -5, -1, -1, -2, -2 ], [ 5, -4, -1, 0, -2, -2 ], [ 6, -4, -1, 0, -2, -2 ], [ 6, -5, -1, 0, -2, -2 ] ], 1.75 ] + ], + [ + [ [ [ 5, -4, -2, 0, -2, -2 ], [ 5, -4, -1, 0, -2, -2 ], [ 6, -4, -1, 0, -2, -2 ], [ 6, -5, -1, 0, -2, -2 ] ], 0.875 ], + [ [ [ 5, -4, -2, 0, -2, -2 ], [ 5, -4, -1, 0, -2, -2 ], [ 6, -4, -1, 0, -2, -2 ], [ 5, -3, -1, 0, -2, -2 ] ], 1.25 ], + [ [ [ 5, -4, -2, 0, -2, -2 ], [ 6, -4, -1, -1, -2, -2 ], [ 6, -4, -1, 0, -2, -2 ], [ 5, -3, -1, 0, -2, -2 ] ], 1 ] + ], + [ + [ [ [ 5, -5, -1, 0, -2, -2 ], [ 6, -4, -1, -1, -2, -2 ], [ 6, -4, -1, 0, -2, -2 ], [ 5, -3, -1, 0, -2, -2 ] ], 1.25 ] + ], + [ + [ [ [ 4, -3, -1, 0, -2, -2 ], [ 6, -4, -1, -1, -2, -2 ], [ 6, -4, -1, 0, -2, -2 ], [ 5, -3, -1, 0, -2, -2 ] ], 1.5 ], + [ [ [ 4, -3, -1, 0, -2, -2 ], [ 6, -4, -1, -1, -2, -2 ], [ 6, -4, -1, 0, -2, -2 ], [ 6, -4, -2, 0, -2, -2 ] ], 0.75 ] + ], + [ + [ [ [ 4, -3, -1, 0, -2, -2 ], [ 6, -4, -1, 0, -2, -3 ], [ 6, -4, -1, 0, -2, -2 ], [ 6, -4, -2, 0, -2, -2 ] ], 1.375 ] + ], + [ + [ [ [ 4, -3, -1, 0, -2, -2 ], [ 6, -4, -1, 0, -2, -3 ], [ 6, -4, -1, 0, -2, -2 ], [ 4, -4, -1, 1, -2, -2 ] ], 0.75 ], + [ [ [ 5, -4, -2, 0, -2, -2 ], [ 6, -4, -1, 0, -2, -3 ], [ 6, -4, -1, 0, -2, -2 ], [ 4, -4, -1, 1, -2, -2 ] ], 1.375 ], + [ [ [ 5, -4, -2, 0, -2, -2 ], [ 6, -5, -1, 0, -2, -2 ], [ 6, -4, -1, 0, -2, -2 ], [ 4, -4, -1, 1, -2, -2 ] ], 0.375 ] + ], + [ + [ [ [ 4, -4, -1, 1, -3, -2 ], [ 6, -5, -1, 0, -2, -2 ], [ 6, -4, -1, 0, -2, -2 ], [ 4, -4, -1, 1, -2, -2 ] ], 0.5 ], + [ [ [ 4, -4, -1, 1, -3, -2 ], [ 4, -4, -1, 1, -2, -1 ], [ 6, -4, -1, 0, -2, -2 ], [ 4, -4, -1, 1, -2, -2 ] ], 1.625 ], + [ [ [ 4, -4, -1, 1, -3, -2 ], [ 4, -4, -1, 1, -2, -1 ], [ 5, -4, -1, 1, -2, -2 ], [ 4, -4, -1, 1, -2, -2 ] ], 1.5 ] + ], + [ + [ [ [ 4, -4, -1, 1, -3, -2 ], [ 4, -4, -1, 1, -2, -1 ], [ 5, -4, -1, 1, -2, -2 ], [ 5, -4, -1, 0, -2, -2 ] ], 1.25 ], + [ [ [ 4, -4, -1, 1, -3, -2 ], [ 4, -4, -1, 1, -2, -2 ], [ 5, -4, -1, 1, -2, -2 ], [ 5, -4, -1, 0, -2, -2 ] ], 1.625 ], + [ [ [ 4, -4, -2, 1, -2, -2 ], [ 4, -4, -1, 1, -2, -2 ], [ 5, -4, -1, 1, -2, -2 ], [ 5, -4, -1, 0, -2, -2 ] ], 0.5 ] + ], + [ + [ [ [ 4, -4, -2, 1, -2, -2 ], [ 4, -4, -1, 1, -2, -2 ], [ 6, -4, -2, 0, -2, -2 ], [ 5, -4, -1, 0, -2, -2 ] ], 0.875 ], + [ [ [ 4, -4, -2, 1, -2, -2 ], [ 4, -4, -1, 1, -2, -2 ], [ 6, -4, -2, 0, -2, -2 ], [ 4, -4, 0, 1, -2, -2 ] ], 0.875 ] + ], + [ + [ [ [ 4, -4, -2, 1, -2, -2 ], [ 4, -4, -1, 1, -2, -2 ], [ 4, -4, 0, 1, -2, -1 ], [ 4, -4, 0, 1, -2, -2 ] ], 1.75 ], + [ [ [ 3, -4, -1, 2, -2, -2 ], [ 4, -4, -1, 1, -2, -2 ], [ 4, -4, 0, 1, -2, -1 ], [ 4, -4, 0, 1, -2, -2 ] ], 1.625 ] + ], + [ + [ [ [ 3, -4, -1, 2, -2, -2 ], [ 4, -4, -1, 1, -2, -2 ], [ 4, -4, 0, 1, -2, -1 ], [ 3, -4, -1, 2, -2, -1 ] ], 1.375 ], + [ [ [ 3, -4, -1, 2, -2, -2 ], [ 3, -4, 0, 2, -2, -2 ], [ 4, -4, 0, 1, -2, -1 ], [ 3, -4, -1, 2, -2, -1 ] ], 1.625 ], + [ [ [ 3, -4, -1, 2, -2, -2 ], [ 3, -4, 0, 2, -2, -2 ], [ 4, -4, 0, 2, -2, -2 ], [ 3, -4, -1, 2, -2, -1 ] ], 1.5 ] + ], + [ + [ [ [ 3, -5, -1, 2, -2, -1 ], [ 3, -4, 0, 2, -2, -2 ], [ 4, -4, 0, 2, -2, -2 ], [ 3, -4, -1, 2, -2, -1 ] ], 1 ], + [ [ [ 3, -5, -1, 2, -2, -1 ], [ 2, -4, -1, 2, -2, 0 ], [ 4, -4, 0, 2, -2, -2 ], [ 3, -4, -1, 2, -2, -1 ] ], 1.25 ] + ], + [ + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 2, -4, -1, 2, -2, 0 ], [ 4, -4, 0, 2, -2, -2 ], [ 3, -4, -1, 2, -2, -1 ] ], 1.25 ], + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 2, -4, 0, 2, -2, -1 ], [ 4, -4, 0, 2, -2, -2 ], [ 3, -4, -1, 2, -2, -1 ] ], 0.875 ] + ], + [ + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 2, -4, 0, 2, -2, -1 ], [ 4, -5, 0, 2, -2, -1 ], [ 3, -4, -1, 2, -2, -1 ] ], 1.75 ], + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 2, -4, 0, 2, -2, -1 ], [ 4, -5, 0, 2, -2, -1 ], [ 2, -4, 0, 3, -2, -1 ] ], 1.5 ] + ], + [ + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 2, -5, 0, 2, -2, 0 ], [ 4, -5, 0, 2, -2, -1 ], [ 2, -4, 0, 3, -2, -1 ] ], 0.625 ], + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 2, -5, 0, 2, -2, 0 ], [ 4, -5, 0, 2, -2, -1 ], [ 3, -4, 0, 2, -2, -1 ] ], 1.25 ] + ], + [ + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 3, -4, 0, 2, -2, -2 ], [ 4, -5, 0, 2, -2, -1 ], [ 3, -4, 0, 2, -2, -1 ] ], 0.625 ], + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 3, -4, 0, 2, -2, -2 ], [ 4, -5, 0, 2, -2, -1 ], [ 4, -5, 0, 2, -1, -2 ] ], 1.625 ] + ], + [ + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 3, -4, 0, 2, -2, -2 ], [ 4, -5, 0, 2, -2, -1 ], [ 4, -4, 0, 2, -2, -2 ] ], 1.5 ], + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 3, -4, 0, 2, -2, -2 ], [ 3, -4, 0, 2, -2, -1 ], [ 4, -4, 0, 2, -2, -2 ] ], 1.5 ] + ], + [ + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 3, -4, -1, 2, -1, -2 ], [ 3, -4, 0, 2, -2, -1 ], [ 4, -4, 0, 2, -2, -2 ] ], 1.625 ], + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 3, -4, -1, 2, -1, -2 ], [ 4, -5, 0, 2, -1, -2 ], [ 4, -4, 0, 2, -2, -2 ] ], 1.25 ], + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 3, -4, -1, 2, -1, -2 ], [ 4, -5, 0, 2, -1, -2 ], [ 4, -4, 0, 1, -1, -2 ] ], 1.75 ] + ], + [ + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 3, -4, -1, 2, -1, -2 ], [ 3, -3, 0, 2, -1, -2 ], [ 4, -4, 0, 1, -1, -2 ] ], 0.75 ], + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 3, -4, -1, 2, -1, -2 ], [ 3, -3, 0, 2, -1, -2 ], [ 3, -4, 1, 2, -1, -2 ] ], 1.5 ], + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 2, -4, 0, 3, -1, -2 ], [ 3, -3, 0, 2, -1, -2 ], [ 3, -4, 1, 2, -1, -2 ] ], 1 ] + ], + [ + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 2, -4, 0, 3, -1, -2 ], [ 2, -3, 0, 3, -1, -2 ], [ 3, -4, 1, 2, -1, -2 ] ], 1.625 ] + ], + [ + [ [ [ 1, -4, 1, 3, -1, -2 ], [ 2, -4, 0, 3, -1, -2 ], [ 2, -3, 0, 3, -1, -2 ], [ 3, -4, 1, 2, -1, -2 ] ], 1.25 ], + [ [ [ 1, -4, 1, 3, -1, -2 ], [ 2, -4, 0, 3, -1, -2 ], [ 4, -4, 1, 1, -1, -2 ], [ 3, -4, 1, 2, -1, -2 ] ], 0.5 ], + [ [ [ 1, -4, 1, 3, -1, -2 ], [ 2, -3, 1, 2, -1, -2 ], [ 4, -4, 1, 1, -1, -2 ], [ 3, -4, 1, 2, -1, -2 ] ], 1 ] + ], + [ + [ [ [ 1, -4, 1, 3, -1, -2 ], [ 2, -3, 1, 2, -1, -2 ], [ 4, -4, 1, 1, -1, -2 ], [ 2, -2, 1, 2, -1, -2 ] ], 1.5 ], + [ [ [ 1, -4, 1, 3, -1, -2 ], [ 2, -3, 1, 2, -1, -2 ], [ 3, -4, 1, 2, -1, -2 ], [ 2, -2, 1, 2, -1, -2 ] ], 1.125 ] + ], + [ + [ [ [ 1, -4, 1, 3, -1, -2 ], [ 2, -3, 1, 2, -1, -2 ], [ 3, -5, 1, 3, -1, -2 ], [ 2, -2, 1, 2, -1, -2 ] ], 1.125 ] + ], + [ + [ [ [ 1, -4, 1, 3, -1, -2 ], [ 2, -3, 1, 2, -1, -2 ], [ 1, -2, 1, 3, -1, -2 ], [ 2, -2, 1, 2, -1, -2 ] ], 1 ] + ], + [ + [ [ [ 1, -4, 1, 3, -1, -2 ], [ 2, -3, 1, 2, -1, -2 ], [ 2, -4, 2, 3, -1, -2 ], [ 2, -2, 1, 2, -1, -2 ] ], 1.25 ], + [ [ [ 1, -4, 1, 3, -1, -2 ], [ 2, -3, 1, 2, -1, -2 ], [ 2, -4, 2, 3, -1, -2 ], [ 3, -3, 0, 2, -1, -2 ] ], 0.875 ] + ], + [ + [ [ [ 1, -4, 1, 3, -1, -2 ], [ 2, -4, 1, 2, -1, -2 ], [ 2, -4, 2, 3, -1, -2 ], [ 3, -3, 0, 2, -1, -2 ] ], 0.875 ], + [ [ [ 1, -4, 1, 3, -1, -2 ], [ 2, -4, 1, 2, -1, -2 ], [ 3, -4, 1, 2, -1, -2 ], [ 3, -3, 0, 2, -1, -2 ] ], 0.5 ], + [ [ [ 1, -4, 1, 3, -1, -2 ], [ 2, -4, 1, 2, -1, -2 ], [ 3, -4, 1, 2, -1, -2 ], [ 2, -4, 2, 3, -1, -2 ] ], 1.25 ] + ], + [ + [ [ [ 1, -4, 1, 3, -1, -2 ], [ 2, -4, 1, 2, -1, -2 ], [ 3, -4, 1, 2, -1, -2 ], [ 4, -4, 1, 1, -1, -2 ] ], 0.5 ] + ], + [ + [ [ [ 1, -4, 1, 3, -1, -2 ], [ 3, -4, 1, 1, -1, -2 ], [ 3, -4, 1, 2, -1, -2 ], [ 4, -4, 1, 1, -1, -2 ] ], 1.625 ], + [ [ [ 2, -4, 1, 2, -1, -2 ], [ 3, -4, 1, 1, -1, -2 ], [ 3, -4, 1, 2, -1, -2 ], [ 4, -4, 1, 1, -1, -2 ] ], 1.25 ], + [ [ [ 2, -4, 1, 2, -1, -2 ], [ 3, -4, 1, 1, -1, -2 ], [ 3, -4, 1, 2, -1, -2 ], [ 1, -4, 1, 2, -1, -1 ] ], 0.625 ] + ], + [ + [ [ [ 2, -4, 1, 2, -1, -2 ], [ 3, -4, 1, 1, -1, -2 ], [ 3, -4, 1, 2, -1, -2 ], [ 3, -4, 0, 1, -1, -2 ] ], 1 ] + ], + [ + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 3, -4, 1, 1, -1, -2 ], [ 3, -4, 1, 2, -1, -2 ], [ 3, -4, 0, 1, -1, -2 ] ], 1.125 ] + ], + [ + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 3, -4, 1, 1, -1, -2 ], [ 4, -4, 1, 1, -1, -2 ], [ 3, -4, 0, 1, -1, -2 ] ], 1 ] + ], + [ + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 3, -4, 1, 1, -1, -2 ], [ 4, -4, 1, 1, -1, -2 ], [ 2, -4, 1, 2, -1, -2 ] ], 1.625 ], + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 2, -3, 0, 2, -1, -2 ], [ 4, -4, 1, 1, -1, -2 ], [ 2, -4, 1, 2, -1, -2 ] ], 1.625 ], + [ [ [ 2, -4, 0, 2, -1, -2 ], [ 2, -3, 0, 2, -1, -2 ], [ 3, -3, 0, 2, -1, -2 ], [ 2, -4, 1, 2, -1, -2 ] ], 1.375 ] + ], + [ + [ [ [ 1, -2, 0, 2, -1, -2 ], [ 2, -3, 0, 2, -1, -2 ], [ 3, -3, 0, 2, -1, -2 ], [ 2, -4, 1, 2, -1, -2 ] ], 0.625 ], + [ [ [ 1, -2, 0, 2, -1, -2 ], [ 2, -3, 0, 2, -1, -2 ], [ 2, -3, 0, 2, -1, -1 ], [ 2, -4, 1, 2, -1, -2 ] ], 1.375 ] + ], + [ + [ [ [ 1, -2, 0, 2, -1, -2 ], [ 2, -3, 0, 2, -1, -2 ], [ 2, -3, 0, 2, -1, -1 ], [ 2, -2, 0, 2, -1, -3 ] ], 1.375 ], + [ [ [ 1, -2, 0, 2, -1, -2 ], [ 1, -1, 0, 2, -1, -2 ], [ 2, -3, 0, 2, -1, -1 ], [ 2, -2, 0, 2, -1, -3 ] ], 1.375 ] + ], + [ + [ [ [ 0, 0, 0, 2, -1, -2 ], [ 1, -1, 0, 2, -1, -2 ], [ 2, -3, 0, 2, -1, -1 ], [ 2, -2, 0, 2, -1, -3 ] ], 1.25 ], + [ [ [ 0, 0, 0, 2, -1, -2 ], [ 1, -1, 0, 2, -1, -2 ], [ 2, -1, -1, 2, -1, -2 ], [ 2, -2, 0, 2, -1, -3 ] ], 1 ] + ], + [ + [ [ [ 2, -2, -1, 2, -1, -3 ], [ 1, -1, 0, 2, -1, -2 ], [ 2, -1, -1, 2, -1, -2 ], [ 2, -2, 0, 2, -1, -3 ] ], 1.75 ], + [ [ [ 2, -2, -1, 2, -1, -3 ], [ 2, -2, -1, 2, -1, -2 ], [ 2, -1, -1, 2, -1, -2 ], [ 2, -2, 0, 2, -1, -3 ] ], 0.625 ] + ], + [ + [ [ [ 2, -2, -1, 2, -1, -3 ], [ 2, -2, -1, 2, -1, -2 ], [ 2, -1, -1, 2, -1, -2 ], [ 1, -1, -2, 2, -1, -2 ] ], 0.5 ], + [ [ [ 2, -3, -1, 2, -1, -2 ], [ 2, -2, -1, 2, -1, -2 ], [ 2, -1, -1, 2, -1, -2 ], [ 1, -1, -2, 2, -1, -2 ] ], 0.875 ] + ], + [ + [ [ [ 2, -3, -1, 2, -1, -2 ], [ 2, -2, -1, 2, -1, -2 ], [ 3, -2, -2, 2, -1, -2 ], [ 1, -1, -2, 2, -1, -2 ] ], 0.875 ] + ], + [ + [ [ [ 2, -3, -1, 2, -1, -2 ], [ 2, -2, -1, 2, -1, -2 ], [ 3, -2, -2, 2, -1, -2 ], [ 2, -2, -3, 2, -1, -2 ] ], 1.125 ], + [ [ [ 2, -3, -2, 2, -1, -2 ], [ 2, -2, -1, 2, -1, -2 ], [ 3, -2, -2, 2, -1, -2 ], [ 2, -2, -3, 2, -1, -2 ] ], 0.5 ] + ], + [ + [ [ [ 2, -3, -2, 2, -1, -2 ], [ 2, -2, -1, 2, -1, -2 ], [ 2, -2, -1, 3, -1, -2 ], [ 2, -2, -3, 2, -1, -2 ] ], 0.875 ], + [ [ [ 2, -3, -2, 2, -1, -2 ], [ 2, -2, -1, 2, -1, -2 ], [ 2, -2, -1, 3, -1, -2 ], [ 2, -2, -1, 2, -2, -2 ] ], 0.875 ], + [ [ [ 2, -2, -1, 1, -1, -2 ], [ 2, -2, -1, 2, -1, -2 ], [ 2, -2, -1, 3, -1, -2 ], [ 2, -2, -1, 2, -2, -2 ] ], 1.375 ] + ], + [ + [ [ [ 2, -2, -1, 2, -1, -3 ], [ 2, -2, -1, 2, -1, -2 ], [ 2, -2, -1, 3, -1, -2 ], [ 2, -2, -1, 2, -2, -2 ] ], 0.875 ] + ], + [ + [ [ [ 2, -2, -1, 2, -1, -3 ], [ 2, -1, -1, 2, -2, -2 ], [ 2, -2, -1, 3, -1, -2 ], [ 2, -2, -1, 2, -2, -2 ] ], 0.875 ] + ], + [ + [ [ [ 2, -2, -1, 2, -1, -3 ], [ 2, -1, -1, 2, -2, -2 ], [ 3, -2, -1, 2, -2, -2 ], [ 2, -2, -1, 2, -2, -2 ] ], 1.75 ] + ], + [ + [ [ [ 2, -2, -1, 2, -1, -3 ], [ 2, -1, -1, 2, -2, -2 ], [ 4, -2, -1, 1, -2, -2 ], [ 2, -2, -1, 2, -2, -2 ] ], 0.875 ], + [ [ [ 2, -2, -1, 2, -1, -3 ], [ 1, -2, -1, 2, -2, -1 ], [ 4, -2, -1, 1, -2, -2 ], [ 2, -2, -1, 2, -2, -2 ] ], 1.5 ] + ], + [ + [ [ [ 2, -2, -1, 2, -1, -3 ], [ 1, -2, -1, 2, -2, -1 ], [ 4, -2, -1, 1, -2, -2 ], [ 1, -2, -1, 2, -1, -1 ] ], 1.625 ], + [ [ [ 2, -2, -1, 1, -2, -1 ], [ 1, -2, -1, 2, -2, -1 ], [ 4, -2, -1, 1, -2, -2 ], [ 1, -2, -1, 2, -1, -1 ] ], 0.625 ], + [ [ [ 2, -2, -1, 1, -2, -1 ], [ 1, -2, -1, 2, -2, -1 ], [ 3, -2, -1, 1, -2, -1 ], [ 1, -2, -1, 2, -1, -1 ] ], 0.875 ] + ], + [ + [ [ [ 2, -2, -1, 1, -2, -1 ], [ 1, -2, -1, 2, -2, -1 ], [ 4, -2, -1, 0, -2, -1 ], [ 1, -2, -1, 2, -1, -1 ] ], 0.625 ], + [ [ [ 2, -2, -1, 1, -2, -1 ], [ 1, -2, -1, 2, -2, -1 ], [ 4, -2, -1, 0, -2, -1 ], [ 3, -3, -1, 1, -2, -1 ] ], 1.75 ], + [ [ [ 2, -2, -1, 1, -2, -1 ], [ 1, -2, -1, 1, -2, 0 ], [ 4, -2, -1, 0, -2, -1 ], [ 3, -3, -1, 1, -2, -1 ] ], 1.25 ] + ], + [ + [ [ [ 2, -2, -1, 1, -2, -1 ], [ 1, -2, -1, 1, -2, 0 ], [ 4, -2, -1, 0, -2, -1 ], [ 3, -2, 0, 0, -2, -1 ] ], 1.375 ] + ], + [ + [ [ [ 2, -2, -1, 0, -2, 0 ], [ 1, -2, -1, 1, -2, 0 ], [ 4, -2, -1, 0, -2, -1 ], [ 3, -2, 0, 0, -2, -1 ] ], 1.875 ], + [ [ [ 2, -2, -1, 0, -2, 0 ], [ 1, -2, -1, 1, -2, 0 ], [ 4, -2, -1, 0, -2, -1 ], [ 2, -2, -1, 1, -2, 0 ] ], 0.5 ], + [ [ [ 2, -2, -1, 0, -2, 0 ], [ 1, -2, -1, 1, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ] ], 0.875 ] + ], + [ + [ [ [ 2, -2, -1, 0, -2, 0 ], [ 0, 0, -1, 1, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ] ], 1.625 ], + [ [ [ 1, -1, -2, 1, -2, 0 ], [ 0, 0, -1, 1, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ] ], 1.625 ] + ], + [ + [ [ [ 1, -1, -2, 1, -2, 0 ], [ 1, -2, 0, 1, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ] ], 1.5 ] + ], + [ + [ [ [ 1, -1, -2, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ] ], 0.375 ], + [ [ [ 1, -1, -2, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 1, 0, -1, 1, -2, 0 ] ], 1.375 ], + [ [ [ 1, -2, -1, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 1, 0, -1, 1, -2, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, -1, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 1, 0, -1, 1, -2, 0 ] ], 0.5 ] + ], + [ + [ [ [ 0, 0, -1, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ], [ 1, -1, -1, 2, -2, 0 ], [ 1, 0, -1, 1, -2, 0 ] ], 1.125 ] + ], + [ + [ [ [ 0, 0, -1, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 1, 0, -1, 1, -2, 0 ] ], 0.875 ], + [ [ [ -1, 0, -1, 2, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 1, 0, -1, 1, -2, 0 ] ], 1 ], + [ [ [ -1, 0, -1, 2, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 1, -1, -1, 2, -2, 0 ] ], 1.125 ] + ], + [ + [ [ [ -1, 0, -1, 2, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 0, -1, -1, 3, -2, 0 ] ], 0.875 ], + [ [ [ 0, -1, -2, 2, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 0, -1, -1, 3, -2, 0 ] ], 1.625 ] + ], + [ + [ [ [ 1, -1, -2, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 0, -1, -1, 3, -2, 0 ] ], 0.5 ] + ], + [ + [ [ [ 1, -1, -2, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ], [ 1, -1, -1, 2, -2, 0 ], [ 0, -1, -1, 3, -2, 0 ] ], 0.5 ], + [ [ [ 1, -1, -2, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ], [ 1, -1, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ] ], 0.75 ], + [ [ [ -1, -1, -1, 2, -2, 1 ], [ 0, -1, -1, 2, -2, 0 ], [ 1, -1, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ] ], 0.5 ] + ], + [ + [ [ [ -1, -1, -1, 2, -2, 1 ], [ 0, -1, -1, 2, -2, 0 ], [ 1, -1, -1, 1, -2, 1 ], [ 2, -1, -1, 1, -2, 0 ] ], 1.75 ], + [ [ [ -1, -1, -1, 2, -2, 1 ], [ 1, -1, -1, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 1 ], [ 2, -1, -1, 1, -2, 0 ] ], 0.875 ], + [ [ [ 0, 0, -1, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 1 ], [ 2, -1, -1, 1, -2, 0 ] ], 0.5 ] + ], + [ + [ [ [ 0, 0, -1, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 1 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.375 ], + [ [ [ 0, -1, -1, 1, -2, 1 ], [ 1, -1, -1, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 1 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.25 ] + ], + [ + [ [ [ 1, -2, -1, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 1 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.625 ] + ], + [ + [ [ [ 1, -2, -1, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 0 ], [ 1, -1, -1, 2, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 0.75 ] + ], + [ + [ [ [ 1, -2, -1, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.5 ], + [ [ [ 1, -1, -1, 1, -3, 0 ], [ 1, -1, -1, 1, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 0.5 ] + ], + [ + [ [ [ 1, -1, -1, 1, -3, 0 ], [ 1, -1, -1, 1, -2, 0 ], [ 2, -1, -2, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.625 ], + [ [ [ 1, -1, -2, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 0 ], [ 2, -1, -2, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.625 ] + ], + [ + [ [ [ 1, -1, -2, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 0 ], [ 1, -1, -1, 2, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.375 ], + [ [ [ -1, -1, -1, 3, -2, 0 ], [ 1, -1, -1, 1, -2, 0 ], [ 1, -1, -1, 2, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.375 ] + ], + [ + [ [ [ -1, -1, -1, 3, -2, 0 ], [ 1, -2, -1, 2, -2, 0 ], [ 1, -1, -1, 2, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.625 ], + [ [ [ -1, -1, -1, 3, -2, 0 ], [ 1, -2, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.25 ], + [ [ [ -1, -2, -1, 2, -2, 0 ], [ 1, -2, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.75 ] + ], + [ + [ [ [ 0, -2, -1, 1, -2, 0 ], [ 1, -2, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.5 ], + [ [ [ 0, -2, -1, 1, -2, 0 ], [ 1, -2, -1, 2, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 0 ] ], 0.5 ], + [ [ [ 0, -2, -1, 1, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ], [ 2, -1, -1, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 0 ] ], 0.5 ] + ], + [ + [ [ [ 0, -2, -1, 1, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ], [ 1, -2, -1, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 0 ] ], 0.875 ], + [ [ [ 1, -2, -1, 0, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ], [ 1, -2, -1, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 0 ] ], 1.625 ] + ], + [ + [ [ [ 0, -2, -2, 1, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ], [ 1, -2, -1, 1, -2, 0 ], [ 1, -1, -1, 1, -2, 0 ] ], 1.375 ], + [ [ [ 0, -2, -2, 1, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ], [ 2, -2, -1, 0, -2, 0 ], [ 1, -1, -1, 1, -2, 0 ] ], 1.75 ], + [ [ [ 0, -2, -2, 1, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ], [ 2, -2, -1, 0, -2, 0 ], [ 2, -2, -2, 1, -2, 0 ] ], 1.5 ] + ], + [ + [ [ [ 0, -2, -2, 1, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ], [ 1, -1, -2, 1, -2, 0 ], [ 2, -2, -2, 1, -2, 0 ] ], 1.5 ], + [ [ [ 0, -2, -2, 1, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ], [ 1, -1, -2, 1, -2, 0 ], [ 3, -2, -2, 0, -2, 0 ] ], 0.5 ] + ], + [ + [ [ [ 0, -2, -2, 1, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ], [ 1, -1, -2, 1, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], 1.625 ] + ], + [ + [ [ [ -1, 0, -2, 1, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ], [ 1, -1, -2, 1, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], 1 ], + [ [ [ -1, 0, -2, 1, -2, 0 ], [ 2, -2, -1, 1, -2, 0 ], [ 1, -1, -2, 1, -2, 0 ], [ 2, -1, -2, 1, -2, 0 ] ], 1.75 ], + [ [ [ -1, 0, -2, 1, -2, 0 ], [ 1, 0, -2, 1, -2, 0 ], [ 1, -1, -2, 1, -2, 0 ], [ 2, -1, -2, 1, -2, 0 ] ], 1.75 ] + ], + [ + [ [ [ -1, 0, -2, 1, -2, 0 ], [ 1, 0, -2, 1, -2, 0 ], [ 0, 1, -2, 1, -2, 0 ], [ 2, -1, -2, 1, -2, 0 ] ], 0.875 ] + ], + [ + [ [ [ -1, 0, -2, 1, -2, 0 ], [ 0, 2, -2, 1, -2, 0 ], [ 0, 1, -2, 1, -2, 0 ], [ 2, -1, -2, 1, -2, 0 ] ], 0.75 ], + [ [ [ -2, 2, -2, 1, -2, 0 ], [ 0, 2, -2, 1, -2, 0 ], [ 0, 1, -2, 1, -2, 0 ], [ 2, -1, -2, 1, -2, 0 ] ], 0.5 ], + [ [ [ -2, 2, -2, 1, -2, 0 ], [ 0, 2, -2, 1, -2, 0 ], [ 0, 1, -2, 1, -2, 0 ], [ 1, 1, -2, 1, -2, 0 ] ], 0.875 ] + ], + [ + [ [ [ -2, 2, -2, 1, -2, 0 ], [ 0, 2, -2, 1, -2, 0 ], [ -1, 3, -2, 1, -2, 0 ], [ 1, 1, -2, 1, -2, 0 ] ], 1.375 ], + [ [ [ -1, 1, -3, 1, -2, 0 ], [ 0, 2, -2, 1, -2, 0 ], [ -1, 3, -2, 1, -2, 0 ], [ 1, 1, -2, 1, -2, 0 ] ], 1.375 ] + ], + [ + [ [ [ -1, 1, -3, 1, -2, 0 ], [ 0, 2, -2, 1, -2, 0 ], [ -1, 3, -2, 1, -2, 0 ], [ 0, 3, -2, 1, -2, 0 ] ], 1.875 ], + [ [ [ -1, 1, -3, 1, -2, 0 ], [ 0, 2, -2, 1, -2, 0 ], [ 0, 2, -3, 1, -2, 0 ], [ 0, 3, -2, 1, -2, 0 ] ], 1.5 ] + ], + [ + [ [ [ -1, 1, -3, 1, -2, 0 ], [ 1, 1, -3, 1, -2, 0 ], [ 0, 2, -3, 1, -2, 0 ], [ 0, 3, -2, 1, -2, 0 ] ], 0.875 ] + ], + [ + [ [ [ -2, 3, -3, 1, -2, 0 ], [ 1, 1, -3, 1, -2, 0 ], [ 0, 2, -3, 1, -2, 0 ], [ 0, 3, -2, 1, -2, 0 ] ], 1.25 ], + [ [ [ -2, 3, -3, 1, -2, 0 ], [ 1, 1, -3, 1, -2, 0 ], [ 0, 2, -3, 1, -2, 0 ], [ 0, 3, -3, 1, -2, 0 ] ], 1.625 ] + ], + [ + [ [ [ -1, 2, -4, 1, -2, 0 ], [ 1, 1, -3, 1, -2, 0 ], [ 0, 2, -3, 1, -2, 0 ], [ 0, 3, -3, 1, -2, 0 ] ], 0.5 ] + ], + [ + [ [ [ -1, 2, -4, 1, -2, 0 ], [ 1, 1, -3, 1, -2, 0 ], [ 0, 2, -3, 1, -2, 0 ], [ 1, 2, -4, 1, -2, 0 ] ], 1.25 ], + [ [ [ 0, 0, -3, 1, -2, 0 ], [ 1, 1, -3, 1, -2, 0 ], [ 0, 2, -3, 1, -2, 0 ], [ 1, 2, -4, 1, -2, 0 ] ], 1.25 ] + ], + [ + [ [ [ -1, 2, -3, 1, -2, 0 ], [ 1, 1, -3, 1, -2, 0 ], [ 0, 2, -3, 1, -2, 0 ], [ 1, 2, -4, 1, -2, 0 ] ], 0.75 ], + [ [ [ -1, 2, -3, 1, -2, 0 ], [ 1, 1, -3, 1, -2, 0 ], [ 0, 2, -3, 1, -2, 0 ], [ 2, 0, -3, 1, -2, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 2, -3, 1, -2, 0 ], [ 1, 0, -3, 1, -2, 0 ], [ 0, 2, -3, 1, -2, 0 ], [ 2, 0, -3, 1, -2, 0 ] ], 0.75 ], + [ [ [ -1, 2, -3, 1, -2, 0 ], [ 1, 0, -3, 1, -2, 0 ], [ 1, 0, -2, 1, -2, 0 ], [ 2, 0, -3, 1, -2, 0 ] ], 1 ], + [ [ [ 0, 0, -2, 1, -2, 0 ], [ 1, 0, -3, 1, -2, 0 ], [ 1, 0, -2, 1, -2, 0 ], [ 2, 0, -3, 1, -2, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, -2, 1, -2, 0 ], [ 1, 0, -3, 1, -2, 0 ], [ 1, 0, -2, 1, -2, 0 ], [ 1, -1, -2, 1, -2, 0 ] ], 0.5 ], + [ [ [ 0, 0, -2, 1, -2, 0 ], [ 0, 0, -2, 2, -2, 0 ], [ 1, 0, -2, 1, -2, 0 ], [ 1, -1, -2, 1, -2, 0 ] ], 0.75 ], + [ [ [ 0, 0, -2, 1, -2, 0 ], [ 0, 0, -2, 2, -2, 0 ], [ 0, 1, -2, 1, -2, 0 ], [ 1, -1, -2, 1, -2, 0 ] ], 0.625 ] + ], + [ + [ [ [ 0, 0, -2, 1, -2, 0 ], [ 0, 0, -2, 2, -2, 0 ], [ 1, 0, -3, 1, -2, 0 ], [ 1, -1, -2, 1, -2, 0 ] ], 0.75 ] + ], + [ + [ [ [ 0, -1, -2, 2, -2, 0 ], [ 0, 0, -2, 2, -2, 0 ], [ 1, 0, -3, 1, -2, 0 ], [ 1, -1, -2, 1, -2, 0 ] ], 0.625 ], + [ [ [ 0, -1, -2, 2, -2, 0 ], [ 1, 0, -2, 1, -2, 0 ], [ 1, 0, -3, 1, -2, 0 ], [ 1, -1, -2, 1, -2, 0 ] ], 0.875 ] + ], + [ + [ [ [ 0, -1, -2, 2, -2, 0 ], [ 1, 0, -2, 1, -2, 0 ], [ 1, 0, -3, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.625 ], + [ [ [ 0, -1, -2, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ], [ 1, 0, -3, 1, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 0.75 ], + [ [ [ 0, -1, -2, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ], [ 0, 0, -2, 2, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.375 ] + ], + [ + [ [ [ 0, -1, -2, 2, -2, 0 ], [ 1, 0, -2, 2, -3, 0 ], [ 0, 0, -2, 2, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.25 ] + ], + [ + [ [ [ 0, -1, -2, 2, -2, 0 ], [ 1, -1, -1, 2, -2, 0 ], [ 0, 0, -2, 2, -2, 0 ], [ 0, -1, -1, 2, -2, 0 ] ], 1.25 ], + [ [ [ 0, -1, -2, 2, -2, 0 ], [ 1, -1, -1, 2, -2, 0 ], [ 0, 0, -2, 2, -2, 0 ], [ 1, -2, -2, 2, -2, 0 ] ], 0.875 ] + ], + [ + [ [ [ 0, -1, -2, 2, -2, 0 ], [ 1, -1, -1, 2, -2, 0 ], [ 0, 0, -2, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], 1.375 ], + [ [ [ 0, -1, -2, 2, -2, 0 ], [ 1, -1, -1, 2, -2, 0 ], [ 1, -1, -3, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], 0.625 ], + [ [ [ 0, -1, -2, 2, -2, 0 ], [ 2, -2, -2, 2, -2, 0 ], [ 1, -1, -3, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], 1 ] + ], + [ + [ [ [ 1, -2, -3, 2, -2, 0 ], [ 2, -2, -2, 2, -2, 0 ], [ 1, -1, -3, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], 0.875 ], + [ [ [ 1, -2, -3, 2, -2, 0 ], [ 2, -2, -2, 2, -2, 0 ], [ 1, -2, -2, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], 0.75 ] + ], + [ + [ [ [ 1, -2, -3, 2, -2, 0 ], [ 2, -1, -2, 2, -3, 0 ], [ 1, -2, -2, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], 1.125 ], + [ [ [ 1, -2, -3, 2, -2, 0 ], [ 2, -1, -2, 2, -3, 0 ], [ 0, 0, -2, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], 1.5 ], + [ [ [ 1, -1, -2, 1, -2, 0 ], [ 2, -1, -2, 2, -3, 0 ], [ 0, 0, -2, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], 1.625 ], + [ [ [ 1, -1, -2, 1, -2, 0 ], [ "Rest" ], [ 0, 0, -2, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], 1.625 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, -2, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], 1.25 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, -2, 2, -2, 0 ], [ "Rest" ] ], 1.25 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 7.25 ] + ] + ] +], +"last_changes": +[ + [ [ 1, -2, -3, 2, -2, 0 ], [ 2, -2, -2, 2, -2, 0 ], [ 1, -1, -3, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], + [ [ 1, -2, -3, 2, -2, 0 ], [ 2, -2, -2, 2, -2, 0 ], [ 1, -2, -2, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], + [ [ 1, -2, -3, 2, -2, 0 ], [ 2, -1, -2, 2, -3, 0 ], [ 1, -2, -2, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], + [ [ 1, -2, -3, 2, -2, 0 ], [ 2, -1, -2, 2, -3, 0 ], [ 0, 0, -2, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ], + [ [ 1, -1, -2, 1, -2, 0 ], [ 2, -1, -2, 2, -3, 0 ], [ 0, 0, -2, 2, -2, 0 ], [ 1, -1, -2, 2, -2, 0 ] ] +], +"cur_uid": "55bd25a1", +"ref_uid": "6a9928d6", +"order_seed": 807265, +"dur_seed": 754968, +"motifs_seed": 848720, +"entrances_probs_vals": [ 0, 0, 0, 0.41, 1.84, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 0.41, 1.84, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 0.41, 1.84, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2430, -293 ], [ -869, 1211 ], [ -832, 1285 ], [ -702, 1211 ] ], +"step_probs_vals": [ -1200, 1200, 0.0020576131687243, 0.068181818181818, 0.074074074074074, 0.0625, 0.20576131687243, 0.0625, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61316872427983, 0, 0.98971193415638, 0 ], +"passages_weights": [ 0.48, 0.46, 0.48, 1, 1 ], +"hd_exp": 9, +"hd_invert": 0, +"order": +[ + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 3, 0 ], [ 1, 2 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 2, 0 ], [ 3, 1 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 2, 1 ], [ 0, 3 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 3, 1 ], [ 2, 0 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 2, 0 ], [ 1, 3 ], [ ] ], + [ [ 0, 2 ], [ 1, 3 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 0 ], [ 1, 2, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 3 ], [ 0, 2, 1 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 0 ], [ 1, 2, 3 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 0, 2 ], [ 3, 1 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 3, 0 ], [ 2, 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 2 ], [ 1, 3, 0 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 3, 1 ], [ 2, 0 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 1 ], [ 0, 2, 3 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 1, 2 ], [ 0, 3 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 2, 1 ], [ 0, 3 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 2, 0 ], [ 1, 3 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 100, 100 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/55f9b81e/55f9b81e_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/55f9b81e/55f9b81e_code.scd new file mode 100644 index 0000000..2dad11e --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/55f9b81e/55f9b81e_code.scd @@ -0,0 +1,958 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + if(pDistance < 0, {stepFunc.value(abs(pDistance))}, {0.001}); + //stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/55f9b81e/55f9b81e_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/55f9b81e/55f9b81e_mus_model.json new file mode 100644 index 0000000..52fe7d6 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/55f9b81e/55f9b81e_mus_model.json @@ -0,0 +1,443 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ -3, 1, 1, 4, 1, -2 ], [ "Rest" ] ], 1.125 ], + [ [ [ -2, 0, 0, 3, 1, -2 ], [ "Rest" ], [ -3, 1, 1, 4, 1, -2 ], [ "Rest" ] ], 1.75 ], + [ [ [ -2, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -3, 1, 1, 4, 1, -2 ], [ "Rest" ] ], 1.375 ], + [ [ [ -2, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -3, 1, 1, 4, 1, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 1 ] + ], + [ + [ [ [ -2, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -2, 0, 0, 4, 1, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 1.5 ] + ], + [ + [ [ [ -2, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -1, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 0.875 ] + ], + [ + [ [ [ -2, 0, 0, 3, 1, -2 ], [ -3, 1, 2, 4, 1, -2 ], [ -1, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 1.125 ] + ], + [ + [ [ [ -4, 1, 2, 4, 1, -2 ], [ -3, 1, 2, 4, 1, -2 ], [ -1, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 0.75 ] + ], + [ + [ [ [ -4, 1, 1, 4, 2, -2 ], [ -3, 1, 2, 4, 1, -2 ], [ -1, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 1.25 ] + ], + [ + [ [ [ -4, 1, 1, 4, 2, -2 ], [ -2, 0, 1, 4, 1, -2 ], [ -1, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 1.125 ] + ], + [ + [ [ [ -4, 1, 1, 4, 2, -2 ], [ -2, 0, 1, 4, 1, -2 ], [ -3, 1, 2, 4, 1, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 1 ] + ], + [ + [ [ [ -4, 2, 1, 4, 1, -2 ], [ -2, 0, 1, 4, 1, -2 ], [ -3, 1, 2, 4, 1, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 1.75 ] + ], + [ + [ [ [ -4, 2, 1, 4, 1, -2 ], [ -2, 1, 2, 3, 1, -2 ], [ -3, 1, 2, 4, 1, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 1.75 ] + ], + [ + [ [ [ -4, 2, 1, 4, 1, -2 ], [ -2, 1, 2, 3, 1, -2 ], [ -2, 0, 1, 4, 1, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 1.25 ] + ], + [ + [ [ [ -4, 2, 1, 4, 1, -2 ], [ -2, 1, 2, 3, 1, -2 ], [ -2, 1, 1, 4, 0, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 0.875 ] + ], + [ + [ [ [ -2, 1, 1, 3, 0, -2 ], [ -2, 1, 2, 3, 1, -2 ], [ -2, 1, 1, 4, 0, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 1, 3, 0, -2 ], [ -2, 1, 2, 3, 1, -2 ], [ -3, 2, 2, 3, 1, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 1.625 ] + ], + [ + [ [ [ -2, 1, 1, 3, 0, -2 ], [ -2, 2, 2, 3, 0, -2 ], [ -3, 2, 2, 3, 1, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 1, 3, 0, -2 ], [ -2, 2, 2, 3, 0, -2 ], [ -3, 3, 2, 3, 0, -2 ], [ -2, 1, 1, 4, 1, -2 ] ], 1.75 ] + ], + [ + [ [ [ -2, 1, 1, 3, 0, -2 ], [ -2, 2, 2, 3, 0, -2 ], [ -3, 3, 2, 3, 0, -2 ], [ -2, 2, 2, 3, 1, -2 ] ], 1.25 ] + ], + [ + [ [ [ -2, 1, 1, 3, 0, -2 ], [ -2, 2, 2, 3, 0, -2 ], [ -2, 1, 1, 3, 0, -1 ], [ -2, 2, 2, 3, 1, -2 ] ], 1.625 ] + ], + [ + [ [ [ -2, 0, 1, 3, 0, -1 ], [ -2, 2, 2, 3, 0, -2 ], [ -2, 1, 1, 3, 0, -1 ], [ -2, 2, 2, 3, 1, -2 ] ], 1.375 ] + ], + [ + [ [ [ -2, 0, 1, 3, 0, -1 ], [ -2, 2, 2, 3, 0, -2 ], [ -1, 0, 0, 3, 0, -1 ], [ -2, 2, 2, 3, 1, -2 ] ], 1.75 ] + ], + [ + [ [ [ -2, 0, 1, 3, 0, -1 ], [ -2, 2, 2, 3, 0, -2 ], [ -2, 0, 1, 3, 0, 0 ], [ -2, 2, 2, 3, 1, -2 ] ], 1 ] + ], + [ + [ [ [ -2, 0, 1, 3, 0, -1 ], [ -2, 2, 2, 3, 0, -2 ], [ -2, 0, 1, 3, 0, 0 ], [ -1, 2, 2, 3, -1, -2 ] ], 1.375 ] + ], + [ + [ [ [ -2, -1, 1, 3, 0, 0 ], [ -2, 2, 2, 3, 0, -2 ], [ -2, 0, 1, 3, 0, 0 ], [ -1, 2, 2, 3, -1, -2 ] ], 1.375 ] + ], + [ + [ [ [ -2, -1, 1, 3, 0, 0 ], [ -1, 0, 1, 2, 0, 0 ], [ -2, 0, 1, 3, 0, 0 ], [ -1, 2, 2, 3, -1, -2 ] ], 1.625 ] + ], + [ + [ [ [ -2, -1, 1, 3, 0, 0 ], [ -1, 0, 1, 2, 0, 0 ], [ -2, 0, 1, 3, 0, 0 ], [ -2, 0, 1, 3, 0, 1 ] ], 1.25 ] + ], + [ + [ [ [ -2, -1, 1, 3, 0, 0 ], [ -1, 0, 1, 2, 0, 0 ], [ -2, 0, 1, 3, 0, 0 ], [ -2, 0, 1, 4, 0, 0 ] ], 1.625 ] + ], + [ + [ [ [ -2, -1, 1, 3, 0, 0 ], [ -1, 0, 1, 2, 0, 0 ], [ -2, 0, 1, 3, 0, 0 ], [ -1, -1, 1, 3, 1, 0 ] ], 1.25 ] + ], + [ + [ [ [ -2, -1, 1, 3, 0, 0 ], [ -1, 0, 1, 2, 0, 0 ], [ -1, -1, 0, 3, 0, 0 ], [ -1, -1, 1, 3, 1, 0 ] ], 0.75 ] + ], + [ + [ [ [ -2, -1, 1, 3, 0, 0 ], [ -1, 0, 1, 2, 0, 0 ], [ -1, -1, 0, 3, 0, 0 ], [ -1, -1, 0, 4, 0, 0 ] ], 1.125 ] + ], + [ + [ [ [ -1, 0, 1, 2, 0, -1 ], [ -1, 0, 1, 2, 0, 0 ], [ -1, -1, 0, 3, 0, 0 ], [ -1, -1, 0, 4, 0, 0 ] ], 0.875 ] + ], + [ + [ [ [ -1, -1, 1, 2, 0, 0 ], [ -1, 0, 1, 2, 0, 0 ], [ -1, -1, 0, 3, 0, 0 ], [ -1, -1, 0, 4, 0, 0 ] ], 1.625 ] + ], + [ + [ [ [ -2, 0, 0, 3, 0, 0 ], [ -1, 0, 1, 2, 0, 0 ], [ -1, -1, 0, 3, 0, 0 ], [ -1, -1, 0, 4, 0, 0 ] ], 1.5 ] + ], + [ + [ [ [ -2, -1, 0, 4, 0, 0 ], [ -1, 0, 1, 2, 0, 0 ], [ -1, -1, 0, 3, 0, 0 ], [ -1, -1, 0, 4, 0, 0 ] ], 1.625 ] + ], + [ + [ [ [ -2, -1, 0, 4, 0, 0 ], [ -1, -1, 1, 3, 0, 0 ], [ -1, -1, 0, 3, 0, 0 ], [ -1, -1, 0, 4, 0, 0 ] ], 1.75 ] + ], + [ + [ [ [ -2, -1, 0, 4, 0, 0 ], [ -1, -1, 1, 3, 0, 0 ], [ -1, -1, 0, 3, 0, 0 ], [ -1, -1, 1, 4, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, -1, 0, 4, 0, 0 ], [ -1, -1, 1, 3, 0, 0 ], [ -1, -1, 0, 3, 0, 0 ], [ -1, 0, 0, 3, 0, 0 ] ], 1.25 ] + ], + [ + [ [ [ -1, -1, 1, 3, -1, 0 ], [ -1, -1, 1, 3, 0, 0 ], [ -1, -1, 0, 3, 0, 0 ], [ -1, 0, 0, 3, 0, 0 ] ], 0.75 ] + ], + [ + [ [ [ -1, -1, 1, 3, -1, 0 ], [ -1, -1, 1, 3, 0, 0 ], [ -2, -1, 1, 3, 0, 1 ], [ -1, 0, 0, 3, 0, 0 ] ], 1.5 ] + ], + [ + [ [ [ -1, -1, 1, 3, -1, 0 ], [ -1, -1, 1, 3, 0, 0 ], [ -1, 0, 0, 3, -1, 0 ], [ -1, 0, 0, 3, 0, 0 ] ], 1.75 ] + ], + [ + [ [ [ -1, -1, 1, 3, -1, 0 ], [ 0, -1, 1, 3, -2, 0 ], [ -1, 0, 0, 3, -1, 0 ], [ -1, 0, 0, 3, 0, 0 ] ], 1.25 ] + ], + [ + [ [ [ -1, -1, 1, 3, -1, 0 ], [ -1, 0, 1, 3, -1, 0 ], [ -1, 0, 0, 3, -1, 0 ], [ -1, 0, 0, 3, 0, 0 ] ], 1.5 ] + ], + [ + [ [ [ -1, -1, 1, 3, -1, 0 ], [ 0, -1, 0, 3, -1, 0 ], [ -1, 0, 0, 3, -1, 0 ], [ -1, 0, 0, 3, 0, 0 ] ], 1.75 ] + ], + [ + [ [ [ -1, -1, 0, 3, 0, 0 ], [ 0, -1, 0, 3, -1, 0 ], [ -1, 0, 0, 3, -1, 0 ], [ -1, 0, 0, 3, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 0, 0, 3, 1, 0 ], [ 0, -1, 0, 3, -1, 0 ], [ -1, 0, 0, 3, -1, 0 ], [ -1, 0, 0, 3, 0, 0 ] ], 1.375 ] + ], + [ + [ [ [ -2, 0, 0, 3, 1, 0 ], [ 0, -1, 0, 3, -1, 0 ], [ -1, 0, 0, 3, -1, 0 ], [ -1, 1, 0, 3, -1, 0 ] ], 1.875 ] + ], + [ + [ [ [ -2, 1, 0, 3, 0, 0 ], [ 0, -1, 0, 3, -1, 0 ], [ -1, 0, 0, 3, -1, 0 ], [ -1, 1, 0, 3, -1, 0 ] ], 1.375 ] + ], + [ + [ [ [ -2, 1, 0, 3, 0, 0 ], [ 0, -1, 0, 3, -1, 0 ], [ -1, 0, 0, 3, -1, 0 ], [ -1, 0, 0, 3, -1, 1 ] ], 1.75 ] + ], + [ + [ [ [ -2, 1, 0, 3, 0, 0 ], [ 0, -1, 0, 3, -1, 0 ], [ -1, -1, 0, 4, -1, 0 ], [ -1, 0, 0, 3, -1, 1 ] ], 1.625 ] + ], + [ + [ [ [ 0, -1, -1, 3, -1, 0 ], [ 0, -1, 0, 3, -1, 0 ], [ -1, -1, 0, 4, -1, 0 ], [ -1, 0, 0, 3, -1, 1 ] ], 0.625 ] + ], + [ + [ [ [ 0, -1, -1, 3, -1, 0 ], [ 0, -1, 0, 3, -1, 0 ], [ -1, -1, 0, 4, -1, 0 ], [ 1, -2, 0, 3, -1, 0 ] ], 1.125 ] + ], + [ + [ [ [ 0, -1, -1, 3, -1, 0 ], [ 0, -1, 0, 3, -1, 0 ], [ 1, -2, 0, 3, -2, 0 ], [ 1, -2, 0, 3, -1, 0 ] ], 0.75 ] + ], + [ + [ [ [ 1, -3, 0, 3, -1, 0 ], [ 0, -1, 0, 3, -1, 0 ], [ 1, -2, 0, 3, -2, 0 ], [ 1, -2, 0, 3, -1, 0 ] ], 0.875 ] + ], + [ + [ [ [ 1, -3, 0, 3, -1, 0 ], [ 0, -1, 0, 3, -1, 0 ], [ 0, -2, 0, 3, -1, 1 ], [ 1, -2, 0, 3, -1, 0 ] ], 0.875 ] + ], + [ + [ [ [ 1, -3, 0, 3, -1, 0 ], [ 0, -1, 0, 3, -1, 0 ], [ 2, -3, 0, 3, -1, -1 ], [ 1, -2, 0, 3, -1, 0 ] ], 1.375 ] + ], + [ + [ [ [ 1, -2, 0, 3, -2, 0 ], [ 0, -1, 0, 3, -1, 0 ], [ 2, -3, 0, 3, -1, -1 ], [ 1, -2, 0, 3, -1, 0 ] ], 1.125 ] + ], + [ + [ [ [ 1, -2, 0, 3, -2, 0 ], [ 1, -2, -1, 3, -1, 0 ], [ 2, -3, 0, 3, -1, -1 ], [ 1, -2, 0, 3, -1, 0 ] ], 1 ] + ], + [ + [ [ [ 1, -2, 0, 3, -2, 0 ], [ 2, -2, 0, 2, -2, 0 ], [ 2, -3, 0, 3, -1, -1 ], [ 1, -2, 0, 3, -1, 0 ] ], 0.75 ] + ], + [ + [ [ [ 1, -2, 0, 3, -2, 0 ], [ 2, -2, 0, 2, -2, 0 ], [ 0, -2, 0, 4, -1, 0 ], [ 1, -2, 0, 3, -1, 0 ] ], 1.75 ] + ], + [ + [ [ [ 1, -2, 0, 3, -2, 0 ], [ 2, -2, 0, 2, -2, 0 ], [ 0, -2, 0, 4, -1, 0 ], [ 2, -2, 0, 3, -3, 0 ] ], 1.5 ] + ], + [ + [ [ [ 1, -2, 0, 3, -2, 0 ], [ 1, -2, 1, 3, -2, 0 ], [ 0, -2, 0, 4, -1, 0 ], [ 2, -2, 0, 3, -3, 0 ] ], 1.625 ] + ], + [ + [ [ [ 1, -2, 0, 3, -2, 0 ], [ 1, -2, 0, 3, -1, 0 ], [ 0, -2, 0, 4, -1, 0 ], [ 2, -2, 0, 3, -3, 0 ] ], 1 ] + ], + [ + [ [ [ 1, -1, 0, 3, -3, 0 ], [ 1, -2, 0, 3, -1, 0 ], [ 0, -2, 0, 4, -1, 0 ], [ 2, -2, 0, 3, -3, 0 ] ], 1.625 ] + ], + [ + [ [ [ 2, -2, -1, 3, -3, 0 ], [ 1, -2, 0, 3, -1, 0 ], [ 0, -2, 0, 4, -1, 0 ], [ 2, -2, 0, 3, -3, 0 ] ], 0.75 ] + ], + [ + [ [ [ -1, -3, 0, 3, -1, 0 ], [ 1, -2, 0, 3, -1, 0 ], [ 0, -2, 0, 4, -1, 0 ], [ 2, -2, 0, 3, -3, 0 ] ], 1.125 ] + ], + [ + [ [ [ -1, -3, 0, 3, -1, 0 ], [ 1, -2, 0, 3, -1, 0 ], [ 2, -4, 0, 3, -1, 0 ], [ 2, -2, 0, 3, -3, 0 ] ], 0.875 ] + ], + [ + [ [ [ -1, -3, 0, 3, -1, 0 ], [ 1, -3, 0, 3, -1, 1 ], [ 2, -4, 0, 3, -1, 0 ], [ 2, -2, 0, 3, -3, 0 ] ], 1.25 ] + ], + [ + [ [ [ -1, -3, 0, 3, -1, 0 ], [ 1, -3, 0, 3, -1, 1 ], [ 2, -4, 0, 3, -1, 0 ], [ 2, -4, 1, 3, -1, 0 ] ], 0.875 ] + ], + [ + [ [ [ -1, -3, 0, 3, -1, 0 ], [ 1, -3, 0, 3, -1, 1 ], [ 2, -4, 0, 3, -1, 0 ], [ 1, -4, 0, 3, -1, 0 ] ], 1.875 ] + ], + [ + [ [ [ -1, -3, 0, 3, -1, 0 ], [ 2, -4, 1, 3, -1, 0 ], [ 2, -4, 0, 3, -1, 0 ], [ 1, -4, 0, 3, -1, 0 ] ], 1.625 ] + ], + [ + [ [ [ -1, -3, 0, 3, -1, 0 ], [ 0, -4, 0, 3, -1, 0 ], [ 2, -4, 0, 3, -1, 0 ], [ 1, -4, 0, 3, -1, 0 ] ], 0.875 ] + ], + [ + [ [ [ -1, -3, 0, 3, -1, 0 ], [ -1, -2, 0, 3, -1, 0 ], [ 2, -4, 0, 3, -1, 0 ], [ 1, -4, 0, 3, -1, 0 ] ], 1.625 ] + ], + [ + [ [ [ -1, -3, 0, 3, -1, 0 ], [ -1, -2, 0, 3, -1, 0 ], [ 2, -4, 0, 3, -1, 0 ], [ 0, -2, 0, 3, -1, 0 ] ], 1.75 ] + ], + [ + [ [ [ -1, -3, 0, 3, -1, 0 ], [ 0, -3, -1, 3, -1, 0 ], [ 2, -4, 0, 3, -1, 0 ], [ 0, -2, 0, 3, -1, 0 ] ], 0.875 ] + ], + [ + [ [ [ -2, -2, 0, 3, 0, 0 ], [ 0, -3, -1, 3, -1, 0 ], [ 2, -4, 0, 3, -1, 0 ], [ 0, -2, 0, 3, -1, 0 ] ], 0.625 ] + ], + [ + [ [ [ -1, -4, 0, 3, -1, 1 ], [ 0, -3, -1, 3, -1, 0 ], [ 2, -4, 0, 3, -1, 0 ], [ 0, -2, 0, 3, -1, 0 ] ], 0.875 ] + ], + [ + [ [ [ -1, -4, 0, 3, -1, 1 ], [ 1, -5, 0, 3, -1, 0 ], [ 2, -4, 0, 3, -1, 0 ], [ 0, -2, 0, 3, -1, 0 ] ], 1.375 ] + ], + [ + [ [ [ -1, -4, 0, 3, -1, 1 ], [ 1, -5, 0, 3, -1, 0 ], [ 2, -4, 0, 3, -1, 0 ], [ 1, -5, 0, 4, -1, 0 ] ], 1.625 ] + ], + [ + [ [ [ -1, -4, 0, 3, -1, 1 ], [ 1, -5, 0, 3, -1, 0 ], [ 2, -4, 0, 3, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 1 ] + ], + [ + [ [ [ 1, -6, 0, 3, -1, 0 ], [ 1, -5, 0, 3, -1, 0 ], [ 2, -4, 0, 3, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 0.625 ] + ], + [ + [ [ [ 1, -6, 0, 3, -1, 0 ], [ 1, -5, 0, 3, -1, 0 ], [ 3, -5, -1, 3, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 0.625 ] + ], + [ + [ [ [ 1, -6, 0, 3, -1, 0 ], [ 1, -5, 0, 3, -1, 0 ], [ 3, -6, 1, 3, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 1.625 ] + ], + [ + [ [ [ 0, -6, 1, 3, -1, 1 ], [ 1, -5, 0, 3, -1, 0 ], [ 3, -6, 1, 3, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 1.25 ] + ], + [ + [ [ [ 0, -6, 1, 3, -1, 1 ], [ 0, -5, 1, 3, -1, 1 ], [ 3, -6, 1, 3, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 0.75 ] + ], + [ + [ [ [ 0, -6, 1, 4, -1, 0 ], [ 0, -5, 1, 3, -1, 1 ], [ 3, -6, 1, 3, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 0.75 ] + ], + [ + [ [ [ 0, -6, 1, 4, -1, 0 ], [ 0, -5, 1, 4, -1, 0 ], [ 3, -6, 1, 3, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 0.875 ] + ], + [ + [ [ [ 0, -6, 1, 4, -1, 0 ], [ 0, -5, 1, 4, -1, 0 ], [ 2, -6, 2, 4, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 1 ] + ], + [ + [ [ [ 0, -6, 1, 4, -1, 0 ], [ 0, -5, 1, 4, -1, 0 ], [ 3, -7, 1, 4, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 1 ] + ], + [ + [ [ [ 0, -6, 1, 4, -1, 0 ], [ 2, -7, 1, 3, -1, 0 ], [ 3, -7, 1, 4, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 1.25 ] + ], + [ + [ [ [ 1, -7, 0, 4, -1, 0 ], [ 2, -7, 1, 3, -1, 0 ], [ 3, -7, 1, 4, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 0.625 ] + ], + [ + [ [ [ 0, -7, 1, 5, -1, 0 ], [ 2, -7, 1, 3, -1, 0 ], [ 3, -7, 1, 4, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 0.75 ] + ], + [ + [ [ [ 0, -7, 1, 5, -1, 0 ], [ 2, -7, 1, 3, -1, 0 ], [ 4, -7, 1, 2, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 1 ] + ], + [ + [ [ [ 0, -7, 1, 5, -1, 0 ], [ 2, -5, 0, 3, -1, -1 ], [ 4, -7, 1, 2, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 1.625 ] + ], + [ + [ [ [ 3, -7, 1, 2, -2, 0 ], [ 2, -5, 0, 3, -1, -1 ], [ 4, -7, 1, 2, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 1.75 ] + ], + [ + [ [ [ 3, -7, 1, 2, -2, 0 ], [ 2, -5, 0, 3, -1, -1 ], [ 5, -7, 1, 2, -3, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 0.875 ] + ], + [ + [ [ [ 3, -7, 1, 2, -2, 0 ], [ 2, -5, 0, 3, -1, -1 ], [ 2, -3, 0, 3, -1, -1 ], [ 2, -4, 0, 3, -1, -1 ] ], 1.25 ] + ], + [ + [ [ [ 3, -7, 1, 2, -2, 0 ], [ 2, -5, 0, 3, -1, -1 ], [ 2, -4, 0, 3, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 1.75 ] + ], + [ + [ [ [ 2, -5, -1, 3, -1, -1 ], [ 2, -5, 0, 3, -1, -1 ], [ 2, -4, 0, 3, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], 1.625 ] + ], + [ + [ [ [ 2, -5, -1, 3, -1, -1 ], [ 2, -5, 0, 3, -1, -1 ], [ 2, -4, 0, 3, -1, 0 ], [ 3, -5, -1, 3, -1, -1 ] ], 1.25 ] + ], + [ + [ [ [ 2, -5, -1, 3, -1, -1 ], [ 2, -5, 0, 3, -1, -1 ], [ 2, -4, 0, 3, -1, 0 ], [ 2, -5, 0, 4, -1, -1 ] ], 1.375 ] + ], + [ + [ [ [ 2, -5, -1, 3, -1, -1 ], [ 2, -5, 0, 3, -1, -1 ], [ 2, -4, 0, 3, -1, 0 ], [ 4, -5, -1, 2, -1, -1 ] ], 1.625 ], + [ [ [ "Rest" ], [ 2, -5, 0, 3, -1, -1 ], [ 2, -4, 0, 3, -1, 0 ], [ 4, -5, -1, 2, -1, -1 ] ], 1.125 ], + [ [ [ "Rest" ], [ 2, -5, 0, 3, -1, -1 ], [ "Rest" ], [ 4, -5, -1, 2, -1, -1 ] ], 1.75 ], + [ [ [ "Rest" ], [ 2, -5, 0, 3, -1, -1 ], [ "Rest" ], [ "Rest" ] ], 1.5 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.0 ] + ] + ] +], +"last_changes": +[ + [ [ 3, -7, 1, 2, -2, 0 ], [ 2, -5, 0, 3, -1, -1 ], [ 2, -4, 0, 3, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], + [ [ 2, -5, -1, 3, -1, -1 ], [ 2, -5, 0, 3, -1, -1 ], [ 2, -4, 0, 3, -1, 0 ], [ 2, -4, 0, 3, -1, -1 ] ], + [ [ 2, -5, -1, 3, -1, -1 ], [ 2, -5, 0, 3, -1, -1 ], [ 2, -4, 0, 3, -1, 0 ], [ 3, -5, -1, 3, -1, -1 ] ], + [ [ 2, -5, -1, 3, -1, -1 ], [ 2, -5, 0, 3, -1, -1 ], [ 2, -4, 0, 3, -1, 0 ], [ 2, -5, 0, 4, -1, -1 ] ], + [ [ 2, -5, -1, 3, -1, -1 ], [ 2, -5, 0, 3, -1, -1 ], [ 2, -4, 0, 3, -1, 0 ], [ 4, -5, -1, 2, -1, -1 ] ] +], +"cur_uid": "55f9b81e", +"ref_uid": "726a40c7", +"order_seed": 540514, +"dur_seed": 331257, +"motifs_seed": 728928, +"entrances_probs_vals": [ 0, 0, 0, 0.66, 1.8406593406593, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 0.66, 1.8406593406593, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 0.66, 1.8406593406593, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2467, 2400 ], [ -1167, 2400 ], [ -702, 2400 ], [ -702, 2400 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.090534979423868, 0.92613636363636, 0.17489711934156, 0.079545454545455, 0.37037037037037, 0, 0.7201646090535, 0, 1, 0 ], +"passages_weights": [ 0.63, 0.62, 1, 0.41, 1 ], +"hd_exp": 3.09, +"hd_invert": 0, +"order": +[ + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ] +], +"sus_weights": [ 0, 0, 0.61 ], +"order_size": [ 100, 100 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/577cf188/577cf188_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/577cf188/577cf188_code.scd new file mode 100644 index 0000000..5a3854b --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/577cf188/577cf188_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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 = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/577cf188/577cf188_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/577cf188/577cf188_mus_model.json new file mode 100644 index 0000000..b37c8be --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/577cf188/577cf188_mus_model.json @@ -0,0 +1,198 @@ +{ +"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 ], + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 2.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 ] ], 1.875 ] + ], + [ + [ [ [ 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.5 ] + ], + [ + [ [ [ 0, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.125 ] + ], + [ + [ [ [ 1, -2, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.625 ] + ], + [ + [ [ [ 0, -1, 1, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 2.5 ] + ], + [ + [ [ [ 0, -1, 1, 0, -1, 0 ], [ 0, 0, 1, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 2 ] + ], + [ + [ [ [ 0, -1, 1, 0, -1, 0 ], [ 0, -1, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 2.625 ] + ], + [ + [ [ [ 0, -1, 1, 0, -1, 0 ], [ 0, -1, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 1.125 ] + ], + [ + [ [ [ 0, -1, 1, 0, -1, 0 ], [ 0, -1, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, -1, 0 ] ], 1.875 ] + ], + [ + [ [ [ -1, 0, 2, 0, -1, 0 ], [ 0, -1, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, -1, 0 ] ], 1.125 ] + ], + [ + [ [ [ 0, -2, 1, 0, 0, 0 ], [ 0, -1, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, -1, 0 ] ], 1.625 ] + ], + [ + [ [ [ 0, -2, 1, 0, 0, 0 ], [ 0, -1, 1, 0, 0, 0 ], [ 0, -2, 1, 1, 0, 0 ], [ 0, 0, 1, 0, -1, 0 ] ], 1.375 ] + ], + [ + [ [ [ 0, -2, 1, 0, 0, 0 ], [ 0, -1, 1, 0, 0, 0 ], [ 1, -1, 1, -1, 0, 0 ], [ 0, 0, 1, 0, -1, 0 ] ], 1.875 ] + ], + [ + [ [ [ 0, 0, 1, -1, -1, 0 ], [ 0, -1, 1, 0, 0, 0 ], [ 1, -1, 1, -1, 0, 0 ], [ 0, 0, 1, 0, -1, 0 ] ], 2.5 ] + ], + [ + [ [ [ 0, 0, 1, -1, -1, 0 ], [ -1, 0, 1, 1, -1, 0 ], [ 1, -1, 1, -1, 0, 0 ], [ 0, 0, 1, 0, -1, 0 ] ], 2 ] + ], + [ + [ [ [ 0, 0, 1, -1, -1, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 1, -1, 1, -1, 0, 0 ], [ 0, 0, 1, 0, -1, 0 ] ], 1.25 ] + ], + [ + [ [ [ 0, 0, 1, -1, -1, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 1, -1, 1, -1, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ] ], 2 ] + ], + [ + [ [ [ 0, 0, 1, -1, -1, 0 ], [ 1, 0, 2, -1, 0, 0 ], [ 1, -1, 1, -1, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ] ], 2.5 ] + ], + [ + [ [ [ 0, 0, 1, -1, -1, 0 ], [ 1, 0, 2, -1, 0, 0 ], [ 0, 0, 2, -1, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ] ], 2.375 ] + ], + [ + [ [ [ 0, 0, 1, -1, -1, 0 ], [ 1, 0, 2, -1, 0, 0 ], [ 0, 0, 2, -1, 0, 0 ], [ 0, 1, 2, -1, 0, 0 ] ], 2.125 ] + ], + [ + [ [ [ 0, 0, 1, -1, -1, 0 ], [ 1, 0, 2, -1, 0, 0 ], [ 0, 0, 1, -1, -1, 1 ], [ 0, 1, 2, -1, 0, 0 ] ], 1.375 ] + ], + [ + [ [ [ 0, 0, 1, -1, -1, 0 ], [ 1, 0, 2, -1, 0, 0 ], [ 0, 1, 2, -1, 0, -1 ], [ 0, 1, 2, -1, 0, 0 ] ], 1.25 ] + ], + [ + [ [ [ 0, 1, 2, -1, 0, -2 ], [ 1, 0, 2, -1, 0, 0 ], [ 0, 1, 2, -1, 0, -1 ], [ 0, 1, 2, -1, 0, 0 ] ], 2.875 ] + ], + [ + [ [ [ 0, 1, 2, -1, 0, -2 ], [ 1, 1, 2, -1, 0, -1 ], [ 0, 1, 2, -1, 0, -1 ], [ 0, 1, 2, -1, 0, 0 ] ], 2.5 ] + ], + [ + [ [ [ 0, 1, 2, -1, 0, -2 ], [ 1, 1, 2, -1, 0, -1 ], [ 0, 1, 2, -1, 0, -1 ], [ 2, 1, 2, -1, 0, -3 ] ], 1.875 ] + ], + [ + [ [ [ 0, 1, 2, -1, 0, -2 ], [ 3, 1, 2, -1, 0, -4 ], [ 0, 1, 2, -1, 0, -1 ], [ 2, 1, 2, -1, 0, -3 ] ], 1.375 ] + ], + [ + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 3, 1, 2, -1, 0, -4 ], [ 0, 1, 2, -1, 0, -1 ], [ 2, 1, 2, -1, 0, -3 ] ], 2.25 ] + ], + [ + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 3, 1, 2, -1, 0, -4 ], [ 0, 1, 2, -1, 0, -1 ], [ 2, 2, 2, -1, 0, -4 ] ], 2 ] + ], + [ + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 3, 1, 2, -1, 0, -4 ], [ 0, 1, 2, -1, 0, -1 ], [ 2, 1, 2, -3, 0, -1 ] ], 2 ] + ], + [ + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 3, 1, 2, -1, 0, -4 ], [ 0, 1, 2, -1, 0, -1 ], [ 0, 1, 3, -1, 0, -1 ] ], 2 ] + ], + [ + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 2, 2, -2, 0, -1 ], [ 0, 1, 2, -1, 0, -1 ], [ 0, 1, 3, -1, 0, -1 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 2, 2, -2, 0, -1 ], [ 2, 1, 2, -3, 0, -1 ], [ 0, 1, 3, -1, 0, -1 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 2, 2, -2, 0, -1 ], [ 2, 1, 2, -3, 0, -1 ], [ 2, 1, 1, -2, 0, -1 ] ], 2.625 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 2, 1, 2, -2, -1, -1 ], [ 2, 1, 2, -3, 0, -1 ], [ 2, 1, 1, -2, 0, -1 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 2, 1, 2, -2, -1, -1 ], [ 1, 1, 2, -1, 0, -1 ], [ 2, 1, 1, -2, 0, -1 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 2, 1, 2, -2, -1, -1 ], [ 1, 1, 2, -1, 0, -1 ], [ 3, 1, 2, -3, 0, -1 ] ], 1.625 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, 1, -1 ], [ 1, 1, 2, -1, 0, -1 ], [ 3, 1, 2, -3, 0, -1 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, 1, -1 ], [ 1, 1, 2, -2, 0, 0 ], [ 3, 1, 2, -3, 0, -1 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, 1, -1 ], [ 1, 1, 2, -2, 0, 0 ], [ 1, 1, 3, -2, 0, -1 ] ], 1.75 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 2, 0, 2, -2, 0, -1 ], [ 1, 1, 2, -2, 0, 0 ], [ 1, 1, 3, -2, 0, -1 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 2, 0, 2, -2, 0, -1 ], [ 1, 2, 2, -2, 0, -1 ], [ 1, 1, 3, -2, 0, -1 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 2, 0, 2, -2, 0, -1 ], [ 1, 2, 2, -2, 0, -1 ], [ 2, 1, 2, -2, 0, -2 ] ], 1.375 ] + ], + [ + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 0, 2, 2, -1, 0, -1 ], [ 1, 2, 2, -2, 0, -1 ], [ 2, 1, 2, -2, 0, -2 ] ], 1.625 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 0, 2, 2, -2, 0, 0 ], [ 1, 2, 2, -2, 0, -1 ], [ 2, 1, 2, -2, 0, -2 ] ], 1.625 ] + ], + [ + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 2, 1, 2, -3, 0, -1 ], [ 1, 2, 2, -2, 0, -1 ], [ 2, 1, 2, -2, 0, -2 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 2, 1, 2, -3, 0, -1 ], [ 2, 1, 2, -2, -1, -1 ], [ 2, 1, 2, -2, 0, -2 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 2, 1, 2, -3, 0, -1 ], [ 2, 1, 2, -2, -1, -1 ], [ 3, 1, 2, -2, 0, -2 ] ], 2.625 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 0, 2, 2, -2, 0, -1 ], [ 2, 1, 2, -2, -1, -1 ], [ 3, 1, 2, -2, 0, -2 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 0, 2, 2, -2, 0, -1 ], [ 1, 1, 2, -2, 1, -1 ], [ 3, 1, 2, -2, 0, -2 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 0, 2, 2, -2, 0, -1 ], [ 1, 1, 2, -2, 1, -1 ], [ 3, 1, 2, -3, 0, -1 ] ], 2.125 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, -1, -1 ], [ 1, 1, 2, -2, 1, -1 ], [ 3, 1, 2, -3, 0, -1 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, -1, -1 ], [ 2, 0, 2, -2, 0, -1 ], [ 3, 1, 2, -3, 0, -1 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, -1, -1 ], [ 2, 0, 2, -2, 0, -1 ], [ 2, 1, 2, -2, 0, -1 ] ], 1.5 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, 0, -1 ], [ 2, 0, 2, -2, 0, -1 ], [ 2, 1, 2, -2, 0, -1 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, 0, -1 ], [ 1, 1, 3, -2, 0, -1 ], [ 2, 1, 2, -2, 0, -1 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, 0, -1 ], [ 1, 1, 3, -2, 0, -1 ], [ 2, 1, 3, -2, 0, -1 ] ], 2.25 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, 0, -1 ], [ "Rest" ], [ 2, 1, 3, -2, 0, -1 ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, 0, -1 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ 0, 1, 2, -2, 0, -1 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 7.0 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, -1, -1 ], [ 2, 0, 2, -2, 0, -1 ], [ 3, 1, 2, -3, 0, -1 ] ], + [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, -1, -1 ], [ 2, 0, 2, -2, 0, -1 ], [ 2, 1, 2, -2, 0, -1 ] ], + [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, 0, -1 ], [ 2, 0, 2, -2, 0, -1 ], [ 2, 1, 2, -2, 0, -1 ] ], + [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, 0, -1 ], [ 1, 1, 3, -2, 0, -1 ], [ 2, 1, 2, -2, 0, -1 ] ], + [ [ 0, 1, 2, -2, 0, -1 ], [ 1, 1, 2, -2, 0, -1 ], [ 1, 1, 3, -2, 0, -1 ], [ 2, 1, 3, -2, 0, -1 ] ] +], +"cur_uid": "577cf188", +"ref_uid": "nil", +"order_seed": 755225, +"dur_seed": 543380, +"motifs_seed": 119394, +"entrances_probs_vals": [ 1, 0, 0, 1.1263736263736, 2.83, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0, 1.1263736263736, 2.83, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0, 1.1263736263736, 2.83, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1315, 1582.6625386997 ], [ -702.16718266254, 1453 ], [ -386, 1676 ], [ -219, 1694 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 1, 1, 0.66, 0.74, 1 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 0 ], [ 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3 ], [ ] ], + [ [ 3, 2, 1 ], [ 1 ], [ ] ], + [ [ 0 ], [ 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3 ], [ ] ] +], +"sus_weights": [ 0, 0, 0.51 ], +"order_size": [ 30, 30 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/5ec14635/5ec14635_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/5ec14635/5ec14635_code.scd new file mode 100644 index 0000000..f822edb --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/5ec14635/5ec14635_code.scd @@ -0,0 +1,946 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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 = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + if(pDistance < 0, {stepFunc.value(abs(pDistance))}, {0.001}); + //stepFunc.value(pDistance) +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/5ec14635/5ec14635_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/5ec14635/5ec14635_mus_model.json new file mode 100644 index 0000000..c4309f6 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/5ec14635/5ec14635_mus_model.json @@ -0,0 +1,163 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ -2, -1, 0, 0, 0, -1 ], [ "Rest" ] ], 0.375 ], + [ [ [ "Rest" ], [ -2, -2, 0, 1, 0, -2 ], [ -2, -1, 0, 0, 0, -1 ], [ "Rest" ] ], 0 ], + [ [ [ -2, -1, 0, 1, 0, -2 ], [ -2, -2, 0, 1, 0, -2 ], [ -2, -1, 0, 0, 0, -1 ], [ "Rest" ] ], 0.5 ], + [ [ [ -2, -1, 0, 1, 0, -2 ], [ -2, -2, 0, 1, 0, -2 ], [ -2, -1, 0, 0, 0, -1 ], [ 1, -2, 0, 2, 0, -2 ] ], 0.125 ] + ], + [ + [ [ [ -2, -1, 0, 1, 0, -2 ], [ -2, -2, 0, 1, 0, -2 ], [ 0, 0, 0, 1, 0, -2 ], [ 1, -2, 0, 2, 0, -2 ] ], 1 ] + ], + [ + [ [ [ -2, -1, 0, 1, 0, -2 ], [ -2, -2, 0, 1, 0, -2 ], [ 0, 0, 0, 1, 0, -2 ], [ 0, 0, 0, 1, 0, -1 ] ], 1.125 ] + ], + [ + [ [ [ -2, -1, 0, 1, 0, -2 ], [ -1, 1, 0, 1, 0, -1 ], [ 0, 0, 0, 1, 0, -2 ], [ 0, 0, 0, 1, 0, -1 ] ], 1.125 ] + ], + [ + [ [ [ -2, -1, 0, 1, 0, -2 ], [ 0, 0, 1, 1, 0, -2 ], [ 0, 0, 0, 1, 0, -2 ], [ 0, 0, 0, 1, 0, -1 ] ], 0.125 ] + ], + [ + [ [ [ -2, -1, 0, 1, 0, -2 ], [ 0, 0, 1, 1, 0, -2 ], [ -1, 0, 1, 1, 0, -1 ], [ 0, 0, 0, 1, 0, -1 ] ], 0.75 ] + ], + [ + [ [ [ -2, -1, 0, 1, 0, -2 ], [ 0, 0, 1, 1, 0, -2 ], [ -1, 0, 1, 2, 0, -2 ], [ 0, 0, 0, 1, 0, -1 ] ], 0.75 ] + ], + [ + [ [ [ -2, -1, 0, 1, 0, -2 ], [ 0, 0, 1, 1, 0, -2 ], [ 0, -1, 0, 2, 0, -2 ], [ 0, 0, 0, 1, 0, -1 ] ], 0 ] + ], + [ + [ [ [ -2, -1, 0, 1, 0, -2 ], [ 0, 0, 1, 1, 0, -2 ], [ -1, 1, 0, 1, 0, -1 ], [ 0, 0, 0, 1, 0, -1 ] ], 0.625 ] + ], + [ + [ [ [ -2, -1, 0, 1, 0, -2 ], [ 0, 0, 1, 1, 0, -2 ], [ -1, 1, 0, 1, 0, -1 ], [ 0, 0, 1, 1, 1, -2 ] ], 1.125 ] + ], + [ + [ [ [ -2, -1, 0, 1, 0, -2 ], [ 0, 0, 1, 1, 0, -2 ], [ -1, 1, 1, 1, 1, -2 ], [ 0, 0, 1, 1, 1, -2 ] ], 1 ] + ], + [ + [ [ [ -2, -1, 0, 1, 0, -2 ], [ 0, 0, 1, 1, 0, -2 ], [ -1, 1, 1, 1, 1, -2 ], [ 1, -1, 0, 1, 1, -2 ] ], 0.625 ] + ], + [ + [ [ [ -2, -1, 0, 1, 0, -2 ], [ 1, -1, 0, 1, 0, -2 ], [ -1, 1, 1, 1, 1, -2 ], [ 1, -1, 0, 1, 1, -2 ] ], 0.75 ] + ], + [ + [ [ [ -1, -1, 0, 2, 1, -2 ], [ 1, -1, 0, 1, 0, -2 ], [ -1, 1, 1, 1, 1, -2 ], [ 1, -1, 0, 1, 1, -2 ] ], 1.125 ] + ], + [ + [ [ [ -1, 0, 1, 1, 1, -2 ], [ 1, -1, 0, 1, 0, -2 ], [ -1, 1, 1, 1, 1, -2 ], [ 1, -1, 0, 1, 1, -2 ] ], 0.25 ] + ], + [ + [ [ [ -1, 0, 1, 1, 1, -2 ], [ -1, 0, 1, 1, 1, -1 ], [ -1, 1, 1, 1, 1, -2 ], [ 1, -1, 0, 1, 1, -2 ] ], 0.25 ] + ], + [ + [ [ [ -1, 0, 1, 1, 1, -2 ], [ -1, 0, 1, 2, 1, -2 ], [ -1, 1, 1, 1, 1, -2 ], [ 1, -1, 0, 1, 1, -2 ] ], 1.125 ] + ], + [ + [ [ [ -1, 0, 1, 1, 1, -2 ], [ -1, 0, 1, 2, 1, -2 ], [ -2, 0, 1, 3, 1, -2 ], [ 1, -1, 0, 1, 1, -2 ] ], 1.125 ] + ], + [ + [ [ [ -1, 0, 1, 1, 1, -2 ], [ -1, 0, 1, 2, 1, -2 ], [ -2, 0, 1, 3, 1, -2 ], [ -1, 0, 1, 3, 0, -2 ] ], 1 ] + ], + [ + [ [ [ -1, 0, 1, 1, 1, -2 ], [ -1, 0, 1, 2, 1, -2 ], [ -2, 0, 1, 3, 1, -2 ], [ 0, -1, 1, 2, 1, -2 ] ], 0.25 ] + ], + [ + [ [ [ -1, 0, 1, 2, 1, -3 ], [ -1, 0, 1, 2, 1, -2 ], [ -2, 0, 1, 3, 1, -2 ], [ 0, -1, 1, 2, 1, -2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 1, 1, 3, 1, -2 ], [ -1, 0, 1, 2, 1, -2 ], [ -2, 0, 1, 3, 1, -2 ], [ 0, -1, 1, 2, 1, -2 ] ], 0 ] + ], + [ + [ [ [ -2, 0, 1, 2, 2, -2 ], [ -1, 0, 1, 2, 1, -2 ], [ -2, 0, 1, 3, 1, -2 ], [ 0, -1, 1, 2, 1, -2 ] ], 1 ] + ], + [ + [ [ [ -2, 0, 1, 2, 2, -2 ], [ -1, 0, 1, 2, 1, -2 ], [ -2, 0, 1, 3, 1, -2 ], [ -1, 0, 0, 3, 1, -2 ] ], 0.75 ] + ], + [ + [ [ [ -2, 0, 1, 2, 2, -2 ], [ -1, 0, 1, 2, 1, -2 ], [ -1, -1, 1, 2, 2, -2 ], [ -1, 0, 0, 3, 1, -2 ] ], 0.625 ] + ], + [ + [ [ [ -1, 0, 1, 2, 0, -2 ], [ -1, 0, 1, 2, 1, -2 ], [ -1, -1, 1, 2, 2, -2 ], [ -1, 0, 0, 3, 1, -2 ] ], 0.125 ] + ], + [ + [ [ [ -1, 0, 1, 2, 0, -2 ], [ -1, 0, 1, 2, 1, -2 ], [ -1, -1, 0, 3, 1, -2 ], [ -1, 0, 0, 3, 1, -2 ] ], 0.75 ] + ], + [ + [ [ [ -1, 0, 1, 2, 0, -2 ], [ 0, 0, 1, 2, -1, -2 ], [ -1, -1, 0, 3, 1, -2 ], [ -1, 0, 0, 3, 1, -2 ] ], 0.25 ] + ], + [ + [ [ [ -1, 0, 1, 2, 0, -2 ], [ 0, -1, 0, 2, 1, -2 ], [ -1, -1, 0, 3, 1, -2 ], [ -1, 0, 0, 3, 1, -2 ] ], 1.25 ] + ], + [ + [ [ [ -1, 0, 1, 2, 0, -2 ], [ 0, -1, 0, 2, 1, -2 ], [ -1, -1, 0, 3, 1, -2 ], [ 0, -1, 0, 2, 2, -2 ] ], 0.625 ], + [ [ [ "Rest" ], [ 0, -1, 0, 2, 1, -2 ], [ -1, -1, 0, 3, 1, -2 ], [ 0, -1, 0, 2, 2, -2 ] ], 0.625 ], + [ [ [ "Rest" ], [ 0, -1, 0, 2, 1, -2 ], [ -1, -1, 0, 3, 1, -2 ], [ "Rest" ] ], 0.375 ], + [ [ [ "Rest" ], [ "Rest" ], [ -1, -1, 0, 3, 1, -2 ], [ "Rest" ] ], 0.875 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.375 ] + ] + ] +], +"last_changes": +[ + [ [ -1, 0, 1, 2, 0, -2 ], [ -1, 0, 1, 2, 1, -2 ], [ -1, -1, 1, 2, 2, -2 ], [ -1, 0, 0, 3, 1, -2 ] ], + [ [ -1, 0, 1, 2, 0, -2 ], [ -1, 0, 1, 2, 1, -2 ], [ -1, -1, 0, 3, 1, -2 ], [ -1, 0, 0, 3, 1, -2 ] ], + [ [ -1, 0, 1, 2, 0, -2 ], [ 0, 0, 1, 2, -1, -2 ], [ -1, -1, 0, 3, 1, -2 ], [ -1, 0, 0, 3, 1, -2 ] ], + [ [ -1, 0, 1, 2, 0, -2 ], [ 0, -1, 0, 2, 1, -2 ], [ -1, -1, 0, 3, 1, -2 ], [ -1, 0, 0, 3, 1, -2 ] ], + [ [ -1, 0, 1, 2, 0, -2 ], [ 0, -1, 0, 2, 1, -2 ], [ -1, -1, 0, 3, 1, -2 ], [ 0, -1, 0, 2, 2, -2 ] ] +], +"cur_uid": "5ec14635", +"ref_uid": "7c2de94c", +"order_seed": 733231, +"dur_seed": 711733, +"motifs_seed": 934821, +"entrances_probs_vals": [ 0, 0, 0, 0, 1.2087912087912, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 0, 1.2087912087912, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 0, 1.2087912087912, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2170, 338 ], [ -2373.9938080495, 1453 ], [ -1650, 1676 ], [ -1370.8978328173, 1694 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 1, 0, 0.2, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ] +], +"sus_weights": [ 0, 0, 0.61 ], +"order_size": [ 30, 30 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/69c568c6/69c568c6_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/69c568c6/69c568c6_code.scd new file mode 100644 index 0000000..a40da01 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/69c568c6/69c568c6_code.scd @@ -0,0 +1,973 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + + + //isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/69c568c6/69c568c6_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/69c568c6/69c568c6_mus_model.json new file mode 100644 index 0000000..a490727 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/69c568c6/69c568c6_mus_model.json @@ -0,0 +1,535 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 1.625 ], + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1 ], + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.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 ] ], 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 ] ], 0.625 ], + [ [ [ 1, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.75 ] + ], + [ + [ [ [ 1, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ] ], 1.25 ] + ], + [ + [ [ [ 1, 0, 0, 0, 0, 0 ], [ -2, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ] ], 1.625 ] + ], + [ + [ [ [ 0, 1, 0, 0, 0, 0 ], [ -2, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ] ], 0.75 ] + ], + [ + [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, -1, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ] ], 1.125 ], + [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, -1, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 1.125 ] + ], + [ + [ [ [ 1, 0, -1, 0, 0, 0 ], [ -1, 1, -1, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 0.5 ], + [ [ [ 1, 0, -1, 0, 0, 0 ], [ -1, 1, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 0.875 ], + [ [ [ 1, 0, -1, 0, 0, 0 ], [ -1, 1, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 1.5 ] + ], + [ + [ [ [ 1, 0, -1, 0, 0, 0 ], [ -1, 1, -1, 0, 0, 0 ], [ -1, 2, -1, 0, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 2, -1, 0, 0, 0 ], [ -1, 1, -1, 0, 0, 0 ], [ -1, 2, -1, 0, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 0.875 ] + ], + [ + [ [ [ 0, 2, -1, 0, 0, 0 ], [ 0, 1, -1, -1, 0, 0 ], [ -1, 2, -1, 0, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 1.375 ], + [ [ [ -2, 2, -1, -1, 0, 0 ], [ 0, 1, -1, -1, 0, 0 ], [ -1, 2, -1, 0, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 0.875 ], + [ [ [ -2, 2, -1, -1, 0, 0 ], [ 0, 1, -1, -1, 0, 0 ], [ 0, 2, -1, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 0.5 ] + ], + [ + [ [ [ -2, 2, -1, -1, 0, 0 ], [ 0, 1, -1, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 1.75 ], + [ [ [ -2, 1, -1, -1, 0, 1 ], [ 0, 1, -1, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, -1, -1, 0, 1 ], [ 1, 1, -1, -2, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 1.25 ] + ], + [ + [ [ [ -2, 1, -1, -1, 0, 1 ], [ 1, 1, -1, -2, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 0.625 ], + [ [ [ -2, 1, -1, -1, 0, 1 ], [ -1, 2, -1, -1, 0, 1 ], [ 1, 0, -1, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 0.875 ] + ], + [ + [ [ [ -2, 1, -1, -1, 0, 1 ], [ 0, 1, -2, -1, 0, 1 ], [ 1, 0, -1, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 1.25 ] + ], + [ + [ [ [ -2, 1, -1, -1, 0, 1 ], [ 1, 1, -1, -1, -1, 0 ], [ 1, 0, -1, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 0.75 ], + [ [ [ -2, 1, -1, -1, 0, 1 ], [ 1, 1, -1, -1, -1, 0 ], [ 0, 2, -1, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 0.875 ] + ], + [ + [ [ [ -1, 2, -1, -2, 0, 0 ], [ 1, 1, -1, -1, -1, 0 ], [ 0, 2, -1, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 1.625 ] + ], + [ + [ [ [ -1, 2, -1, -2, 0, 0 ], [ -1, 2, -1, -1, 0, 0 ], [ 0, 2, -1, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 1.375 ] + ], + [ + [ [ [ -1, 2, -1, -2, 0, 0 ], [ -1, 2, -1, -1, 0, 0 ], [ 1, 2, -1, -2, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 1.125 ], + [ [ [ -1, 2, -1, -2, 0, 0 ], [ -1, 2, -1, -1, 0, 0 ], [ 1, 2, -1, -2, 0, 0 ], [ 0, 2, -1, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 2, -1, -2, 0, 0 ], [ 0, 2, -1, -2, 0, 0 ], [ 1, 2, -1, -2, 0, 0 ], [ 0, 2, -1, -1, 0, 0 ] ], 1.625 ], + [ [ [ -1, 2, -1, -2, 0, 0 ], [ 0, 2, -1, -2, 0, 0 ], [ 0, 2, 0, -1, 0, 0 ], [ 0, 2, -1, -1, 0, 0 ] ], 0.75 ] + ], + [ + [ [ [ -1, 2, -1, -2, 0, 0 ], [ -1, 2, 0, -1, 0, 0 ], [ 0, 2, 0, -1, 0, 0 ], [ 0, 2, -1, -1, 0, 0 ] ], 1.375 ], + [ [ [ -1, 2, -1, -2, 0, 0 ], [ -1, 2, 0, -1, 0, 0 ], [ 1, 2, 0, -2, 0, 0 ], [ 0, 2, -1, -1, 0, 0 ] ], 1.75 ] + ], + [ + [ [ [ -1, 2, -1, -2, 0, 0 ], [ -1, 2, 0, -1, 0, 0 ], [ 0, 2, -1, -2, 1, 0 ], [ 0, 2, -1, -1, 0, 0 ] ], 1 ], + [ [ [ -1, 2, -1, -2, 0, 0 ], [ 1, 2, -1, -2, 0, -1 ], [ 0, 2, -1, -2, 1, 0 ], [ 0, 2, -1, -1, 0, 0 ] ], 1.125 ], + [ [ [ -1, 2, -1, -2, 0, 0 ], [ 1, 2, -1, -2, 0, -1 ], [ 0, 2, -1, -2, 1, 0 ], [ 1, 2, -1, -2, 0, 0 ] ], 1.125 ] + ], + [ + [ [ [ -1, 2, -1, -2, 0, 0 ], [ 1, 2, -1, -2, 0, -1 ], [ 0, 3, -1, -2, 0, 0 ], [ 1, 2, -1, -2, 0, 0 ] ], 1.375 ], + [ [ [ -1, 2, -1, -2, 0, 0 ], [ 1, 2, -1, -2, 0, -1 ], [ 0, 3, -1, -2, 0, 0 ], [ 1, 2, -1, -1, 0, -1 ] ], 1.125 ] + ], + [ + [ [ [ -1, 2, -1, -2, 0, 0 ], [ 1, 2, -1, -2, 0, -1 ], [ 0, 3, -1, -2, 0, 0 ], [ 1, 3, -2, -2, 0, 0 ] ], 0.75 ], + [ [ [ -1, 2, -1, -2, 0, 0 ], [ -1, 3, -1, -1, 0, 0 ], [ 0, 3, -1, -2, 0, 0 ], [ 1, 3, -2, -2, 0, 0 ] ], 1.5 ], + [ [ [ -1, 3, -1, -2, 0, 0 ], [ -1, 3, -1, -1, 0, 0 ], [ 0, 3, -1, -2, 0, 0 ], [ 1, 3, -2, -2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 2, -2, -2, 0, 0 ], [ -1, 3, -1, -1, 0, 0 ], [ 0, 3, -1, -2, 0, 0 ], [ 1, 3, -2, -2, 0, 0 ] ], 1.75 ] + ], + [ + [ [ [ 0, 2, -2, -2, 0, 0 ], [ -1, 3, -1, -1, 0, 0 ], [ 1, 2, -2, -2, 0, 0 ], [ 1, 3, -2, -2, 0, 0 ] ], 1.375 ] + ], + [ + [ [ [ 0, 2, -2, -2, 0, 0 ], [ -1, 3, -1, -1, 0, 0 ], [ 0, 3, -2, -2, 0, 0 ], [ 1, 3, -2, -2, 0, 0 ] ], 1.625 ], + [ [ [ 0, 2, -2, -2, 0, 0 ], [ 0, 2, -2, -1, 0, 0 ], [ 0, 3, -2, -2, 0, 0 ], [ 1, 3, -2, -2, 0, 0 ] ], 1.75 ], + [ [ [ 0, 2, -2, -2, 0, 0 ], [ 0, 2, -2, -1, 0, 0 ], [ 0, 3, -2, -2, 0, 0 ], [ 1, 2, -2, -2, 0, 1 ] ], 1 ] + ], + [ + [ [ [ 0, 1, -2, -2, 0, 1 ], [ 0, 2, -2, -1, 0, 0 ], [ 0, 3, -2, -2, 0, 0 ], [ 1, 2, -2, -2, 0, 1 ] ], 1.875 ], + [ [ [ 0, 1, -2, -2, 0, 1 ], [ 0, 2, -1, -2, 0, 1 ], [ 0, 3, -2, -2, 0, 0 ], [ 1, 2, -2, -2, 0, 1 ] ], 0.5 ], + [ [ [ 0, 1, -2, -2, 0, 1 ], [ 0, 2, -1, -2, 0, 1 ], [ 0, 2, -2, -2, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 0.875 ] + ], + [ + [ [ [ 0, 1, -2, -2, 0, 1 ], [ 0, 2, -1, -2, 0, 1 ], [ 0, 1, -2, -2, 0, 2 ], [ 1, 2, -2, -2, 0, 1 ] ], 1.375 ], + [ [ [ 0, 1, -2, -2, 0, 1 ], [ 0, 2, -1, -2, 0, 1 ], [ 0, 1, -2, -2, 0, 2 ], [ 1, 1, -2, -2, 0, 2 ] ], 0.625 ] + ], + [ + [ [ [ 0, 1, -2, -2, 0, 1 ], [ 0, 2, -1, -2, 0, 1 ], [ 0, 1, -2, -2, 0, 2 ], [ 1, 2, -1, -2, 0, 1 ] ], 0.625 ], + [ [ [ -1, 1, -1, -2, 0, 1 ], [ 0, 2, -1, -2, 0, 1 ], [ 0, 1, -2, -2, 0, 2 ], [ 1, 2, -1, -2, 0, 1 ] ], 0.5 ] + ], + [ + [ [ [ -1, 1, -1, -2, 0, 1 ], [ 1, 1, -2, -2, 0, 1 ], [ 0, 1, -2, -2, 0, 2 ], [ 1, 2, -1, -2, 0, 1 ] ], 0.75 ] + ], + [ + [ [ [ -1, 1, -1, -2, 0, 1 ], [ 1, 1, -2, -2, 0, 1 ], [ 0, 1, -1, -2, 1, 1 ], [ 1, 2, -1, -2, 0, 1 ] ], 0.875 ] + ], + [ + [ [ [ -1, 1, -1, -2, 0, 1 ], [ 1, 1, -2, -2, 0, 1 ], [ 0, 2, -1, -2, 0, 1 ], [ 1, 2, -1, -2, 0, 1 ] ], 1.5 ], + [ [ [ -2, 3, -1, -2, 0, 1 ], [ 1, 1, -2, -2, 0, 1 ], [ 0, 2, -1, -2, 0, 1 ], [ 1, 2, -1, -2, 0, 1 ] ], 1.125 ] + ], + [ + [ [ [ -1, 2, -2, -2, 0, 1 ], [ 1, 1, -2, -2, 0, 1 ], [ 0, 2, -1, -2, 0, 1 ], [ 1, 2, -1, -2, 0, 1 ] ], 0.625 ], + [ [ [ -1, 2, -2, -2, 0, 1 ], [ 1, 1, -2, -2, 0, 1 ], [ 0, 2, -1, -2, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 1.75 ], + [ [ [ -1, 2, -2, -2, 0, 1 ], [ 1, 1, -2, -2, 0, 1 ], [ 0, 2, -2, -2, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 0.625 ] + ], + [ + [ [ [ -1, 2, -2, -2, 0, 1 ], [ 1, 1, -2, -2, 0, 1 ], [ 1, 1, -3, -2, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 0.625 ], + [ [ [ 0, 1, -3, -2, 0, 1 ], [ 1, 1, -2, -2, 0, 1 ], [ 1, 1, -3, -2, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 1.25 ] + ], + [ + [ [ [ 0, 1, -3, -2, 0, 1 ], [ 1, 0, -3, -2, 0, 1 ], [ 1, 1, -3, -2, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 1.375 ], + [ [ [ -1, 2, -3, -2, 0, 1 ], [ 1, 0, -3, -2, 0, 1 ], [ 1, 1, -3, -2, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 0.5 ] + ], + [ + [ [ [ -1, 2, -3, -2, 0, 1 ], [ 0, 2, -3, -2, 0, 1 ], [ 1, 1, -3, -2, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 1 ], + [ [ [ 0, 1, -4, -2, 0, 1 ], [ 0, 2, -3, -2, 0, 1 ], [ 1, 1, -3, -2, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 1.5 ] + ], + [ + [ [ [ 0, 1, -4, -2, 0, 1 ], [ 1, 1, -4, -2, 0, 1 ], [ 1, 1, -3, -2, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 1.75 ], + [ [ [ -2, 3, -2, -2, 0, 1 ], [ 1, 1, -4, -2, 0, 1 ], [ 1, 1, -3, -2, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 1.625 ] + ], + [ + [ [ [ -2, 2, -2, -2, 0, 2 ], [ 1, 1, -4, -2, 0, 1 ], [ 1, 1, -3, -2, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 1.25 ], + [ [ [ -2, 2, -2, -2, 0, 2 ], [ 1, 1, -4, -2, 0, 1 ], [ 1, 2, -2, -3, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 1.25 ], + [ [ [ -2, 2, -2, -2, 0, 2 ], [ -1, 2, -2, -2, 0, 2 ], [ 1, 2, -2, -3, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 0.5 ] + ], + [ + [ [ [ -2, 2, -2, -2, 0, 2 ], [ 0, 3, -2, -3, 0, 1 ], [ 1, 2, -2, -3, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 0.625 ], + [ [ [ -1, 3, -2, -3, 0, 1 ], [ 0, 3, -2, -3, 0, 1 ], [ 1, 2, -2, -3, 0, 1 ], [ 1, 2, -2, -2, 0, 1 ] ], 0.625 ] + ], + [ + [ [ [ -1, 3, -2, -3, 0, 1 ], [ 0, 3, -2, -3, 0, 1 ], [ 1, 2, -2, -3, 0, 1 ], [ 2, 2, -2, -3, 0, 1 ] ], 0.75 ] + ], + [ + [ [ [ -1, 3, -2, -3, 0, 1 ], [ 0, 3, -2, -3, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 2, 2, -2, -3, 0, 1 ] ], 0.75 ], + [ [ [ 0, 3, -2, -4, 0, 1 ], [ 0, 3, -2, -3, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 2, 2, -2, -3, 0, 1 ] ], 0.875 ] + ], + [ + [ [ [ 0, 3, -2, -4, 0, 1 ], [ 0, 3, -2, -3, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 1, 4, -2, -3, 0, 1 ] ], 0.875 ] + ], + [ + [ [ [ -1, 3, -1, -3, 0, 1 ], [ 0, 3, -2, -3, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 1, 4, -2, -3, 0, 1 ] ], 1.25 ] + ], + [ + [ [ [ 0, 2, -2, -3, 0, 1 ], [ 0, 3, -2, -3, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 1, 4, -2, -3, 0, 1 ] ], 1.25 ] + ], + [ + [ [ [ 0, 2, -2, -3, 0, 1 ], [ 0, 3, -2, -3, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 1, 3, -1, -3, 0, 1 ] ], 1.125 ], + [ [ [ 0, 3, -2, -3, -1, 1 ], [ 0, 3, -2, -3, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 1, 3, -1, -3, 0, 1 ] ], 1.25 ] + ], + [ + [ [ [ 0, 3, -2, -3, -1, 1 ], [ 0, 4, -2, -3, -1, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 1, 3, -1, -3, 0, 1 ] ], 0.875 ], + [ [ [ -1, 3, -2, -3, 0, 1 ], [ 0, 4, -2, -3, -1, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 1, 3, -1, -3, 0, 1 ] ], 1.625 ], + [ [ [ -1, 3, -2, -3, 0, 1 ], [ 0, 4, -2, -3, -1, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 0, 4, -2, -2, 0, 1 ] ], 0.375 ] + ], + [ + [ [ [ -1, 3, -2, -3, 0, 1 ], [ 0, 3, -1, -3, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 0, 4, -2, -2, 0, 1 ] ], 0.5 ], + [ [ [ -1, 3, -2, -3, 0, 1 ], [ 0, 3, -1, -3, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 1, 4, -2, -3, 0, 1 ] ], 0.5 ] + ], + [ + [ [ [ -1, 4, -2, -3, 0, 0 ], [ 0, 3, -1, -3, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 1, 4, -2, -3, 0, 1 ] ], 0.75 ], + [ [ [ -1, 4, -2, -3, 0, 0 ], [ -1, 4, -2, -2, 0, 1 ], [ 0, 4, -2, -3, 0, 1 ], [ 1, 4, -2, -3, 0, 1 ] ], 1.5 ] + ], + [ + [ [ [ -1, 4, -2, -3, 0, 0 ], [ -1, 4, -2, -2, 0, 1 ], [ 0, 4, -2, -2, 0, 0 ], [ 1, 4, -2, -3, 0, 1 ] ], 1.125 ], + [ [ [ -1, 4, -2, -3, 0, 0 ], [ -1, 4, -2, -2, 0, 1 ], [ 0, 4, -2, -2, 0, 0 ], [ 2, 3, -2, -3, 0, 0 ] ], 1.5 ] + ], + [ + [ [ [ -1, 3, -2, -2, 0, 0 ], [ -1, 4, -2, -2, 0, 1 ], [ 0, 4, -2, -2, 0, 0 ], [ 2, 3, -2, -3, 0, 0 ] ], 0.625 ], + [ [ [ -1, 3, -2, -2, 0, 0 ], [ 1, 3, -2, -3, 0, 0 ], [ 0, 4, -2, -2, 0, 0 ], [ 2, 3, -2, -3, 0, 0 ] ], 1.125 ], + [ [ [ -1, 3, -2, -2, 0, 0 ], [ 1, 3, -2, -3, 0, 0 ], [ 1, 4, -2, -3, 0, 0 ], [ 2, 3, -2, -3, 0, 0 ] ], 1.625 ] + ], + [ + [ [ [ -1, 3, -2, -2, 0, 0 ], [ 1, 3, -2, -3, 0, 0 ], [ 1, 4, -2, -3, 0, 0 ], [ 1, 5, -2, -3, 0, 0 ] ], 1.125 ] + ], + [ + [ [ [ -1, 3, -2, -2, 0, 0 ], [ 1, 3, -2, -3, 0, 0 ], [ 1, 4, -2, -3, 0, 0 ], [ 3, 3, -2, -3, 0, -1 ] ], 0.75 ], + [ [ [ -1, 3, -2, -2, 0, 0 ], [ 1, 3, -2, -3, 0, 0 ], [ 2, 3, -3, -3, 0, 0 ], [ 3, 3, -2, -3, 0, -1 ] ], 0.5 ], + [ [ [ 0, 3, -2, -3, 0, 0 ], [ 1, 3, -2, -3, 0, 0 ], [ 2, 3, -3, -3, 0, 0 ], [ 3, 3, -2, -3, 0, -1 ] ], 1.25 ] + ], + [ + [ [ [ 0, 3, -2, -3, 0, 0 ], [ 1, 3, -2, -3, 0, 0 ], [ 2, 2, -2, -3, 0, 0 ], [ 3, 3, -2, -3, 0, -1 ] ], 1.5 ] + ], + [ + [ [ [ 0, 3, -2, -3, 0, 0 ], [ 1, 3, -2, -3, 0, 0 ], [ 1, 4, -2, -3, 0, -1 ], [ 3, 3, -2, -3, 0, -1 ] ], 1 ], + [ [ [ 0, 3, -2, -2, 0, -1 ], [ 1, 3, -2, -3, 0, 0 ], [ 1, 4, -2, -3, 0, -1 ], [ 3, 3, -2, -3, 0, -1 ] ], 1.375 ], + [ [ [ 0, 3, -2, -2, 0, -1 ], [ 1, 3, -2, -2, 0, -1 ], [ 1, 4, -2, -3, 0, -1 ], [ 3, 3, -2, -3, 0, -1 ] ], 0.875 ] + ], + [ + [ [ [ 0, 3, -2, -2, 0, -1 ], [ 2, 3, -2, -3, 0, -1 ], [ 1, 4, -2, -3, 0, -1 ], [ 3, 3, -2, -3, 0, -1 ] ], 0.75 ], + [ [ [ 1, 3, -2, -3, 0, -1 ], [ 2, 3, -2, -3, 0, -1 ], [ 1, 4, -2, -3, 0, -1 ], [ 3, 3, -2, -3, 0, -1 ] ], 0.375 ] + ], + [ + [ [ [ 1, 3, -2, -3, 0, -1 ], [ 2, 3, -2, -3, 0, -1 ], [ 2, 3, -3, -3, 0, -1 ], [ 3, 3, -2, -3, 0, -1 ] ], 1.75 ], + [ [ [ 1, 3, -2, -3, 0, -1 ], [ 2, 3, -2, -3, 0, -1 ], [ 2, 3, -3, -3, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ] ], 1.25 ] + ], + [ + [ [ [ 1, 3, -2, -3, 0, -1 ], [ 2, 3, -2, -3, 0, -1 ], [ 3, 3, -3, -4, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ] ], 1.75 ], + [ [ [ 1, 3, -2, -3, 0, -1 ], [ 1, 3, -3, -3, 0, 0 ], [ 3, 3, -3, -4, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ] ], 0.5 ], + [ [ [ 2, 2, -3, -3, 0, -1 ], [ 1, 3, -3, -3, 0, 0 ], [ 3, 3, -3, -4, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ] ], 1.625 ] + ], + [ + [ [ [ 2, 2, -3, -3, 0, -1 ], [ 3, 1, -3, -3, 0, -1 ], [ 3, 3, -3, -4, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ] ], 0.875 ] + ], + [ + [ [ [ 2, 2, -3, -3, 0, -1 ], [ 3, 1, -3, -3, 0, -1 ], [ 3, 3, -3, -4, 0, -1 ], [ 4, 2, -4, -3, 0, -1 ] ], 1.125 ] + ], + [ + [ [ [ 2, 2, -3, -3, 0, -1 ], [ 3, 1, -3, -3, 0, -1 ], [ 3, 3, -3, -4, 0, -1 ], [ 4, 3, -3, -4, 0, -1 ] ], 1.625 ], + [ [ [ 3, 2, -3, -4, 0, -1 ], [ 3, 1, -3, -3, 0, -1 ], [ 3, 3, -3, -4, 0, -1 ], [ 4, 3, -3, -4, 0, -1 ] ], 1.375 ] + ], + [ + [ [ [ 2, 4, -3, -4, 0, -1 ], [ 3, 1, -3, -3, 0, -1 ], [ 3, 3, -3, -4, 0, -1 ], [ 4, 3, -3, -4, 0, -1 ] ], 0.75 ] + ], + [ + [ [ [ 2, 4, -3, -4, 0, -1 ], [ 1, 5, -3, -4, 0, -1 ], [ 3, 3, -3, -4, 0, -1 ], [ 4, 3, -3, -4, 0, -1 ] ], 1.5 ], + [ [ [ 2, 4, -3, -4, 0, -1 ], [ 1, 5, -3, -4, 0, -1 ], [ 3, 3, -3, -4, 0, -1 ], [ 4, 4, -3, -4, -1, -1 ] ], 0.875 ], + [ [ [ 2, 4, -3, -4, 0, -1 ], [ 1, 5, -3, -4, 0, -1 ], [ 3, 4, -3, -4, -1, -1 ], [ 4, 4, -3, -4, -1, -1 ] ], 1.625 ] + ], + [ + [ [ [ 2, 4, -3, -4, 0, -1 ], [ 1, 5, -3, -4, 0, -1 ], [ 3, 4, -4, -4, 0, -1 ], [ 4, 4, -3, -4, -1, -1 ] ], 0.5 ], + [ [ [ 2, 4, -3, -4, 0, -1 ], [ 2, 4, -4, -4, 0, -1 ], [ 3, 4, -4, -4, 0, -1 ], [ 4, 4, -3, -4, -1, -1 ] ], 1.375 ] + ], + [ + [ [ [ 2, 4, -3, -4, 0, -1 ], [ 2, 4, -4, -4, 0, -1 ], [ 3, 4, -4, -4, 0, -1 ], [ 3, 4, -2, -4, 0, -1 ] ], 1.75 ], + [ [ [ 2, 4, -3, -4, 0, -1 ], [ 1, 4, -3, -3, 0, -1 ], [ 3, 4, -4, -4, 0, -1 ], [ 3, 4, -2, -4, 0, -1 ] ], 0.625 ], + [ [ [ 2, 4, -3, -4, 0, -1 ], [ 1, 4, -3, -3, 0, -1 ], [ 2, 4, -3, -3, 0, -1 ], [ 3, 4, -2, -4, 0, -1 ] ], 1.75 ] + ], + [ + [ [ [ 2, 4, -3, -4, 0, -1 ], [ 1, 4, -3, -3, 0, -1 ], [ 2, 4, -3, -3, 0, -1 ], [ 2, 5, -3, -3, 0, -1 ] ], 0.75 ], + [ [ [ 2, 4, -3, -4, 0, -1 ], [ 1, 4, -3, -3, 0, -1 ], [ 3, 4, -3, -4, 0, -1 ], [ 2, 5, -3, -3, 0, -1 ] ], 0.5 ] + ], + [ + [ [ [ 2, 3, -3, -3, 0, -1 ], [ 1, 4, -3, -3, 0, -1 ], [ 3, 4, -3, -4, 0, -1 ], [ 2, 5, -3, -3, 0, -1 ] ], 0.75 ], + [ [ [ 2, 3, -3, -3, 0, -1 ], [ 1, 4, -3, -3, 0, -1 ], [ 2, 4, -2, -3, 0, -1 ], [ 2, 5, -3, -3, 0, -1 ] ], 1.75 ] + ], + [ + [ [ [ 2, 3, -3, -3, 0, -1 ], [ 1, 4, -3, -3, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ], [ 2, 5, -3, -3, 0, -1 ] ], 1 ], + [ [ [ 2, 3, -3, -3, 0, -1 ], [ 2, 3, -4, -3, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ], [ 2, 5, -3, -3, 0, -1 ] ], 1.125 ] + ], + [ + [ [ [ 2, 3, -3, -3, 0, -1 ], [ 2, 3, -4, -3, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ], [ 3, 3, -2, -3, 0, -1 ] ], 1.5 ], + [ [ [ 2, 3, -3, -3, 0, -1 ], [ 2, 2, -3, -3, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ], [ 3, 3, -2, -3, 0, -1 ] ], 1.625 ], + [ [ [ 3, 3, -3, -4, 0, -1 ], [ 2, 2, -3, -3, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ], [ 3, 3, -2, -3, 0, -1 ] ], 0.5 ] + ], + [ + [ [ [ 3, 3, -3, -4, 0, -1 ], [ 3, 2, -3, -4, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ], [ 3, 3, -2, -3, 0, -1 ] ], 0.75 ] + ], + [ + [ [ [ 2, 3, -2, -3, 0, -1 ], [ 3, 2, -3, -4, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ], [ 3, 3, -2, -3, 0, -1 ] ], 0.875 ], + [ [ [ 2, 3, -2, -3, 0, -1 ], [ 3, 2, -3, -4, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ], [ 2, 3, -3, -3, 0, -1 ] ], 1.125 ] + ], + [ + [ [ [ 2, 3, -2, -3, 0, -1 ], [ 2, 3, -4, -3, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ], [ 2, 3, -3, -3, 0, -1 ] ], 0.875 ], + [ [ [ 3, 2, -3, -3, 0, -1 ], [ 2, 3, -4, -3, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ], [ 2, 3, -3, -3, 0, -1 ] ], 0.875 ] + ], + [ + [ [ [ 3, 2, -3, -3, 0, -1 ], [ 2, 3, -4, -3, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ], [ 3, 3, -3, -4, 0, -1 ] ], 1.25 ], + [ [ [ 3, 2, -3, -3, 0, -1 ], [ 1, 3, -3, -2, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ], [ 3, 3, -3, -4, 0, -1 ] ], 1.25 ], + [ [ [ 2, 4, -3, -3, 0, -1 ], [ 1, 3, -3, -2, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ], [ 3, 3, -3, -4, 0, -1 ] ], 1.125 ] + ], + [ + [ [ [ 2, 4, -3, -3, 0, -1 ], [ 1, 3, -3, -2, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ], [ 1, 4, -3, -2, 0, -1 ] ], 0.625 ] + ], + [ + [ [ [ 2, 3, -3, -2, 0, -1 ], [ 1, 3, -3, -2, 0, -1 ], [ 3, 3, -3, -3, 0, -1 ], [ 1, 4, -3, -2, 0, -1 ] ], 1.25 ], + [ [ [ 2, 3, -3, -2, 0, -1 ], [ 1, 3, -3, -2, 0, -1 ], [ 2, 3, -2, -2, 0, -1 ], [ 1, 4, -3, -2, 0, -1 ] ], 1.375 ] + ], + [ + [ [ [ 1, 3, -2, -2, 0, -1 ], [ 1, 3, -3, -2, 0, -1 ], [ 2, 3, -2, -2, 0, -1 ], [ 1, 4, -3, -2, 0, -1 ] ], 0.875 ] + ], + [ + [ [ [ 1, 3, -2, -2, 0, -1 ], [ 1, 3, -3, -2, 0, -1 ], [ 2, 3, -2, -2, 0, -1 ], [ 2, 2, -2, -2, 0, -1 ] ], 1.5 ] + ], + [ + [ [ [ 1, 3, -2, -2, 0, -1 ], [ 2, 1, -2, -2, 0, -1 ], [ 2, 3, -2, -2, 0, -1 ], [ 2, 2, -2, -2, 0, -1 ] ], 0.5 ] + ], + [ + [ [ [ 1, 3, -2, -2, 0, -1 ], [ 2, 1, -2, -2, 0, -1 ], [ 3, 1, -2, -2, 0, -1 ], [ 2, 2, -2, -2, 0, -1 ] ], 1.625 ], + [ [ [ 2, 0, -2, -2, 0, -1 ], [ 2, 1, -2, -2, 0, -1 ], [ 3, 1, -2, -2, 0, -1 ], [ 2, 2, -2, -2, 0, -1 ] ], 1.5 ], + [ [ [ 2, 0, -2, -2, 0, -1 ], [ 2, 1, -2, -2, 0, -1 ], [ 3, 1, -2, -2, 0, -1 ], [ 3, 1, -3, -2, 0, -1 ] ], 0.75 ] + ], + [ + [ [ [ 2, 0, -2, -2, 0, -1 ], [ 3, 0, -3, -2, 0, -1 ], [ 3, 1, -2, -2, 0, -1 ], [ 3, 1, -3, -2, 0, -1 ] ], 1.5 ] + ], + [ + [ [ [ 2, 0, -2, -2, 0, -1 ], [ 3, 0, -3, -2, 0, -1 ], [ 4, 0, -3, -2, 0, -1 ], [ 3, 1, -3, -2, 0, -1 ] ], 1 ], + [ [ [ 2, 0, -3, -2, 0, -1 ], [ 3, 0, -3, -2, 0, -1 ], [ 4, 0, -3, -2, 0, -1 ], [ 3, 1, -3, -2, 0, -1 ] ], 1.25 ], + [ [ [ 2, 0, -3, -2, 0, -1 ], [ 3, 0, -3, -2, 0, -1 ], [ 4, 0, -3, -2, 0, -1 ], [ 4, 0, -4, -2, 0, -1 ] ], 1.25 ] + ], + [ + [ [ [ 2, 0, -3, -2, 0, -1 ], [ 2, 0, -4, -2, 0, 0 ], [ 4, 0, -3, -2, 0, -1 ], [ 4, 0, -4, -2, 0, -1 ] ], 0.5 ], + [ [ [ 3, -1, -4, -2, 0, -1 ], [ 2, 0, -4, -2, 0, 0 ], [ 4, 0, -3, -2, 0, -1 ], [ 4, 0, -4, -2, 0, -1 ] ], 1.125 ], + [ [ [ 3, -1, -4, -2, 0, -1 ], [ 2, 0, -4, -2, 0, 0 ], [ 5, -1, -4, -2, 0, -1 ], [ 4, 0, -4, -2, 0, -1 ] ], 0.5 ] + ], + [ + [ [ [ 3, -1, -4, -2, 0, -1 ], [ 2, 0, -4, -2, 0, 0 ], [ 5, -1, -4, -2, 0, -1 ], [ 4, -1, -4, -2, 0, 0 ] ], 1.75 ] + ], + [ + [ [ [ 2, 0, -4, -2, 0, -1 ], [ 2, 0, -4, -2, 0, 0 ], [ 5, -1, -4, -2, 0, -1 ], [ 4, -1, -4, -2, 0, 0 ] ], 0.5 ], + [ [ [ 2, 0, -4, -2, 0, -1 ], [ 2, 0, -4, -2, 0, 0 ], [ 5, -1, -4, -2, 0, -1 ], [ 3, 1, -4, -2, 0, 0 ] ], 1.125 ], + [ [ [ 2, 0, -4, -2, 0, -1 ], [ 2, 0, -4, -2, 0, 0 ], [ 3, 0, -4, -1, 0, 0 ], [ 3, 1, -4, -2, 0, 0 ] ], 0.5 ] + ], + [ + [ [ [ 2, -1, -4, -2, 0, 0 ], [ 2, 0, -4, -2, 0, 0 ], [ 3, 0, -4, -1, 0, 0 ], [ 3, 1, -4, -2, 0, 0 ] ], 1.625 ], + [ [ [ 2, -1, -4, -2, 0, 0 ], [ 2, 0, -4, -2, 0, 0 ], [ 4, 1, -4, -2, 0, -1 ], [ 3, 1, -4, -2, 0, 0 ] ], 0.75 ] + ], + [ + [ [ [ 2, -1, -4, -2, 0, 0 ], [ 2, 0, -4, -2, 0, 0 ], [ 4, 0, -5, -2, 0, 0 ], [ 3, 1, -4, -2, 0, 0 ] ], 1.75 ], + [ [ [ 2, -1, -4, -2, 0, 0 ], [ 2, 0, -4, -2, 0, 0 ], [ 4, 0, -5, -2, 0, 0 ], [ 4, -1, -4, -2, 0, -1 ] ], 0.5 ] + ], + [ + [ [ [ 2, -1, -4, -2, 0, 0 ], [ 2, 0, -4, -2, 0, 0 ], [ 4, 0, -5, -2, 0, 0 ], [ 2, 0, -4, -1, 0, 0 ] ], 1.75 ] + ], + [ + [ [ [ 1, 1, -4, -2, 0, 0 ], [ 2, 0, -4, -2, 0, 0 ], [ 4, 0, -5, -2, 0, 0 ], [ 2, 0, -4, -1, 0, 0 ] ], 0.875 ], + [ [ [ 1, 1, -4, -2, 0, 0 ], [ 2, 0, -4, -2, 0, 0 ], [ 3, 0, -4, -1, 0, 0 ], [ 2, 0, -4, -1, 0, 0 ] ], 0.875 ] + ], + [ + [ [ [ 1, 1, -4, -2, 0, 0 ], [ 2, 0, -4, -2, 0, 0 ], [ 4, 1, -4, -2, 0, -1 ], [ 2, 0, -4, -1, 0, 0 ] ], 1.625 ] + ], + [ + [ [ [ 1, 1, -4, -2, 0, 0 ], [ 1, 2, -4, -2, 0, 0 ], [ 4, 1, -4, -2, 0, -1 ], [ 2, 0, -4, -1, 0, 0 ] ], 0.5 ], + [ [ [ 1, 1, -4, -2, 0, 0 ], [ 1, 2, -4, -2, 0, 0 ], [ 3, 1, -4, -2, 0, 0 ], [ 2, 0, -4, -1, 0, 0 ] ], 0.875 ], + [ [ [ 1, 1, -4, -2, 0, 0 ], [ 1, 2, -4, -2, 0, 0 ], [ 3, 1, -4, -2, 0, 0 ], [ 2, 1, -4, -2, 0, 0 ] ], 1.125 ] + ], + [ + [ [ [ 0, 2, -4, -2, 0, 0 ], [ 1, 2, -4, -2, 0, 0 ], [ 3, 1, -4, -2, 0, 0 ], [ 2, 1, -4, -2, 0, 0 ] ], 1.625 ] + ], + [ + [ [ [ 0, 2, -4, -2, 0, 0 ], [ 1, 2, -4, -2, 0, 0 ], [ 3, 1, -4, -2, 0, 0 ], [ 1, 3, -4, -2, 0, 0 ] ], 0.75 ] + ], + [ + [ [ [ 1, 2, -4, -3, 0, 0 ], [ 1, 2, -4, -2, 0, 0 ], [ 3, 1, -4, -2, 0, 0 ], [ 1, 3, -4, -2, 0, 0 ] ], 0.875 ] + ], + [ + [ [ [ 1, 2, -4, -3, 0, 0 ], [ 1, 2, -4, -2, 0, 0 ], [ 3, 1, -4, -2, 0, 0 ], [ 3, 1, -4, -2, 0, -1 ] ], 1.5 ], + [ [ [ 1, 2, -4, -3, 0, 0 ], [ 2, 2, -4, -3, 0, 0 ], [ 3, 1, -4, -2, 0, 0 ], [ 3, 1, -4, -2, 0, -1 ] ], 1.5 ] + ], + [ + [ [ [ 1, 2, -4, -3, 0, 0 ], [ 2, 2, -4, -3, 0, 0 ], [ 3, 1, -4, -2, 0, 0 ], [ 3, 0, -4, -2, 0, 0 ] ], 0.5 ], + [ [ [ 1, 1, -4, -2, 0, 0 ], [ 2, 2, -4, -3, 0, 0 ], [ 3, 1, -4, -2, 0, 0 ], [ 3, 0, -4, -2, 0, 0 ] ], 0.5 ], + [ [ [ 1, 1, -4, -2, 0, 0 ], [ 2, 1, -4, -2, 0, 0 ], [ 3, 1, -4, -2, 0, 0 ], [ 3, 0, -4, -2, 0, 0 ] ], 0.5 ] + ], + [ + [ [ [ 1, 1, -4, -2, 0, 0 ], [ 2, 1, -4, -2, 0, 0 ], [ 4, 0, -5, -2, 0, 0 ], [ 3, 0, -4, -2, 0, 0 ] ], 1.375 ], + [ [ [ 2, 0, -5, -2, 0, 0 ], [ 2, 1, -4, -2, 0, 0 ], [ 4, 0, -5, -2, 0, 0 ], [ 3, 0, -4, -2, 0, 0 ] ], 0.875 ], + [ [ [ 2, 0, -5, -2, 0, 0 ], [ 3, 0, -5, -2, 0, 0 ], [ 4, 0, -5, -2, 0, 0 ], [ 3, 0, -4, -2, 0, 0 ] ], 0.625 ] + ], + [ + [ [ [ 1, 0, -4, -2, 0, 0 ], [ 3, 0, -5, -2, 0, 0 ], [ 4, 0, -5, -2, 0, 0 ], [ 3, 0, -4, -2, 0, 0 ] ], 0.625 ], + [ [ [ 1, 0, -4, -2, 0, 0 ], [ 2, 0, -4, -2, 0, 0 ], [ 4, 0, -5, -2, 0, 0 ], [ 3, 0, -4, -2, 0, 0 ] ], 1.375 ], + [ [ [ 1, 0, -4, -2, 0, 0 ], [ 2, 0, -4, -2, 0, 0 ], [ 3, 1, -4, -2, 0, 0 ], [ 3, 0, -4, -2, 0, 0 ] ], 1.125 ] + ], + [ + [ [ [ 1, 0, -4, -2, 0, 0 ], [ 2, 0, -4, -2, 0, 0 ], [ 2, 1, -4, -2, 0, 0 ], [ 3, 0, -4, -2, 0, 0 ] ], 1.625 ], + [ [ [ 1, 0, -4, -2, 0, 0 ], [ 2, 0, -4, -2, 0, 0 ], [ 2, 1, -4, -2, 0, 0 ], [ 4, 0, -4, -3, 0, 0 ] ], 1.25 ] + ], + [ + [ [ [ 1, 0, -4, -2, 0, 0 ], [ 2, 0, -4, -2, 0, 0 ], [ 3, 0, -5, -2, 0, 0 ], [ 4, 0, -4, -3, 0, 0 ] ], 0.75 ], + [ [ [ 1, 0, -4, -2, 0, 0 ], [ 2, 0, -4, -2, 0, 0 ], [ 3, 0, -5, -2, 0, 0 ], [ 2, 1, -4, -2, 0, 0 ] ], 1.375 ] + ], + [ + [ [ [ 1, 0, -4, -2, 0, 0 ], [ 2, 0, -5, -2, 1, 0 ], [ 3, 0, -5, -2, 0, 0 ], [ 2, 1, -4, -2, 0, 0 ] ], 1.625 ], + [ [ [ 1, 0, -4, -2, 0, 0 ], [ 2, 0, -5, -2, 1, 0 ], [ 3, 0, -5, -2, 0, 0 ], [ 2, 0, -4, -1, 0, 0 ] ], 0.75 ] + ], + [ + [ [ [ 1, 0, -5, -2, 1, 0 ], [ 2, 0, -5, -2, 1, 0 ], [ 3, 0, -5, -2, 0, 0 ], [ 2, 0, -4, -1, 0, 0 ] ], 1.375 ], + [ [ [ 1, 0, -5, -2, 1, 0 ], [ 3, 0, -5, -2, -1, 0 ], [ 3, 0, -5, -2, 0, 0 ], [ 2, 0, -4, -1, 0, 0 ] ], 1.75 ], + [ [ [ 1, 0, -5, -2, 1, 0 ], [ 3, 0, -5, -2, -1, 0 ], [ 3, 0, -5, -2, 0, 0 ], [ 4, 0, -5, -2, 0, -1 ] ], 1.25 ] + ], + [ + [ [ [ 1, 0, -5, -2, 1, 0 ], [ 3, 0, -5, -2, -1, 0 ], [ 3, 0, -6, -2, 1, 0 ], [ 4, 0, -5, -2, 0, -1 ] ], 1.375 ], + [ [ [ 1, 0, -5, -2, 1, 0 ], [ 3, 0, -5, -2, -1, 0 ], [ 3, 0, -6, -2, 1, 0 ], [ "Rest" ] ], 0.625 ], + [ [ [ 1, 0, -5, -2, 1, 0 ], [ 3, 0, -5, -2, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 0.875 ], + [ [ [ 1, 0, -5, -2, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.375 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 6.75 ] + ] + ] +], +"last_changes": +[ + [ [ 1, 0, -4, -2, 0, 0 ], [ 2, 0, -5, -2, 1, 0 ], [ 3, 0, -5, -2, 0, 0 ], [ 2, 0, -4, -1, 0, 0 ] ], + [ [ 1, 0, -5, -2, 1, 0 ], [ 2, 0, -5, -2, 1, 0 ], [ 3, 0, -5, -2, 0, 0 ], [ 2, 0, -4, -1, 0, 0 ] ], + [ [ 1, 0, -5, -2, 1, 0 ], [ 3, 0, -5, -2, -1, 0 ], [ 3, 0, -5, -2, 0, 0 ], [ 2, 0, -4, -1, 0, 0 ] ], + [ [ 1, 0, -5, -2, 1, 0 ], [ 3, 0, -5, -2, -1, 0 ], [ 3, 0, -5, -2, 0, 0 ], [ 4, 0, -5, -2, 0, -1 ] ], + [ [ 1, 0, -5, -2, 1, 0 ], [ 3, 0, -5, -2, -1, 0 ], [ 3, 0, -6, -2, 1, 0 ], [ 4, 0, -5, -2, 0, -1 ] ] +], +"cur_uid": "69c568c6", +"ref_uid": "nil", +"order_seed": 712406, +"dur_seed": 506999, +"motifs_seed": 551883, +"entrances_probs_vals": [ 0, 0, 0, 0.41, 1.84, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 0.41, 1.84, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 3.2936507936508, 0.41, 1.84, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ -1200, 1200, 0.0020576131687243, 0.068181818181818, 0.074074074074074, 0.0625, 0.20576131687243, 0.0625, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61316872427983, 0, 0.98971193415638, 0 ], +"passages_weights": [ 0.48, 0.46, 0.48, 1, 1 ], +"hd_exp": 9, +"hd_invert": 0, +"order": +[ + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 0, 3 ], [ 1, 2 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 0, 2 ], [ 1, 3 ], [ ] ], + [ [ 1 ], [ 0, 2, 3 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 3, 1 ], [ 2, 0 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 0, 3 ], [ 2, 1 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 3, 0 ], [ 1, 2 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 3, 0 ], [ 1, 2 ], [ ] ], + [ [ 0, 3 ], [ 1, 2 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 3, 1 ], [ 2, 0 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 3 ], [ 0, 2, 1 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 3, 1 ], [ 2, 0 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 2, 0 ], [ 1, 3 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 3 ], [ 2, 0, 1 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 3, 0 ], [ 2, 1 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 3, 0 ], [ 2, 1 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 1, 2 ], [ 0, 3 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 0 ], [ 1, 2, 3 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 2, 0 ], [ 3, 1 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 3 ], [ 2, 0, 1 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 0, 2 ], [ 1, 3 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 100, 100 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/6a9928d6/6a9928d6_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/6a9928d6/6a9928d6_code.scd new file mode 100644 index 0000000..49436ca --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/6a9928d6/6a9928d6_code.scd @@ -0,0 +1,973 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + + + //isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/6a9928d6/6a9928d6_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/6a9928d6/6a9928d6_mus_model.json new file mode 100644 index 0000000..7ef872c --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/6a9928d6/6a9928d6_mus_model.json @@ -0,0 +1,554 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ 2, -4, 0, 3, -1, 0 ], [ "Rest" ] ], 1.5 ], + [ [ [ "Rest" ], [ "Rest" ], [ 2, -4, 0, 3, -1, 0 ], [ 4, -5, -1, 2, -1, -1 ] ], 0.5 ], + [ [ [ "Rest" ], [ 2, -5, 0, 3, -1, -1 ], [ 2, -4, 0, 3, -1, 0 ], [ 4, -5, -1, 2, -1, -1 ] ], 1.75 ], + [ [ [ 1, -5, 0, 3, -1, -1 ], [ 2, -5, 0, 3, -1, -1 ], [ 2, -4, 0, 3, -1, 0 ], [ 4, -5, -1, 2, -1, -1 ] ], 0.875 ] + ], + [ + [ [ [ 1, -5, 0, 3, -1, -1 ], [ 4, -5, -1, 2, -1, -2 ], [ 2, -4, 0, 3, -1, 0 ], [ 4, -5, -1, 2, -1, -1 ] ], 1.125 ], + [ [ [ 1, -5, 0, 3, -1, -1 ], [ 4, -5, -1, 2, -1, -2 ], [ 4, -5, -2, 2, -1, -1 ], [ 4, -5, -1, 2, -1, -1 ] ], 1.625 ], + [ [ [ 2, -5, 0, 2, -1, -1 ], [ 4, -5, -1, 2, -1, -2 ], [ 4, -5, -2, 2, -1, -1 ], [ 4, -5, -1, 2, -1, -1 ] ], 1.875 ] + ], + [ + [ [ [ 2, -5, 0, 2, -1, -1 ], [ 4, -5, -1, 2, -1, -2 ], [ 3, -5, 0, 2, 0, -1 ], [ 4, -5, -1, 2, -1, -1 ] ], 1.125 ], + [ [ [ 2, -5, 0, 2, -1, -1 ], [ 4, -5, -1, 2, -1, -2 ], [ 3, -5, 0, 2, 0, -1 ], [ 4, -6, 0, 2, -1, -1 ] ], 0.5 ], + [ [ [ 2, -5, 0, 2, -1, -1 ], [ 3, -6, 0, 2, -1, -1 ], [ 3, -5, 0, 2, 0, -1 ], [ 4, -6, 0, 2, -1, -1 ] ], 1.875 ] + ], + [ + [ [ [ 2, -5, 0, 2, -1, -1 ], [ 2, -5, 0, 2, 0, -2 ], [ 3, -5, 0, 2, 0, -1 ], [ 4, -6, 0, 2, -1, -1 ] ], 0.75 ], + [ [ [ 1, -5, 0, 2, 0, 0 ], [ 2, -5, 0, 2, 0, -2 ], [ 3, -5, 0, 2, 0, -1 ], [ 4, -6, 0, 2, -1, -1 ] ], 0.5 ], + [ [ [ 1, -5, 0, 2, 0, 0 ], [ 2, -5, 0, 2, 0, -2 ], [ 3, -5, 0, 2, 0, -1 ], [ 3, -5, -1, 2, 0, -1 ] ], 0.75 ] + ], + [ + [ [ [ 1, -5, 0, 2, 0, 0 ], [ 2, -5, 0, 2, 0, -2 ], [ 3, -5, 0, 2, 1, -2 ], [ 3, -5, -1, 2, 0, -1 ] ], 1.625 ], + [ [ [ 3, -5, 0, 1, 0, -2 ], [ 2, -5, 0, 2, 0, -2 ], [ 3, -5, 0, 2, 1, -2 ], [ 3, -5, -1, 2, 0, -1 ] ], 1.625 ] + ], + [ + [ [ [ 3, -5, 0, 2, 0, -3 ], [ 2, -5, 0, 2, 0, -2 ], [ 3, -5, 0, 2, 1, -2 ], [ 3, -5, -1, 2, 0, -1 ] ], 1.875 ] + ], + [ + [ [ [ 3, -5, 0, 2, 0, -3 ], [ 2, -5, 0, 2, 0, -2 ], [ 4, -5, 1, 2, 0, -3 ], [ 3, -5, -1, 2, 0, -1 ] ], 0.625 ], + [ [ [ 3, -5, 0, 2, 0, -3 ], [ 2, -5, 0, 3, 0, -3 ], [ 4, -5, 1, 2, 0, -3 ], [ 3, -5, -1, 2, 0, -1 ] ], 1.125 ], + [ [ [ 3, -5, 0, 2, 0, -3 ], [ 2, -5, 0, 3, 0, -3 ], [ 4, -5, 1, 2, 0, -3 ], [ 5, -5, 0, 1, 0, -3 ] ], 1.625 ] + ], + [ + [ [ [ 3, -5, 0, 2, 0, -3 ], [ 4, -5, -1, 2, 0, -3 ], [ 4, -5, 1, 2, 0, -3 ], [ 5, -5, 0, 1, 0, -3 ] ], 1 ], + [ [ [ 3, -5, 0, 2, 0, -3 ], [ 4, -5, -1, 2, 0, -3 ], [ 4, -5, 1, 2, 0, -3 ], [ 5, -5, 0, 2, 0, -4 ] ], 0.5 ], + [ [ [ 3, -5, 0, 2, 0, -3 ], [ 4, -5, -1, 2, 0, -3 ], [ 4, -5, 0, 2, 1, -3 ], [ 5, -5, 0, 2, 0, -4 ] ], 1.5 ] + ], + [ + [ [ [ 3, -5, 0, 3, 0, -4 ], [ 4, -5, -1, 2, 0, -3 ], [ 4, -5, 0, 2, 1, -3 ], [ 5, -5, 0, 2, 0, -4 ] ], 0.5 ] + ], + [ + [ [ [ 3, -5, 0, 2, 1, -4 ], [ 4, -5, -1, 2, 0, -3 ], [ 4, -5, 0, 2, 1, -3 ], [ 5, -5, 0, 2, 0, -4 ] ], 1.875 ], + [ [ [ 3, -5, 0, 2, 1, -4 ], [ 4, -5, 0, 2, 1, -4 ], [ 4, -5, 0, 2, 1, -3 ], [ 5, -5, 0, 2, 0, -4 ] ], 1.75 ], + [ [ [ 3, -5, 0, 2, 1, -4 ], [ 4, -5, 0, 2, 1, -4 ], [ 4, -5, 0, 2, 1, -3 ], [ 3, -4, 0, 2, 1, -3 ] ], 0.5 ] + ], + [ + [ [ [ 3, -5, 0, 2, 1, -4 ], [ 4, -5, 0, 2, 1, -4 ], [ 4, -5, 0, 2, 1, -3 ], [ 3, -5, 0, 2, 1, -2 ] ], 1.5 ] + ], + [ + [ [ [ 3, -5, 0, 2, 1, -4 ], [ 4, -5, 0, 2, 1, -4 ], [ 4, -5, 0, 2, 2, -4 ], [ 3, -5, 0, 2, 1, -2 ] ], 1.25 ] + ], + [ + [ [ [ 2, -5, -1, 2, 1, -2 ], [ 4, -5, 0, 2, 1, -4 ], [ 4, -5, 0, 2, 2, -4 ], [ 3, -5, 0, 2, 1, -2 ] ], 1.375 ], + [ [ [ 2, -5, -1, 2, 1, -2 ], [ 4, -5, 0, 2, 1, -4 ], [ 4, -5, 0, 1, 1, -2 ], [ 3, -5, 0, 2, 1, -2 ] ], 0.875 ], + [ [ [ 2, -5, -1, 2, 1, -2 ], [ 2, -5, 0, 3, 1, -2 ], [ 4, -5, 0, 1, 1, -2 ], [ 3, -5, 0, 2, 1, -2 ] ], 1.875 ] + ], + [ + [ [ [ 2, -5, -1, 2, 1, -2 ], [ 4, -5, -1, 2, 1, -3 ], [ 4, -5, 0, 1, 1, -2 ], [ 3, -5, 0, 2, 1, -2 ] ], 0.875 ], + [ [ [ 2, -5, -1, 2, 1, -2 ], [ 4, -5, -1, 2, 1, -3 ], [ 4, -5, 0, 1, 1, -2 ], [ 4, -6, -1, 2, 1, -2 ] ], 1.75 ], + [ [ [ 2, -5, -1, 2, 1, -2 ], [ 4, -5, -1, 2, 1, -3 ], [ 3, -4, -1, 2, 1, -2 ], [ 4, -6, -1, 2, 1, -2 ] ], 0.875 ] + ], + [ + [ [ [ 2, -5, -1, 2, 1, -2 ], [ 4, -5, -1, 2, 1, -3 ], [ 3, -4, -1, 2, 1, -2 ], [ 5, -5, -1, 1, 1, -3 ] ], 1.125 ], + [ [ [ 2, -5, -1, 2, 1, -2 ], [ 4, -5, -1, 2, 1, -3 ], [ 4, -6, -1, 2, 1, -2 ], [ 5, -5, -1, 1, 1, -3 ] ], 1 ] + ], + [ + [ [ [ 2, -5, -1, 2, 1, -2 ], [ 4, -5, -1, 2, 1, -3 ], [ 4, -6, -1, 2, 1, -2 ], [ 3, -6, -1, 3, 1, -2 ] ], 0.625 ], + [ [ [ 3, -6, -2, 2, 1, -2 ], [ 4, -5, -1, 2, 1, -3 ], [ 4, -6, -1, 2, 1, -2 ], [ 3, -6, -1, 3, 1, -2 ] ], 0.75 ], + [ [ [ 3, -6, -2, 2, 1, -2 ], [ 2, -6, -1, 2, 1, -1 ], [ 4, -6, -1, 2, 1, -2 ], [ 3, -6, -1, 3, 1, -2 ] ], 0.5 ] + ], + [ + [ [ [ 3, -6, -2, 2, 1, -2 ], [ 4, -6, -2, 1, 1, -2 ], [ 4, -6, -1, 2, 1, -2 ], [ 3, -6, -1, 3, 1, -2 ] ], 1.5 ], + [ [ [ 3, -6, -2, 2, 1, -2 ], [ 4, -6, -2, 1, 1, -2 ], [ 4, -6, -1, 2, 1, -2 ], [ 5, -6, -2, 2, 1, -3 ] ], 0.75 ], + [ [ [ 3, -6, -2, 2, 1, -2 ], [ 4, -6, -2, 1, 1, -2 ], [ 5, -7, -2, 2, 1, -2 ], [ 5, -6, -2, 2, 1, -3 ] ], 0.875 ] + ], + [ + [ [ [ 3, -6, -2, 2, 1, -2 ], [ 4, -6, -2, 2, 1, -3 ], [ 5, -7, -2, 2, 1, -2 ], [ 5, -6, -2, 2, 1, -3 ] ], 1 ], + [ [ [ 3, -6, -2, 2, 1, -2 ], [ 4, -6, -2, 2, 1, -3 ], [ 5, -7, -2, 2, 1, -2 ], [ 4, -6, -2, 2, 2, -2 ] ], 0.5 ], + [ [ [ 3, -6, -2, 2, 1, -2 ], [ 4, -6, -2, 2, 1, -3 ], [ 5, -6, -2, 2, 0, -2 ], [ 4, -6, -2, 2, 2, -2 ] ], 1.125 ] + ], + [ + [ [ [ 3, -6, -2, 2, 1, -2 ], [ 3, -6, -2, 2, 2, -2 ], [ 5, -6, -2, 2, 0, -2 ], [ 4, -6, -2, 2, 2, -2 ] ], 1.75 ], + [ [ [ 3, -6, -2, 2, 1, -2 ], [ 3, -6, -2, 2, 2, -2 ], [ 5, -6, -2, 2, 0, -2 ], [ 5, -6, -2, 1, 1, -2 ] ], 0.5 ], + [ [ [ 3, -6, -2, 2, 1, -2 ], [ 3, -6, -2, 2, 2, -2 ], [ 4, -6, -2, 2, 2, -2 ], [ 5, -6, -2, 1, 1, -2 ] ], 1.75 ] + ], + [ + [ [ [ 3, -6, -2, 2, 1, -2 ], [ 5, -7, -2, 1, 1, -2 ], [ 4, -6, -2, 2, 2, -2 ], [ 5, -6, -2, 1, 1, -2 ] ], 0.875 ] + ], + [ + [ [ [ 3, -6, -2, 2, 1, -2 ], [ 5, -7, -2, 1, 1, -2 ], [ 6, -7, -2, 1, 0, -2 ], [ 5, -6, -2, 1, 1, -2 ] ], 1.25 ] + ], + [ + [ [ [ 3, -6, -2, 2, 1, -2 ], [ 5, -7, -2, 1, 1, -2 ], [ 6, -7, -3, 1, 1, -2 ], [ 5, -6, -2, 1, 1, -2 ] ], 1.625 ], + [ [ [ 3, -6, -2, 2, 1, -2 ], [ 5, -7, -2, 1, 1, -2 ], [ 6, -7, -3, 1, 1, -2 ], [ 5, -7, -2, 1, 1, -1 ] ], 1.375 ], + [ [ [ 5, -7, -2, 1, 0, -2 ], [ 5, -7, -2, 1, 1, -2 ], [ 6, -7, -3, 1, 1, -2 ], [ 5, -7, -2, 1, 1, -1 ] ], 1.375 ] + ], + [ + [ [ [ 5, -7, -2, 1, 0, -2 ], [ 5, -7, -2, 1, 1, -2 ], [ 7, -7, -2, 1, 0, -3 ], [ 5, -7, -2, 1, 1, -1 ] ], 1.5 ], + [ [ [ 5, -7, -2, 1, 0, -2 ], [ 5, -6, -2, 1, 0, -2 ], [ 7, -7, -2, 1, 0, -3 ], [ 5, -7, -2, 1, 1, -1 ] ], 0.875 ] + ], + [ + [ [ [ 5, -7, -2, 1, 0, -2 ], [ 5, -6, -2, 1, 0, -2 ], [ 7, -7, -2, 1, 0, -3 ], [ 5, -6, -2, 1, 0, -1 ] ], 0.75 ], + [ [ [ 6, -8, -2, 1, 0, -3 ], [ 5, -6, -2, 1, 0, -2 ], [ 7, -7, -2, 1, 0, -3 ], [ 5, -6, -2, 1, 0, -1 ] ], 1.75 ] + ], + [ + [ [ [ 6, -8, -2, 1, 0, -3 ], [ 5, -6, -2, 1, 0, -2 ], [ 5, -6, -2, 2, 0, -2 ], [ 5, -6, -2, 1, 0, -1 ] ], 0.5 ] + ], + [ + [ [ [ 6, -8, -2, 1, 0, -3 ], [ 5, -6, -2, 1, 0, -2 ], [ 5, -6, -2, 2, 0, -2 ], [ 6, -6, -2, 1, -1, -2 ] ], 1.375 ], + [ [ [ 6, -8, -2, 1, 0, -3 ], [ 5, -6, -2, 1, 0, -2 ], [ 6, -6, -3, 1, 0, -2 ], [ 6, -6, -2, 1, -1, -2 ] ], 1.25 ] + ], + [ + [ [ [ 5, -6, -3, 1, -1, -2 ], [ 5, -6, -2, 1, 0, -2 ], [ 6, -6, -3, 1, 0, -2 ], [ 6, -6, -2, 1, -1, -2 ] ], 1.75 ], + [ [ [ 5, -6, -3, 1, -1, -2 ], [ 5, -5, -2, 1, -1, -2 ], [ 6, -6, -3, 1, 0, -2 ], [ 6, -6, -2, 1, -1, -2 ] ], 1.375 ], + [ [ [ 5, -6, -3, 1, -1, -2 ], [ 5, -5, -2, 1, -1, -2 ], [ 4, -5, -2, 1, -1, -2 ], [ 6, -6, -2, 1, -1, -2 ] ], 1.25 ] + ], + [ + [ [ [ 5, -6, -3, 1, -1, -2 ], [ 6, -6, -3, 1, -1, -2 ], [ 4, -5, -2, 1, -1, -2 ], [ 6, -6, -2, 1, -1, -2 ] ], 1.375 ], + [ [ [ 4, -6, -2, 2, -1, -2 ], [ 6, -6, -3, 1, -1, -2 ], [ 4, -5, -2, 1, -1, -2 ], [ 6, -6, -2, 1, -1, -2 ] ], 1.125 ], + [ [ [ 4, -6, -2, 2, -1, -2 ], [ 6, -6, -3, 1, -1, -2 ], [ 4, -6, -2, 1, -1, -1 ], [ 6, -6, -2, 1, -1, -2 ] ], 1.75 ] + ], + [ + [ [ [ 4, -6, -2, 2, -1, -2 ], [ 5, -6, -2, 2, -1, -3 ], [ 4, -6, -2, 1, -1, -1 ], [ 6, -6, -2, 1, -1, -2 ] ], 1.625 ], + [ [ [ 4, -6, -2, 2, -1, -2 ], [ 5, -6, -2, 2, -1, -3 ], [ 4, -6, -2, 1, -1, -1 ], [ 5, -6, -1, 2, -1, -2 ] ], 0.875 ], + [ [ [ 4, -6, -2, 2, -1, -2 ], [ 5, -6, -2, 2, -1, -3 ], [ 3, -6, -2, 3, -1, -2 ], [ 5, -6, -1, 2, -1, -2 ] ], 1.625 ] + ], + [ + [ [ [ 4, -6, -2, 2, -1, -2 ], [ 5, -6, -2, 2, -1, -3 ], [ 3, -5, -1, 2, -1, -2 ], [ 5, -6, -1, 2, -1, -2 ] ], 0.875 ], + [ [ [ 3, -6, -1, 3, -1, -2 ], [ 5, -6, -2, 2, -1, -3 ], [ 3, -5, -1, 2, -1, -2 ], [ 5, -6, -1, 2, -1, -2 ] ], 1.375 ] + ], + [ + [ [ [ 3, -6, -1, 3, -1, -2 ], [ 4, -6, 0, 2, -1, -2 ], [ 3, -5, -1, 2, -1, -2 ], [ 5, -6, -1, 2, -1, -2 ] ], 1.25 ], + [ [ [ 3, -6, -1, 3, -1, -2 ], [ 4, -6, 0, 2, -1, -2 ], [ 4, -6, -2, 2, -1, -2 ], [ 5, -6, -1, 2, -1, -2 ] ], 1.25 ], + [ [ [ 3, -5, -1, 2, -1, -2 ], [ 4, -6, 0, 2, -1, -2 ], [ 4, -6, -2, 2, -1, -2 ], [ 5, -6, -1, 2, -1, -2 ] ], 1.25 ] + ], + [ + [ [ [ 3, -5, -1, 2, -1, -2 ], [ 4, -6, 0, 2, -1, -2 ], [ 4, -5, -1, 2, -1, -3 ], [ 5, -6, -1, 2, -1, -2 ] ], 1.5 ], + [ [ [ 3, -5, -1, 2, -1, -2 ], [ 5, -7, -1, 2, -1, -2 ], [ 4, -5, -1, 2, -1, -3 ], [ 5, -6, -1, 2, -1, -2 ] ], 1.125 ] + ], + [ + [ [ [ 3, -5, -1, 2, -1, -2 ], [ 5, -7, -1, 2, -1, -2 ], [ 4, -5, -1, 2, -1, -3 ], [ 5, -7, 0, 2, -1, -2 ] ], 0.75 ], + [ [ [ 3, -5, -1, 2, -1, -2 ], [ 5, -7, -1, 2, -1, -2 ], [ 4, -6, -1, 2, -1, -2 ], [ 5, -7, 0, 2, -1, -2 ] ], 1.5 ], + [ [ [ 5, -7, -1, 2, -1, -3 ], [ 5, -7, -1, 2, -1, -2 ], [ 4, -6, -1, 2, -1, -2 ], [ 5, -7, 0, 2, -1, -2 ] ], 1.625 ] + ], + [ + [ [ [ 5, -7, -1, 2, -1, -3 ], [ 4, -7, 0, 3, -1, -2 ], [ 4, -6, -1, 2, -1, -2 ], [ 5, -7, 0, 2, -1, -2 ] ], 1.375 ], + [ [ [ 5, -7, -1, 2, -1, -3 ], [ 4, -7, 0, 3, -1, -2 ], [ 6, -8, -1, 2, -1, -3 ], [ 5, -7, 0, 2, -1, -2 ] ], 0.375 ] + ], + [ + [ [ [ 5, -7, -1, 2, -1, -3 ], [ 4, -7, 0, 3, -1, -2 ], [ 3, -7, 0, 3, -1, -1 ], [ 5, -7, 0, 2, -1, -2 ] ], 1.125 ], + [ [ [ 4, -7, 0, 2, -1, -2 ], [ 4, -7, 0, 3, -1, -2 ], [ 3, -7, 0, 3, -1, -1 ], [ 5, -7, 0, 2, -1, -2 ] ], 0.875 ], + [ [ [ 4, -7, 0, 2, -1, -2 ], [ 4, -7, 0, 3, -1, -2 ], [ 3, -7, 0, 3, -1, -1 ], [ 5, -7, 0, 3, -1, -3 ] ], 1.125 ] + ], + [ + [ [ [ 3, -7, 0, 3, -1, -2 ], [ 4, -7, 0, 3, -1, -2 ], [ 3, -7, 0, 3, -1, -1 ], [ 5, -7, 0, 3, -1, -3 ] ], 0.75 ], + [ [ [ 3, -7, 0, 3, -1, -2 ], [ 4, -7, 0, 3, -1, -2 ], [ 3, -7, 0, 3, -1, -1 ], [ 5, -8, 0, 3, -1, -2 ] ], 0.625 ], + [ [ [ 3, -7, 0, 3, -1, -2 ], [ 4, -7, 0, 3, -1, -2 ], [ 3, -7, 0, 4, -1, -2 ], [ 5, -8, 0, 3, -1, -2 ] ], 1.125 ] + ], + [ + [ [ [ 3, -7, 0, 3, -1, -2 ], [ 4, -7, 0, 4, -1, -3 ], [ 3, -7, 0, 4, -1, -2 ], [ 5, -8, 0, 3, -1, -2 ] ], 0.5 ] + ], + [ + [ [ [ 3, -7, 0, 3, -1, -2 ], [ 4, -7, -1, 3, -1, -2 ], [ 3, -7, 0, 4, -1, -2 ], [ 5, -8, 0, 3, -1, -2 ] ], 0.625 ], + [ [ [ 3, -7, 0, 3, -1, -2 ], [ 4, -7, -1, 3, -1, -2 ], [ 4, -8, 0, 3, 0, -2 ], [ 5, -8, 0, 3, -1, -2 ] ], 1.625 ] + ], + [ + [ [ [ 3, -7, 0, 3, -1, -2 ], [ 4, -7, -1, 3, -1, -2 ], [ 4, -8, 0, 3, 0, -2 ], [ 5, -7, 0, 3, -2, -2 ] ], 1.125 ], + [ [ [ 3, -7, 0, 3, -1, -2 ], [ 4, -7, -1, 3, -1, -2 ], [ 4, -7, 0, 3, -1, -2 ], [ 5, -7, 0, 3, -2, -2 ] ], 1.625 ], + [ [ [ 3, -7, 0, 3, -1, -2 ], [ 3, -7, 0, 4, -1, -2 ], [ 4, -7, 0, 3, -1, -2 ], [ 5, -7, 0, 3, -2, -2 ] ], 1 ] + ], + [ + [ [ [ 3, -7, 0, 3, -1, -2 ], [ 3, -7, 0, 4, -1, -2 ], [ 4, -7, 0, 4, -1, -3 ], [ 5, -7, 0, 3, -2, -2 ] ], 0.875 ] + ], + [ + [ [ [ 4, -7, 0, 3, -3, -2 ], [ 3, -7, 0, 4, -1, -2 ], [ 4, -7, 0, 4, -1, -3 ], [ 5, -7, 0, 3, -2, -2 ] ], 1.625 ], + [ [ [ 4, -7, 0, 3, -3, -2 ], [ 3, -7, 0, 3, -1, -2 ], [ 4, -7, 0, 4, -1, -3 ], [ 5, -7, 0, 3, -2, -2 ] ], 1 ] + ], + [ + [ [ [ 4, -7, 0, 3, -3, -2 ], [ 3, -7, 0, 4, -1, -3 ], [ 4, -7, 0, 4, -1, -3 ], [ 5, -7, 0, 3, -2, -2 ] ], 0.75 ], + [ [ [ 4, -7, 0, 3, -3, -2 ], [ 3, -7, 0, 4, -1, -3 ], [ 4, -7, 0, 4, -1, -3 ], [ 5, -7, 0, 4, -1, -4 ] ], 1.5 ] + ], + [ + [ [ [ 4, -7, 0, 3, -3, -2 ], [ 3, -7, 0, 4, -1, -3 ], [ 3, -6, 0, 4, -1, -3 ], [ 5, -7, 0, 4, -1, -4 ] ], 1 ], + [ [ [ 3, -7, 0, 5, -1, -4 ], [ 3, -7, 0, 4, -1, -3 ], [ 3, -6, 0, 4, -1, -3 ], [ 5, -7, 0, 4, -1, -4 ] ], 0.625 ] + ], + [ + [ [ [ 3, -7, 0, 5, -1, -4 ], [ 3, -7, 0, 4, -1, -3 ], [ 5, -8, 0, 4, -1, -4 ], [ 5, -7, 0, 4, -1, -4 ] ], 1 ], + [ [ [ 3, -7, 0, 5, -1, -4 ], [ 3, -7, 0, 4, 0, -4 ], [ 5, -8, 0, 4, -1, -4 ], [ 5, -7, 0, 4, -1, -4 ] ], 0.5 ] + ], + [ + [ [ [ 3, -7, 0, 5, -1, -4 ], [ 3, -7, 0, 4, 0, -4 ], [ 5, -8, 0, 4, -1, -4 ], [ 4, -7, 1, 5, -1, -4 ] ], 1.25 ] + ], + [ + [ [ [ 4, -8, 0, 4, 0, -4 ], [ 3, -7, 0, 4, 0, -4 ], [ 5, -8, 0, 4, -1, -4 ], [ 4, -7, 1, 5, -1, -4 ] ], 1.75 ], + [ [ [ 4, -8, 0, 4, 0, -4 ], [ 3, -7, 0, 4, 0, -4 ], [ 3, -7, 0, 4, 0, -3 ], [ 4, -7, 1, 5, -1, -4 ] ], 1.75 ], + [ [ [ 4, -8, 0, 4, 0, -4 ], [ 3, -7, 0, 4, 0, -4 ], [ 3, -7, 0, 4, 0, -3 ], [ 4, -7, 0, 4, 1, -4 ] ], 1 ] + ], + [ + [ [ [ 4, -8, 0, 4, 0, -4 ], [ 3, -7, 0, 4, 0, -4 ], [ 3, -7, 0, 4, 2, -4 ], [ 4, -7, 0, 4, 1, -4 ] ], 1.25 ], + [ [ [ 4, -8, 0, 4, 0, -4 ], [ 3, -7, -1, 4, 1, -4 ], [ 3, -7, 0, 4, 2, -4 ], [ 4, -7, 0, 4, 1, -4 ] ], 0.625 ], + [ [ [ 2, -7, 0, 5, 1, -4 ], [ 3, -7, -1, 4, 1, -4 ], [ 3, -7, 0, 4, 2, -4 ], [ 4, -7, 0, 4, 1, -4 ] ], 0.875 ] + ], + [ + [ [ [ 2, -7, 0, 5, 1, -4 ], [ 3, -7, -1, 4, 1, -4 ], [ 3, -7, 0, 4, 2, -4 ], [ 3, -7, 0, 4, 2, -3 ] ], 0.875 ] + ], + [ + [ [ [ 2, -7, 0, 5, 1, -4 ], [ 3, -7, -1, 4, 1, -4 ], [ 3, -7, 0, 4, 2, -4 ], [ 4, -8, 0, 4, 2, -4 ] ], 0.5 ], + [ [ [ 2, -7, 0, 5, 1, -4 ], [ 3, -7, 0, 4, 2, -5 ], [ 3, -7, 0, 4, 2, -4 ], [ 4, -8, 0, 4, 2, -4 ] ], 1.375 ], + [ [ [ 2, -7, 0, 4, 3, -4 ], [ 3, -7, 0, 4, 2, -5 ], [ 3, -7, 0, 4, 2, -4 ], [ 4, -8, 0, 4, 2, -4 ] ], 0.5 ] + ], + [ + [ [ [ 2, -7, 0, 4, 3, -4 ], [ 3, -7, 0, 4, 2, -5 ], [ 3, -7, 0, 4, 2, -4 ], [ 3, -6, 0, 4, 2, -4 ] ], 1.375 ], + [ [ [ 2, -7, 0, 4, 3, -4 ], [ 3, -8, 0, 4, 2, -4 ], [ 3, -7, 0, 4, 2, -4 ], [ 3, -6, 0, 4, 2, -4 ] ], 0.375 ] + ], + [ + [ [ [ 1, -5, 0, 4, 2, -4 ], [ 3, -8, 0, 4, 2, -4 ], [ 3, -7, 0, 4, 2, -4 ], [ 3, -6, 0, 4, 2, -4 ] ], 1.375 ], + [ [ [ 1, -5, 0, 4, 2, -4 ], [ 2, -6, 0, 4, 2, -4 ], [ 3, -7, 0, 4, 2, -4 ], [ 3, -6, 0, 4, 2, -4 ] ], 1.125 ], + [ [ [ 1, -5, 0, 4, 2, -4 ], [ 2, -6, 0, 4, 2, -4 ], [ 2, -5, 0, 4, 2, -4 ], [ 3, -6, 0, 4, 2, -4 ] ], 1.5 ] + ], + [ + [ [ [ 2, -5, 0, 3, 2, -4 ], [ 2, -6, 0, 4, 2, -4 ], [ 2, -5, 0, 4, 2, -4 ], [ 3, -6, 0, 4, 2, -4 ] ], 1.5 ], + [ [ [ 2, -5, 0, 3, 2, -4 ], [ 1, -4, 0, 4, 2, -4 ], [ 2, -5, 0, 4, 2, -4 ], [ 3, -6, 0, 4, 2, -4 ] ], 1.125 ], + [ [ [ 2, -5, 0, 3, 2, -4 ], [ 1, -4, 0, 4, 2, -4 ], [ 2, -5, 0, 4, 2, -4 ], [ 3, -5, 0, 4, 1, -4 ] ], 0.625 ] + ], + [ + [ [ [ 2, -5, 0, 3, 2, -4 ], [ 1, -4, 0, 4, 2, -4 ], [ 2, -4, 0, 4, 1, -4 ], [ 3, -5, 0, 4, 1, -4 ] ], 1.25 ] + ], + [ + [ [ [ 2, -5, 0, 3, 2, -4 ], [ 3, -5, 0, 3, 1, -4 ], [ 2, -4, 0, 4, 1, -4 ], [ 3, -5, 0, 4, 1, -4 ] ], 1.75 ], + [ [ [ 2, -5, 0, 3, 2, -4 ], [ 3, -5, 0, 3, 1, -4 ], [ 3, -5, 0, 3, 2, -5 ], [ 3, -5, 0, 4, 1, -4 ] ], 1.625 ], + [ [ [ 2, -5, 0, 3, 2, -4 ], [ 3, -5, 0, 3, 1, -4 ], [ 3, -5, 0, 3, 2, -5 ], [ 3, -5, 0, 3, 2, -4 ] ], 0.625 ] + ], + [ + [ [ [ 3, -5, 0, 3, 0, -4 ], [ 3, -5, 0, 3, 1, -4 ], [ 3, -5, 0, 3, 2, -5 ], [ 3, -5, 0, 3, 2, -4 ] ], 1.625 ], + [ [ [ 3, -5, 0, 3, 0, -4 ], [ 3, -5, 0, 3, 1, -4 ], [ 3, -6, 0, 3, 2, -4 ], [ 3, -5, 0, 3, 2, -4 ] ], 1 ] + ], + [ + [ [ [ 3, -5, 0, 3, 0, -4 ], [ 3, -5, 0, 3, 1, -4 ], [ 3, -6, 0, 3, 2, -4 ], [ 3, -6, 0, 4, 2, -4 ] ], 1.375 ], + [ [ [ 2, -6, 1, 3, 2, -4 ], [ 3, -5, 0, 3, 1, -4 ], [ 3, -6, 0, 3, 2, -4 ], [ 3, -6, 0, 4, 2, -4 ] ], 1 ], + [ [ [ 2, -6, 1, 3, 2, -4 ], [ 3, -6, 1, 3, 2, -4 ], [ 3, -6, 0, 3, 2, -4 ], [ 3, -6, 0, 4, 2, -4 ] ], 0.75 ] + ], + [ + [ [ [ 2, -6, 1, 3, 2, -4 ], [ 3, -6, 0, 3, 3, -4 ], [ 3, -6, 0, 3, 2, -4 ], [ 3, -6, 0, 4, 2, -4 ] ], 0.875 ] + ], + [ + [ [ [ 2, -6, 0, 3, 3, -4 ], [ 3, -6, 0, 3, 3, -4 ], [ 3, -6, 0, 3, 2, -4 ], [ 3, -6, 0, 4, 2, -4 ] ], 1.5 ], + [ [ [ 2, -6, 0, 3, 3, -4 ], [ 3, -6, 0, 3, 3, -4 ], [ 3, -6, -1, 3, 3, -4 ], [ 3, -6, 0, 4, 2, -4 ] ], 0.5 ], + [ [ [ 2, -6, 0, 3, 3, -4 ], [ 3, -6, 0, 3, 3, -4 ], [ 3, -6, -1, 3, 3, -4 ], [ 3, -6, 0, 3, 4, -4 ] ], 1.5 ] + ], + [ + [ [ [ 2, -6, 0, 3, 3, -4 ], [ 3, -6, -1, 3, 4, -4 ], [ 3, -6, -1, 3, 3, -4 ], [ 3, -6, 0, 3, 4, -4 ] ], 1.125 ] + ], + [ + [ [ [ 2, -6, 0, 3, 3, -4 ], [ 4, -6, -2, 3, 3, -4 ], [ 3, -6, -1, 3, 3, -4 ], [ 3, -6, 0, 3, 4, -4 ] ], 1 ] + ], + [ + [ [ [ 2, -6, 0, 3, 3, -4 ], [ 4, -6, -2, 3, 3, -4 ], [ 3, -6, -1, 3, 3, -4 ], [ 3, -6, -2, 4, 3, -4 ] ], 1.625 ], + [ [ [ 2, -6, 0, 3, 3, -4 ], [ 4, -6, -2, 3, 3, -4 ], [ 3, -6, -2, 3, 4, -4 ], [ 3, -6, -2, 4, 3, -4 ] ], 0.625 ], + [ [ [ 2, -6, -2, 4, 3, -4 ], [ 4, -6, -2, 3, 3, -4 ], [ 3, -6, -2, 3, 4, -4 ], [ 3, -6, -2, 4, 3, -4 ] ], 1.625 ] + ], + [ + [ [ [ 2, -6, -2, 4, 3, -4 ], [ 3, -6, -1, 4, 3, -4 ], [ 3, -6, -2, 3, 4, -4 ], [ 3, -6, -2, 4, 3, -4 ] ], 1.375 ], + [ [ [ 2, -6, -2, 4, 3, -4 ], [ 3, -6, -1, 4, 3, -4 ], [ 2, -6, -2, 5, 3, -4 ], [ 3, -6, -2, 4, 3, -4 ] ], 0.5 ], + [ [ [ 1, -6, -2, 4, 3, -3 ], [ 3, -6, -1, 4, 3, -4 ], [ 2, -6, -2, 5, 3, -4 ], [ 3, -6, -2, 4, 3, -4 ] ], 1.625 ] + ], + [ + [ [ [ 1, -6, -2, 4, 3, -3 ], [ 2, -6, -2, 4, 3, -4 ], [ 2, -6, -2, 5, 3, -4 ], [ 3, -6, -2, 4, 3, -4 ] ], 1.125 ], + [ [ [ 1, -6, -2, 4, 3, -3 ], [ 2, -6, -2, 4, 3, -4 ], [ 3, -6, -2, 4, 3, -5 ], [ 3, -6, -2, 4, 3, -4 ] ], 1.125 ] + ], + [ + [ [ [ 1, -6, -2, 4, 3, -3 ], [ 2, -6, -2, 4, 3, -4 ], [ 3, -6, -2, 4, 3, -5 ], [ 3, -7, -2, 4, 3, -3 ] ], 1 ], + [ [ [ 1, -6, -2, 4, 3, -3 ], [ 2, -6, -2, 4, 3, -4 ], [ 1, -6, -2, 4, 3, -2 ], [ 3, -7, -2, 4, 3, -3 ] ], 0.875 ], + [ [ [ 1, -6, -2, 4, 3, -3 ], [ 2, -7, -2, 4, 3, -3 ], [ 1, -6, -2, 4, 3, -2 ], [ 3, -7, -2, 4, 3, -3 ] ], 1.125 ] + ], + [ + [ [ [ 1, -6, -2, 4, 3, -3 ], [ 3, -7, -2, 3, 3, -3 ], [ 1, -6, -2, 4, 3, -2 ], [ 3, -7, -2, 4, 3, -3 ] ], 1.75 ], + [ [ [ 1, -7, -2, 5, 3, -3 ], [ 3, -7, -2, 3, 3, -3 ], [ 1, -6, -2, 4, 3, -2 ], [ 3, -7, -2, 4, 3, -3 ] ], 1.5 ], + [ [ [ 1, -7, -2, 5, 3, -3 ], [ 3, -7, -2, 3, 3, -3 ], [ 2, -7, -2, 4, 4, -3 ], [ 3, -7, -2, 4, 3, -3 ] ], 0.75 ] + ], + [ + [ [ [ 1, -7, -2, 5, 3, -3 ], [ 3, -7, -2, 3, 3, -3 ], [ 2, -6, -2, 4, 3, -3 ], [ 3, -7, -2, 4, 3, -3 ] ], 0.625 ] + ], + [ + [ [ [ 1, -6, -1, 4, 3, -3 ], [ 3, -7, -2, 3, 3, -3 ], [ 2, -6, -2, 4, 3, -3 ], [ 3, -7, -2, 4, 3, -3 ] ], 1.375 ], + [ [ [ 1, -6, -1, 4, 3, -3 ], [ 3, -7, -2, 4, 3, -4 ], [ 2, -6, -2, 4, 3, -3 ], [ 3, -7, -2, 4, 3, -3 ] ], 1.625 ] + ], + [ + [ [ [ 1, -6, -1, 4, 3, -3 ], [ 3, -7, -2, 4, 3, -4 ], [ 2, -6, -1, 4, 3, -4 ], [ 3, -7, -2, 4, 3, -3 ] ], 0.875 ], + [ [ [ 1, -6, -1, 4, 3, -3 ], [ 3, -7, -2, 4, 3, -4 ], [ 2, -6, -1, 4, 3, -4 ], [ 3, -6, -1, 3, 3, -3 ] ], 1.625 ], + [ [ [ 1, -6, -1, 4, 3, -3 ], [ 2, -6, -1, 4, 2, -3 ], [ 2, -6, -1, 4, 3, -4 ], [ 3, -6, -1, 3, 3, -3 ] ], 1.375 ] + ], + [ + [ [ [ 1, -6, -1, 4, 3, -3 ], [ 0, -6, -1, 4, 3, -2 ], [ 2, -6, -1, 4, 3, -4 ], [ 3, -6, -1, 3, 3, -3 ] ], 1.5 ] + ], + [ + [ [ [ 1, -5, -1, 3, 3, -3 ], [ 0, -6, -1, 4, 3, -2 ], [ 2, -6, -1, 4, 3, -4 ], [ 3, -6, -1, 3, 3, -3 ] ], 1.625 ], + [ [ [ 1, -5, -1, 3, 3, -3 ], [ 0, -6, -1, 4, 3, -2 ], [ 3, -6, -1, 3, 3, -4 ], [ 3, -6, -1, 3, 3, -3 ] ], 1.625 ] + ], + [ + [ [ [ 1, -5, -1, 3, 3, -3 ], [ 1, -6, -1, 3, 3, -2 ], [ 3, -6, -1, 3, 3, -4 ], [ 3, -6, -1, 3, 3, -3 ] ], 1.875 ], + [ [ [ 1, -5, -1, 3, 3, -3 ], [ 1, -6, -1, 3, 3, -2 ], [ 1, -6, -1, 4, 3, -3 ], [ 3, -6, -1, 3, 3, -3 ] ], 1.5 ], + [ [ [ 2, -6, -2, 3, 3, -3 ], [ 1, -6, -1, 3, 3, -2 ], [ 1, -6, -1, 4, 3, -3 ], [ 3, -6, -1, 3, 3, -3 ] ], 0.625 ] + ], + [ + [ [ [ 2, -6, -1, 3, 2, -3 ], [ 1, -6, -1, 3, 3, -2 ], [ 1, -6, -1, 4, 3, -3 ], [ 3, -6, -1, 3, 3, -3 ] ], 1 ] + ], + [ + [ [ [ 0, -6, -1, 5, 3, -3 ], [ 1, -6, -1, 3, 3, -2 ], [ 1, -6, -1, 4, 3, -3 ], [ 3, -6, -1, 3, 3, -3 ] ], 1.75 ] + ], + [ + [ [ [ 0, -6, -1, 5, 3, -3 ], [ 1, -6, -1, 3, 3, -2 ], [ 2, -6, -1, 2, 3, -2 ], [ 3, -6, -1, 3, 3, -3 ] ], 0.625 ], + [ [ [ 1, -6, -1, 4, 3, -3 ], [ 1, -6, -1, 3, 3, -2 ], [ 2, -6, -1, 2, 3, -2 ], [ 3, -6, -1, 3, 3, -3 ] ], 0.875 ] + ], + [ + [ [ [ 1, -5, -1, 2, 3, -2 ], [ 1, -6, -1, 3, 3, -2 ], [ 2, -6, -1, 2, 3, -2 ], [ 3, -6, -1, 3, 3, -3 ] ], 0.875 ], + [ [ [ 1, -5, -1, 2, 3, -2 ], [ 1, -6, -1, 3, 3, -2 ], [ 2, -6, -1, 2, 3, -2 ], [ 4, -6, -1, 1, 3, -2 ] ], 1 ] + ], + [ + [ [ [ 3, -6, -1, 1, 2, -2 ], [ 1, -6, -1, 3, 3, -2 ], [ 2, -6, -1, 2, 3, -2 ], [ 4, -6, -1, 1, 3, -2 ] ], 1.375 ], + [ [ [ 3, -6, -1, 1, 2, -2 ], [ 2, -6, -1, 1, 3, -1 ], [ 2, -6, -1, 2, 3, -2 ], [ 4, -6, -1, 1, 3, -2 ] ], 0.5 ], + [ [ [ 3, -6, -1, 1, 2, -2 ], [ 2, -6, -1, 1, 3, -1 ], [ 3, -6, -1, 1, 3, -2 ], [ 4, -6, -1, 1, 3, -2 ] ], 1.5 ] + ], + [ + [ [ [ 3, -6, -1, 1, 2, -2 ], [ 2, -6, -1, 1, 3, -1 ], [ 3, -6, -1, 1, 3, -2 ], [ 3, -6, -1, 2, 3, -2 ] ], 0.625 ], + [ [ [ 3, -6, -2, 1, 3, -2 ], [ 2, -6, -1, 1, 3, -1 ], [ 3, -6, -1, 1, 3, -2 ], [ 3, -6, -1, 2, 3, -2 ] ], 1.75 ] + ], + [ + [ [ [ 3, -6, -2, 1, 3, -2 ], [ 2, -6, -1, 1, 3, -1 ], [ 3, -6, -2, 1, 4, -2 ], [ 3, -6, -1, 2, 3, -2 ] ], 1.25 ], + [ [ [ 3, -6, -2, 1, 3, -2 ], [ 4, -6, -2, 0, 3, -2 ], [ 3, -6, -2, 1, 4, -2 ], [ 3, -6, -1, 2, 3, -2 ] ], 1.625 ], + [ [ [ 3, -6, -2, 1, 3, -2 ], [ 4, -6, -2, 0, 3, -2 ], [ 3, -6, -2, 1, 4, -2 ], [ 5, -6, -2, 1, 3, -3 ] ], 0.875 ] + ], + [ + [ [ [ 3, -6, -2, 1, 3, -2 ], [ 4, -6, -2, 0, 3, -2 ], [ 3, -6, -2, 1, 4, -2 ], [ 4, -6, -2, 1, 3, -2 ] ], 1.125 ], + [ [ [ 3, -7, -2, 0, 3, -2 ], [ 4, -6, -2, 0, 3, -2 ], [ 3, -6, -2, 1, 4, -2 ], [ 4, -6, -2, 1, 3, -2 ] ], 0.375 ] + ], + [ + [ [ [ 3, -7, -2, 0, 3, -2 ], [ 2, -6, -2, 2, 3, -2 ], [ 3, -6, -2, 1, 4, -2 ], [ 4, -6, -2, 1, 3, -2 ] ], 1 ] + ], + [ + [ [ [ 1, -6, -2, 2, 3, -2 ], [ 2, -6, -2, 2, 3, -2 ], [ 3, -6, -2, 1, 4, -2 ], [ 4, -6, -2, 1, 3, -2 ] ], 0.5 ] + ], + [ + [ [ [ 2, -6, -2, 1, 2, -2 ], [ 2, -6, -2, 2, 3, -2 ], [ 3, -6, -2, 1, 4, -2 ], [ 4, -6, -2, 1, 3, -2 ] ], 0.875 ] + ], + [ + [ [ [ 2, -6, -2, 1, 2, -2 ], [ 2, -6, -2, 2, 3, -2 ], [ 3, -6, -2, 1, 4, -2 ], [ 4, -6, -2, 2, 3, -3 ] ], 1.125 ], + [ [ [ 2, -6, -2, 1, 2, -2 ], [ 2, -6, -2, 2, 3, -2 ], [ 3, -6, -2, 1, 3, -2 ], [ 4, -6, -2, 2, 3, -3 ] ], 0.5 ] + ], + [ + [ [ [ 2, -6, -2, 1, 2, -2 ], [ 2, -6, -2, 2, 3, -2 ], [ 4, -6, -2, 1, 1, -2 ], [ 4, -6, -2, 2, 3, -3 ] ], 1 ], + [ [ [ 2, -6, -2, 1, 2, -2 ], [ 3, -6, -2, 1, 3, -2 ], [ 4, -6, -2, 1, 1, -2 ], [ 4, -6, -2, 2, 3, -3 ] ], 1.625 ] + ], + [ + [ [ [ 2, -6, -2, 1, 2, -2 ], [ 3, -6, -2, 1, 3, -2 ], [ 4, -6, -2, 1, 1, -2 ], [ 6, -6, -2, 0, 1, -2 ] ], 1.375 ], + [ [ [ 3, -6, -2, 1, 0, -2 ], [ 3, -6, -2, 1, 3, -2 ], [ 4, -6, -2, 1, 1, -2 ], [ 6, -6, -2, 0, 1, -2 ] ], 1.5 ], + [ [ [ 3, -6, -2, 1, 0, -2 ], [ 3, -5, -2, 1, 1, -2 ], [ 4, -6, -2, 1, 1, -2 ], [ 6, -6, -2, 0, 1, -2 ] ], 0.5 ] + ], + [ + [ [ [ 3, -6, -2, 1, 0, -2 ], [ 5, -6, -2, 0, 0, -2 ], [ 4, -6, -2, 1, 1, -2 ], [ 6, -6, -2, 0, 1, -2 ] ], 1.25 ], + [ [ [ 4, -6, -2, 0, 0, -2 ], [ 5, -6, -2, 0, 0, -2 ], [ 4, -6, -2, 1, 1, -2 ], [ 6, -6, -2, 0, 1, -2 ] ], 0.5 ], + [ [ [ 4, -6, -2, 0, 0, -2 ], [ 5, -6, -2, 0, 0, -2 ], [ 5, -6, -2, 0, 1, -2 ], [ 6, -6, -2, 0, 1, -2 ] ], 0.625 ] + ], + [ + [ [ [ 5, -6, -2, -1, 0, -2 ], [ 5, -6, -2, 0, 0, -2 ], [ 5, -6, -2, 0, 1, -2 ], [ 6, -6, -2, 0, 1, -2 ] ], 1.625 ], + [ [ [ 5, -6, -2, -1, 0, -2 ], [ 5, -6, -2, 0, 0, -2 ], [ 5, -5, -2, 0, 0, -2 ], [ 6, -6, -2, 0, 1, -2 ] ], 1.625 ], + [ [ [ 5, -6, -2, -1, 0, -2 ], [ 5, -6, -2, 0, 0, -2 ], [ 5, -5, -2, 0, 0, -2 ], [ 7, -6, -2, 0, -1, -2 ] ], 1 ] + ], + [ + [ [ [ 5, -6, -2, -1, 0, -2 ], [ 4, -4, -2, 0, 0, -2 ], [ 5, -5, -2, 0, 0, -2 ], [ 7, -6, -2, 0, -1, -2 ] ], 1.625 ] + ], + [ + [ [ [ 5, -6, -2, -1, 0, -2 ], [ 4, -4, -2, 0, 0, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 7, -6, -2, 0, -1, -2 ] ], 1 ] + ], + [ + [ [ [ 6, -6, -2, -1, -2, -2 ], [ 4, -4, -2, 0, 0, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 7, -6, -2, 0, -1, -2 ] ], 0.5 ], + [ [ [ 6, -6, -2, -1, -2, -2 ], [ 7, -6, -2, -1, -2, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 7, -6, -2, 0, -1, -2 ] ], 1.375 ], + [ [ [ 6, -6, -2, -1, -2, -2 ], [ 7, -6, -2, -1, -2, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 7, -5, -2, -1, -1, -2 ] ], 1.125 ] + ], + [ + [ [ [ 6, -6, -2, -1, -2, -2 ], [ 7, -6, -3, -1, -1, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 7, -5, -2, -1, -1, -2 ] ], 0.625 ], + [ [ [ 6, -6, -3, -1, -1, -2 ], [ 7, -6, -3, -1, -1, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 7, -5, -2, -1, -1, -2 ] ], 0.875 ] + ], + [ + [ [ [ 6, -6, -3, -1, -1, -2 ], [ 7, -6, -3, -1, -1, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 8, -6, -3, -1, -1, -2 ] ], 0.625 ], + [ [ [ 6, -6, -3, -1, -1, -2 ], [ 8, -6, -3, -2, -1, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 8, -6, -3, -1, -1, -2 ] ], 1.5 ] + ], + [ + [ [ [ 6, -6, -3, -1, -1, -2 ], [ 8, -6, -3, -2, -1, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 7, -6, -2, 0, -1, -2 ] ], 1.125 ] + ], + [ + [ [ [ 6, -6, -3, -1, -1, -2 ], [ 8, -6, -3, -2, -1, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 7, -5, -3, -2, -1, -2 ] ], 0.375 ] + ], + [ + [ [ [ 6, -6, -3, -1, -1, -2 ], [ 8, -6, -3, -2, -1, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 7, -6, -2, -1, -2, -2 ] ], 1.5 ] + ], + [ + [ [ [ 6, -6, -3, -1, -1, -2 ], [ 8, -6, -3, -2, -1, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 6, -6, -2, -1, -1, -1 ] ], 1.25 ] + ], + [ + [ [ [ 6, -6, -3, -1, -1, -2 ], [ 8, -6, -3, -2, -1, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], 1.625 ], + [ [ [ 6, -6, -3, -1, -1, -2 ], [ 7, -6, -2, -1, -2, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], 1.75 ], + [ [ [ 5, -6, -2, 0, -1, -2 ], [ 7, -6, -2, -1, -2, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], 0.5 ] + ], + [ + [ [ [ 5, -6, -2, 0, -1, -2 ], [ 7, -6, -2, -1, -2, -2 ], [ 7, -5, -2, -1, -2, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], 1.5 ] + ], + [ + [ [ [ 5, -6, -2, 0, -1, -2 ], [ 7, -5, -2, -1, -3, -2 ], [ 7, -5, -2, -1, -2, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], 1.375 ], + [ [ [ 5, -5, -2, 0, -2, -2 ], [ 7, -5, -2, -1, -3, -2 ], [ 7, -5, -2, -1, -2, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], 1.25 ] + ], + [ + [ [ [ 5, -5, -2, 0, -2, -2 ], [ 7, -5, -2, -1, -3, -2 ], [ 8, -5, -2, -1, -4, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], 0.75 ], + [ [ [ 5, -5, -2, 0, -2, -2 ], [ 7, -5, -2, -1, -3, -2 ], [ "Rest" ], [ 6, -6, -2, 0, -1, -2 ] ], 1.25 ], + [ [ [ "Rest" ], [ 7, -5, -2, -1, -3, -2 ], [ "Rest" ], [ 6, -6, -2, 0, -1, -2 ] ], 0.5 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 6, -6, -2, 0, -1, -2 ] ], 1.25 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 6.625 ] + ] + ] +], +"last_changes": +[ + [ [ 5, -6, -2, 0, -1, -2 ], [ 7, -6, -2, -1, -2, -2 ], [ 7, -6, -2, -1, -1, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], + [ [ 5, -6, -2, 0, -1, -2 ], [ 7, -6, -2, -1, -2, -2 ], [ 7, -5, -2, -1, -2, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], + [ [ 5, -6, -2, 0, -1, -2 ], [ 7, -5, -2, -1, -3, -2 ], [ 7, -5, -2, -1, -2, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], + [ [ 5, -5, -2, 0, -2, -2 ], [ 7, -5, -2, -1, -3, -2 ], [ 7, -5, -2, -1, -2, -2 ], [ 6, -6, -2, 0, -1, -2 ] ], + [ [ 5, -5, -2, 0, -2, -2 ], [ 7, -5, -2, -1, -3, -2 ], [ 8, -5, -2, -1, -4, -2 ], [ 6, -6, -2, 0, -1, -2 ] ] +], +"cur_uid": "6a9928d6", +"ref_uid": "55f9b81e", +"order_seed": 963124, +"dur_seed": 397683, +"motifs_seed": 845264, +"entrances_probs_vals": [ 0, 0, 0, 0.41, 1.8406593406593, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 0.41, 1.8406593406593, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 0.41, 1.8406593406593, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2430, -293.49845201238 ], [ -869, 1211.1455108359 ], [ -832.19814241486, 1285 ], [ -702, 1211.1455108359 ] ], +"step_probs_vals": [ -1200, 1200, 0.0020576131687243, 0.068181818181818, 0.074074074074074, 0.0625, 0.20576131687243, 0.0625, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61316872427983, 0, 0.98971193415638, 0 ], +"passages_weights": [ 0.48, 0.46, 0.48, 1, 1 ], +"hd_exp": 1.52, +"hd_invert": 0, +"order": +[ + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 3, 1 ], [ 2, 0 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 3 ], [ 0, 2, 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 3, 0 ], [ 2, 1 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 3, 0 ], [ 2, 1 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 3, 0 ], [ 1, 2 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 0, 3 ], [ 1, 2 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 0, 2 ], [ 1, 3 ], [ ] ], + [ [ 3, 1 ], [ 2, 0 ], [ ] ], + [ [ 3, 0 ], [ 2, 1 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 1 ], [ 0, 2, 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 0, 2 ], [ 3, 1 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 0 ], [ 1, 2, 3 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 1 ], [ 0, 2, 3 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 3, 0 ], [ 1, 2 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 2, 1 ], [ 0, 3 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 3, 0 ], [ 2, 1 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 1 ], [ 0, 2, 3 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 0, 2 ], [ 3, 1 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 100, 100 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/6f0f638f/6f0f638f_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/6f0f638f/6f0f638f_code.scd new file mode 100644 index 0000000..c194eef --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/6f0f638f/6f0f638f_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/6f0f638f/6f0f638f_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/6f0f638f/6f0f638f_mus_model.json new file mode 100644 index 0000000..e65877d --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/6f0f638f/6f0f638f_mus_model.json @@ -0,0 +1,105 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, -1, -1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ 0, 0, 0, -1, -1, 0 ], [ "Rest" ], [ 1, 0, 0, -1, -1, 1 ], [ "Rest" ] ], 0 ], + [ [ [ 0, 0, 0, -1, -1, 0 ], [ "Rest" ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 2 ] ], 1.25 ], + [ [ [ 0, 0, 0, -1, -1, 0 ], [ 0, 0, 0, -1, -2, 2 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 2 ] ], 1.5 ], + [ [ [ 0, 0, 0, -1, -1, 0 ], [ 0, -1, 0, -1, -1, 2 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 2 ] ], 2.625 ] + ], + [ + [ [ [ 0, 0, 0, -1, -1, 0 ], [ "Rest" ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 2 ] ], 0 ], + [ [ [ -1, 0, -1, -1, -1, 2 ], [ "Rest" ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 2 ] ], 0 ], + [ [ [ -1, 0, -1, -1, -1, 2 ], [ "Rest" ], [ 1, -1, 0, -1, -1, 2 ], [ 1, 0, 0, -1, -1, 2 ] ], 1.25 ], + [ [ [ -1, 0, -1, -1, -1, 2 ], [ "Rest" ], [ 1, 0, 0, -1, -2, 2 ], [ 1, 0, 0, -1, -1, 2 ] ], 0.75 ], + [ [ [ -1, 0, -1, -1, -1, 2 ], [ "Rest" ], [ 0, 0, 0, -1, 0, 2 ], [ 1, 0, 0, -1, -1, 2 ] ], 1.5 ] + ], + [ + [ [ [ -1, 0, -1, -1, -1, 2 ], [ "Rest" ], [ 0, 0, 0, -1, 0, 2 ], [ "Rest" ] ], 0 ], + [ [ [ -1, 0, 0, -1, 0, 1 ], [ "Rest" ], [ 0, 0, 0, -1, 0, 2 ], [ "Rest" ] ], 0 ], + [ [ [ -1, 0, 0, -1, 0, 1 ], [ -1, 0, 0, -1, 0, 2 ], [ 0, 0, 0, -1, 0, 2 ], [ "Rest" ] ], 1.125 ], + [ [ [ -2, 0, 1, -1, 0, 2 ], [ -1, 0, 0, -1, 0, 2 ], [ 0, 0, 0, -1, 0, 2 ], [ "Rest" ] ], 2 ], + [ [ [ -1, 0, 0, -2, 0, 2 ], [ -1, 0, 0, -1, 0, 2 ], [ 0, 0, 0, -1, 0, 2 ], [ "Rest" ] ], 0.875 ], + [ [ [ 0, 0, 0, -2, 0, 2 ], [ -1, 0, 0, -1, 0, 2 ], [ 0, 0, 0, -1, 0, 2 ], [ "Rest" ] ], 0 ], + [ [ [ 0, 0, 0, -2, 0, 2 ], [ -1, 0, 1, -1, 0, 2 ], [ 0, 0, 0, -1, 0, 2 ], [ "Rest" ] ], 1.75 ] + ], + [ + [ [ [ 0, 0, 0, -2, 0, 2 ], [ -1, 0, 1, -1, 0, 2 ], [ 0, 0, 0, -1, 0, 2 ], [ 1, 0, 0, -1, -1, 2 ] ], 3 ], + [ [ [ 0, 0, 0, -2, 0, 2 ], [ -1, 0, 1, -1, 0, 2 ], [ 0, 0, 1, -1, -1, 2 ], [ 1, 0, 0, -1, -1, 2 ] ], 0 ], + [ [ [ 0, 0, 0, -2, 0, 2 ], [ 0, 0, -1, -1, -1, 2 ], [ 0, 0, 1, -1, -1, 2 ], [ 1, 0, 0, -1, -1, 2 ] ], 0.875 ], + [ [ [ 0, 0, 0, -2, 0, 2 ], [ -1, 1, 0, -1, -1, 2 ], [ 0, 0, 1, -1, -1, 2 ], [ 1, 0, 0, -1, -1, 2 ] ], 0 ], + [ [ [ 0, 0, 0, -2, 0, 2 ], [ -1, 1, 0, -1, -1, 2 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 2 ] ], 1.625 ], + [ [ [ 0, 0, 0, -2, 0, 2 ], [ -1, 0, 0, -1, 0, 2 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 2 ] ], 0 ], + [ [ [ 0, 0, 0, -2, 0, 2 ], [ -1, 0, 0, -1, 0, 2 ], [ 1, 0, 0, -2, -1, 2 ], [ 1, 0, 0, -1, -1, 2 ] ], 1.125 ] + ], + [ + [ [ [ 0, 0, 0, -2, 0, 2 ], [ -1, 0, 0, -1, 0, 2 ], [ -1, 0, 0, -1, 0, 3 ], [ 1, 0, 0, -1, -1, 2 ] ], 0 ], + [ [ [ 0, 0, 0, -1, 0, 1 ], [ -1, 0, 0, -1, 0, 2 ], [ -1, 0, 0, -1, 0, 3 ], [ 1, 0, 0, -1, -1, 2 ] ], 1.125 ], + [ [ [ 0, -1, 0, -1, 0, 2 ], [ -1, 0, 0, -1, 0, 2 ], [ -1, 0, 0, -1, 0, 3 ], [ 1, 0, 0, -1, -1, 2 ] ], 2.5 ] + ], + [ + [ [ [ 0, -1, 0, -1, 0, 2 ], [ -1, 0, 0, -1, 0, 2 ], [ -1, 0, 0, -1, 0, 3 ], [ -1, 0, 1, -1, 0, 3 ] ], 1.125 ], + [ [ [ 0, -1, 0, -1, 0, 2 ], [ -1, 0, 0, -1, 0, 2 ], [ -1, 0, 0, -1, 0, 3 ], [ 1, 0, 0, -2, 0, 2 ] ], 3 ] + ], + [ + [ [ [ 0, -1, 0, -1, 0, 2 ], [ -1, 0, 0, -1, 0, 2 ], [ -1, 0, 0, -1, 0, 3 ], [ "Rest" ] ], 0 ], + [ [ [ 0, -1, 0, -1, 0, 2 ], [ 0, -1, 0, -1, -1, 2 ], [ -1, 0, 0, -1, 0, 3 ], [ "Rest" ] ], 1.375 ], + [ [ [ 0, -1, 0, -1, 0, 2 ], [ 0, -2, 0, -1, 0, 2 ], [ -1, 0, 0, -1, 0, 3 ], [ "Rest" ] ], 2.5 ], + [ [ [ 0, -1, 0, -1, 0, 2 ], [ -1, -1, 1, -1, 0, 2 ], [ -1, 0, 0, -1, 0, 3 ], [ "Rest" ] ], 1 ], + [ [ [ 0, -1, 0, -1, 0, 2 ], [ -2, 0, 0, -1, 0, 3 ], [ -1, 0, 0, -1, 0, 3 ], [ "Rest" ] ], 2.125 ], + [ [ [ 0, -1, 0, -1, 0, 2 ], [ 0, -1, 0, -2, 0, 2 ], [ -1, 0, 0, -1, 0, 3 ], [ "Rest" ] ], 1.375 ] + ], + [ + [ [ [ -2, 1, 0, -1, 0, 3 ], [ 0, -1, 0, -2, 0, 2 ], [ -1, 0, 0, -1, 0, 3 ], [ "Rest" ] ], 1.625 ], + [ [ [ -2, 1, 0, -1, 0, 3 ], [ 0, -1, 0, -2, 0, 2 ], [ -1, 0, 0, -1, 0, 3 ], [ 0, -1, 0, -1, 0, 3 ] ], 0.5 ], + [ [ [ -2, 1, 0, -1, 0, 3 ], [ -1, 0, 1, -1, 0, 3 ], [ -1, 0, 0, -1, 0, 3 ], [ 0, -1, 0, -1, 0, 3 ] ], 0 ], + [ [ [ -2, 1, 0, -1, 0, 3 ], [ -1, 0, 1, -1, 0, 3 ], [ -1, 0, 0, -1, 0, 3 ], [ 0, 0, 0, -1, -1, 3 ] ], 2.5 ], + [ [ [ -2, 1, 0, -1, 0, 3 ], [ 0, -1, 0, -1, 0, 3 ], [ -1, 0, 0, -1, 0, 3 ], [ 0, 0, 0, -1, -1, 3 ] ], 0 ], + [ [ [ -2, 0, 0, -1, 1, 3 ], [ 0, -1, 0, -1, 0, 3 ], [ -1, 0, 0, -1, 0, 3 ], [ 0, 0, 0, -1, -1, 3 ] ], 1.125 ], + [ [ [ -2, 0, 0, -1, 1, 3 ], [ 0, -1, 0, -1, 0, 3 ], [ -1, 0, 0, -1, 0, 3 ], [ "Rest" ] ], 0 ], + [ [ [ -2, 0, 0, -1, 1, 3 ], [ "Rest" ], [ -1, 0, 0, -1, 0, 3 ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ -1, 0, 0, -1, 0, 3 ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0.875 ] + ] + ] +], +"last_changes": +[ + [ [ -2, 1, 0, -1, 0, 3 ], [ 0, -1, 0, -2, 0, 2 ], [ -1, 0, 0, -1, 0, 3 ], [ 0, -1, 0, -1, 0, 3 ] ], + [ [ -2, 1, 0, -1, 0, 3 ], [ -1, 0, 1, -1, 0, 3 ], [ -1, 0, 0, -1, 0, 3 ], [ 0, -1, 0, -1, 0, 3 ] ], + [ [ -2, 1, 0, -1, 0, 3 ], [ -1, 0, 1, -1, 0, 3 ], [ -1, 0, 0, -1, 0, 3 ], [ 0, 0, 0, -1, -1, 3 ] ], + [ [ -2, 1, 0, -1, 0, 3 ], [ 0, -1, 0, -1, 0, 3 ], [ -1, 0, 0, -1, 0, 3 ], [ 0, 0, 0, -1, -1, 3 ] ], + [ [ -2, 0, 0, -1, 1, 3 ], [ 0, -1, 0, -1, 0, 3 ], [ -1, 0, 0, -1, 0, 3 ], [ 0, 0, 0, -1, -1, 3 ] ] +], +"cur_uid": "6f0f638f", +"ref_uid": "781442dc", +"order_seed": 778672, +"dur_seed": 554838, +"motifs_seed": 420644, +"entrances_probs_vals": [ 0.76, 0, 0, 0.38461538461538, 3.08, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0.76, 0, 0, 0.38461538461538, 3.08, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0.76, 0, 0, 0.38461538461538, 3.08, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1984, 932.50773993808 ], [ -999, 951.08359133127 ], [ -15, 1043.9628482972 ], [ 78, 1081.1145510836 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.076131687242798, 0.91477272727273, 0.17489711934156, 0, 0.57818930041152, 0, 1, 0 ], +"passages_weights": [ 1, 1, 1, 1, 1 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 0, 2, 3 ], [ 1, 1 ], [ ] ], + [ [ 3 ], [ 0, 2, 2, 2 ], [ 1 ] ], + [ [ 2 ], [ 0, 1, 0, 0, 0, 1 ], [ 3 ] ], + [ [ 0, 3 ], [ 2, 1, 1, 2, 1, 2 ], [ ] ], + [ [ 1, 3 ], [ 2, 0, 0 ], [ ] ], + [ [ 2, 1, 0 ], [ 3, 3 ], [ ] ], + [ [ 2, 0 ], [ 1, 1, 1, 1, 1 ], [ 3 ] ], + [ [ 2 ], [ 0, 3, 1, 3, 1, 0 ], [ ] ] +], +"sus_weights": [ 1, 1, 1 ], +"order_size": [ 5, 10 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/726a40c7/726a40c7_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/726a40c7/726a40c7_code.scd new file mode 100644 index 0000000..f822edb --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/726a40c7/726a40c7_code.scd @@ -0,0 +1,946 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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 = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + if(pDistance < 0, {stepFunc.value(abs(pDistance))}, {0.001}); + //stepFunc.value(pDistance) +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/726a40c7/726a40c7_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/726a40c7/726a40c7_mus_model.json new file mode 100644 index 0000000..06e11db --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/726a40c7/726a40c7_mus_model.json @@ -0,0 +1,163 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ 0, -1, 0, 2, 1, -2 ], [ "Rest" ], [ "Rest" ] ], 0.5 ], + [ [ [ -1, 0, 1, 2, 0, -2 ], [ 0, -1, 0, 2, 1, -2 ], [ "Rest" ], [ "Rest" ] ], 0.625 ], + [ [ [ -1, 0, 1, 2, 0, -2 ], [ 0, -1, 0, 2, 1, -2 ], [ -1, -1, 0, 3, 1, -2 ], [ "Rest" ] ], 0.25 ], + [ [ [ -1, 0, 1, 2, 0, -2 ], [ 0, -1, 0, 2, 1, -2 ], [ -1, -1, 0, 3, 1, -2 ], [ -1, -1, 0, 3, 1, -1 ] ], 0.875 ] + ], + [ + [ [ [ 0, -1, 0, 2, 0, -2 ], [ 0, -1, 0, 2, 1, -2 ], [ -1, -1, 0, 3, 1, -2 ], [ -1, -1, 0, 3, 1, -1 ] ], 1 ] + ], + [ + [ [ [ 0, -1, 0, 2, 0, -2 ], [ 0, -1, 0, 2, 1, -2 ], [ -2, -1, 1, 3, 1, -1 ], [ -1, -1, 0, 3, 1, -1 ] ], 0.375 ] + ], + [ + [ [ [ 0, -1, 0, 2, 0, -2 ], [ 0, -1, 0, 2, 1, -2 ], [ -2, -1, 1, 3, 1, -1 ], [ -2, -1, 1, 3, 1, 0 ] ], 0.625 ] + ], + [ + [ [ [ 0, -1, 0, 2, 0, -2 ], [ 0, -1, 0, 2, 1, -2 ], [ -2, -1, 1, 3, 1, -1 ], [ 1, -1, 0, 2, 0, -2 ] ], 1.125 ] + ], + [ + [ [ [ 0, -1, 0, 2, 0, -2 ], [ 0, -1, 0, 2, 1, -2 ], [ -2, -1, 1, 3, 1, -1 ], [ 0, 0, 0, 2, 1, -2 ] ], 0.125 ] + ], + [ + [ [ [ 0, -1, 0, 2, 0, -2 ], [ 0, -1, 0, 2, 1, -2 ], [ -2, -1, 1, 3, 1, -1 ], [ 0, -1, 0, 2, 1, -1 ] ], 0.75 ] + ], + [ + [ [ [ -1, 0, 0, 2, 1, -2 ], [ 0, -1, 0, 2, 1, -2 ], [ -2, -1, 1, 3, 1, -1 ], [ 0, -1, 0, 2, 1, -1 ] ], 0.625 ] + ], + [ + [ [ [ -1, 0, 0, 2, 1, -2 ], [ 0, -2, 0, 2, 1, -1 ], [ -2, -1, 1, 3, 1, -1 ], [ 0, -1, 0, 2, 1, -1 ] ], 0.875 ] + ], + [ + [ [ [ -1, 0, 0, 2, 1, -2 ], [ 0, -2, 0, 2, 1, -1 ], [ -2, -1, 1, 3, 1, -1 ], [ 1, -2, -1, 2, 1, -1 ] ], 1.125 ] + ], + [ + [ [ [ -1, 0, 0, 2, 1, -2 ], [ 0, -2, 0, 2, 1, -1 ], [ -1, 0, 1, 2, 1, -2 ], [ 1, -2, -1, 2, 1, -1 ] ], 0.375 ] + ], + [ + [ [ [ -1, 0, 0, 2, 1, -2 ], [ 0, -2, 0, 2, 1, -1 ], [ -1, 0, 1, 2, 1, -2 ], [ 1, 0, 0, 2, 1, -3 ] ], 0.875 ] + ], + [ + [ [ [ -1, 0, 0, 2, 1, -2 ], [ 0, -2, 0, 2, 1, -1 ], [ -1, 0, 1, 2, 1, -2 ], [ 0, 0, 1, 2, 1, -2 ] ], 0.5 ] + ], + [ + [ [ [ 0, -2, 0, 2, 0, -1 ], [ 0, -2, 0, 2, 1, -1 ], [ -1, 0, 1, 2, 1, -2 ], [ 0, 0, 1, 2, 1, -2 ] ], 0.75 ] + ], + [ + [ [ [ 0, -2, 0, 2, 0, -1 ], [ 0, 0, 1, 2, 1, -3 ], [ -1, 0, 1, 2, 1, -2 ], [ 0, 0, 1, 2, 1, -2 ] ], 1.125 ] + ], + [ + [ [ [ -2, 0, 1, 3, 1, -2 ], [ 0, 0, 1, 2, 1, -3 ], [ -1, 0, 1, 2, 1, -2 ], [ 0, 0, 1, 2, 1, -2 ] ], 0.625 ] + ], + [ + [ [ [ -2, 0, 1, 3, 1, -2 ], [ -1, 0, 1, 3, 0, -2 ], [ -1, 0, 1, 2, 1, -2 ], [ 0, 0, 1, 2, 1, -2 ] ], 0.5 ] + ], + [ + [ [ [ -2, 0, 1, 3, 1, -2 ], [ -1, 0, 1, 3, 0, -2 ], [ -1, 0, 0, 3, 0, -2 ], [ 0, 0, 1, 2, 1, -2 ] ], 1.125 ] + ], + [ + [ [ [ -2, 0, 1, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -1, 0, 0, 3, 0, -2 ], [ 0, 0, 1, 2, 1, -2 ] ], 0.125 ] + ], + [ + [ [ [ -2, 0, 1, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -2, 1, 0, 3, 1, -2 ], [ 0, 0, 1, 2, 1, -2 ] ], 0.125 ] + ], + [ + [ [ [ -3, 1, 0, 4, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -2, 1, 0, 3, 1, -2 ], [ 0, 0, 1, 2, 1, -2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 2, 1, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -2, 1, 0, 3, 1, -2 ], [ 0, 0, 1, 2, 1, -2 ] ], 0.5 ] + ], + [ + [ [ [ -2, 0, 2, 2, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -2, 1, 0, 3, 1, -2 ], [ 0, 0, 1, 2, 1, -2 ] ], 0.875 ] + ], + [ + [ [ [ -2, 0, 2, 2, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -2, 1, 0, 3, 1, -2 ], [ -1, 1, 0, 3, 1, -2 ] ], 0.75 ] + ], + [ + [ [ [ -2, 1, 0, 3, 1, -3 ], [ -2, 1, 1, 3, 1, -2 ], [ -2, 1, 0, 3, 1, -2 ], [ -1, 1, 0, 3, 1, -2 ] ], 0 ] + ], + [ + [ [ [ -3, 1, 1, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -2, 1, 0, 3, 1, -2 ], [ -1, 1, 0, 3, 1, -2 ] ], 0.5 ] + ], + [ + [ [ [ -2, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -2, 1, 0, 3, 1, -2 ], [ -1, 1, 0, 3, 1, -2 ] ], 0.75 ] + ], + [ + [ [ [ -2, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -1, 0, -1, 3, 1, -2 ], [ -1, 1, 0, 3, 1, -2 ] ], 0.875 ] + ], + [ + [ [ [ -2, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -1, 0, -1, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -1 ] ], 0.75 ] + ], + [ + [ [ [ -2, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -3, 1, 1, 4, 1, -2 ], [ -2, 1, 1, 3, 1, -1 ] ], 0.125 ], + [ [ [ -2, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -3, 1, 1, 4, 1, -2 ], [ "Rest" ] ], 1 ], + [ [ [ -2, 0, 0, 3, 1, -2 ], [ "Rest" ], [ -3, 1, 1, 4, 1, -2 ], [ "Rest" ] ], 0.875 ], + [ [ [ "Rest" ], [ "Rest" ], [ -3, 1, 1, 4, 1, -2 ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.75 ] + ] + ] +], +"last_changes": +[ + [ [ -3, 1, 1, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -2, 1, 0, 3, 1, -2 ], [ -1, 1, 0, 3, 1, -2 ] ], + [ [ -2, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -2, 1, 0, 3, 1, -2 ], [ -1, 1, 0, 3, 1, -2 ] ], + [ [ -2, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -1, 0, -1, 3, 1, -2 ], [ -1, 1, 0, 3, 1, -2 ] ], + [ [ -2, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -1, 0, -1, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -1 ] ], + [ [ -2, 0, 0, 3, 1, -2 ], [ -2, 1, 1, 3, 1, -2 ], [ -3, 1, 1, 4, 1, -2 ], [ -2, 1, 1, 3, 1, -1 ] ] +], +"cur_uid": "726a40c7", +"ref_uid": "5ec14635", +"order_seed": 439818, +"dur_seed": 544932, +"motifs_seed": 109123, +"entrances_probs_vals": [ 0, 0, 0, 0, 1.2087912087912, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 0, 1.2087912087912, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 0, 1.2087912087912, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2170, 338 ], [ -2373.9938080495, 1453 ], [ -1650, 1676 ], [ -1370.8978328173, 1694 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 1, 0, 0.2, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ] +], +"sus_weights": [ 0, 0, 0.61 ], +"order_size": [ 30, 30 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/75316bf0/75316bf0_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/75316bf0/75316bf0_code.scd new file mode 100644 index 0000000..49436ca --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/75316bf0/75316bf0_code.scd @@ -0,0 +1,973 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + + + //isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/75316bf0/75316bf0_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/75316bf0/75316bf0_mus_model.json new file mode 100644 index 0000000..e03d000 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/75316bf0/75316bf0_mus_model.json @@ -0,0 +1,550 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ 2, -1, -2, 2, -3, 0 ], [ "Rest" ], [ "Rest" ] ], 0.625 ], + [ [ [ "Rest" ], [ 2, -1, -2, 2, -3, 0 ], [ 2, -1, -2, 1, -3, 0 ], [ "Rest" ] ], 1 ], + [ [ [ "Rest" ], [ 2, -1, -2, 2, -3, 0 ], [ 2, -1, -2, 1, -3, 0 ], [ 1, 0, -2, 2, -3, 0 ] ], 1.5 ], + [ [ [ 1, -2, -2, 2, -3, 0 ], [ 2, -1, -2, 2, -3, 0 ], [ 2, -1, -2, 1, -3, 0 ], [ 1, 0, -2, 2, -3, 0 ] ], 1.875 ] + ], + [ + [ [ [ 1, -2, -2, 2, -3, 0 ], [ 2, -1, -2, 2, -3, 0 ], [ 2, -1, -2, 1, -3, 0 ], [ 2, -2, -1, 2, -3, 0 ] ], 1.625 ], + [ [ [ 1, -2, -2, 2, -3, 0 ], [ 3, -2, -2, 1, -3, 0 ], [ 2, -1, -2, 1, -3, 0 ], [ 2, -2, -1, 2, -3, 0 ] ], 1.5 ] + ], + [ + [ [ [ 1, -2, -2, 2, -3, 0 ], [ 3, -2, -2, 1, -3, 0 ], [ 2, -3, -2, 2, -3, 0 ], [ 2, -2, -1, 2, -3, 0 ] ], 1.5 ], + [ [ [ 1, -2, -2, 2, -3, 0 ], [ 3, -2, -2, 1, -3, 0 ], [ 2, -3, -2, 2, -3, 0 ], [ 3, -3, -2, 2, -3, 0 ] ], 0.875 ] + ], + [ + [ [ [ 2, -3, -3, 2, -3, 0 ], [ 3, -2, -2, 1, -3, 0 ], [ 2, -3, -2, 2, -3, 0 ], [ 3, -3, -2, 2, -3, 0 ] ], 1.125 ], + [ [ [ 2, -3, -3, 2, -3, 0 ], [ 3, -2, -2, 1, -3, 0 ], [ 3, -3, -2, 1, -3, 0 ], [ 3, -3, -2, 2, -3, 0 ] ], 1.75 ] + ], + [ + [ [ [ 2, -3, -3, 2, -3, 0 ], [ 3, -2, -2, 1, -3, 0 ], [ 3, -3, -2, 1, -3, 0 ], [ 4, -4, -3, 2, -3, 0 ] ], 1.5 ], + [ [ [ 2, -3, -3, 2, -3, 0 ], [ 4, -3, -3, 1, -3, 0 ], [ 3, -3, -2, 1, -3, 0 ], [ 4, -4, -3, 2, -3, 0 ] ], 1.5 ] + ], + [ + [ [ [ 2, -3, -3, 2, -3, 0 ], [ 3, -3, -2, 2, -3, 0 ], [ 3, -3, -2, 1, -3, 0 ], [ 4, -4, -3, 2, -3, 0 ] ], 1.75 ], + [ [ [ 2, -3, -3, 2, -3, 0 ], [ 3, -3, -2, 2, -3, 0 ], [ 3, -4, -3, 2, -3, 0 ], [ 4, -4, -3, 2, -3, 0 ] ], 1.5 ] + ], + [ + [ [ [ 2, -3, -3, 2, -3, 0 ], [ 3, -3, -2, 2, -3, 0 ], [ 2, -2, -3, 2, -3, 0 ], [ 4, -4, -3, 2, -3, 0 ] ], 0.5 ] + ], + [ + [ [ [ 2, -3, -3, 2, -3, 0 ], [ 4, -4, -4, 2, -3, 0 ], [ 2, -2, -3, 2, -3, 0 ], [ 4, -4, -3, 2, -3, 0 ] ], 0.5 ], + [ [ [ 2, -3, -3, 2, -3, 0 ], [ 4, -4, -4, 2, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 4, -4, -3, 2, -3, 0 ] ], 0.75 ], + [ [ [ 3, -4, -4, 2, -3, 0 ], [ 4, -4, -4, 2, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 4, -4, -3, 2, -3, 0 ] ], 0.625 ] + ], + [ + [ [ [ 3, -4, -4, 2, -3, 0 ], [ 4, -4, -4, 2, -3, 0 ], [ 3, -5, -3, 2, -3, 0 ], [ 4, -4, -3, 2, -3, 0 ] ], 0.625 ] + ], + [ + [ [ [ 1, -3, -4, 2, -3, 0 ], [ 4, -4, -4, 2, -3, 0 ], [ 3, -5, -3, 2, -3, 0 ], [ 4, -4, -3, 2, -3, 0 ] ], 1.25 ], + [ [ [ 1, -3, -4, 2, -3, 0 ], [ 4, -4, -4, 2, -3, 0 ], [ 2, -4, -4, 3, -3, 0 ], [ 4, -4, -3, 2, -3, 0 ] ], 1.375 ], + [ [ [ 1, -3, -4, 2, -3, 0 ], [ 4, -4, -4, 2, -3, 0 ], [ 2, -4, -4, 3, -3, 0 ], [ 5, -4, -4, 1, -3, 0 ] ], 0.75 ] + ], + [ + [ [ [ 1, -3, -4, 2, -3, 0 ], [ 4, -4, -4, 2, -3, 0 ], [ 3, -4, -4, 2, -3, 0 ], [ 5, -4, -4, 1, -3, 0 ] ], 1.375 ] + ], + [ + [ [ [ 1, -3, -4, 2, -3, 0 ], [ 4, -4, -4, 2, -3, 0 ], [ 3, -4, -4, 2, -3, 0 ], [ 4, -3, -5, 2, -3, 0 ] ], 1.5 ], + [ [ [ 1, -3, -4, 2, -3, 0 ], [ 3, -2, -4, 2, -3, 0 ], [ 3, -4, -4, 2, -3, 0 ], [ 4, -3, -5, 2, -3, 0 ] ], 0.5 ] + ], + [ + [ [ [ 1, -3, -4, 2, -3, 0 ], [ 3, -2, -4, 2, -3, 0 ], [ 3, -4, -4, 2, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 1.75 ], + [ [ [ 1, -3, -4, 2, -3, 0 ], [ 3, -2, -4, 2, -3, 0 ], [ 2, -2, -4, 2, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 1.625 ] + ], + [ + [ [ [ 1, -2, -4, 2, -4, 0 ], [ 3, -2, -4, 2, -3, 0 ], [ 2, -2, -4, 2, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 0.625 ] + ], + [ + [ [ [ 1, -2, -4, 2, -4, 0 ], [ 1, -2, -4, 3, -3, 0 ], [ 2, -2, -4, 2, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 0.875 ], + [ [ [ 1, -4, -4, 3, -3, 0 ], [ 1, -2, -4, 3, -3, 0 ], [ 2, -2, -4, 2, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 1.625 ] + ], + [ + [ [ [ 1, -4, -4, 3, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 2, -2, -4, 2, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 1.625 ] + ], + [ + [ [ [ 1, -4, -4, 3, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 2, -3, -4, 3, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 0.5 ] + ], + [ + [ [ [ 1, -4, -4, 3, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 2, -4, -4, 3, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 0.75 ] + ], + [ + [ [ [ 1, -4, -4, 3, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 1, -4, -3, 4, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 0.75 ], + [ [ [ 0, -4, -3, 4, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 1, -4, -3, 4, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 1.25 ], + [ [ [ 0, -4, -3, 4, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 1, -4, -3, 4, -3, 0 ], [ 3, -4, -3, 3, -3, 0 ] ], 1.25 ] + ], + [ + [ [ [ 0, -4, -3, 4, -3, 0 ], [ 3, -4, -3, 2, -3, 0 ], [ 1, -4, -3, 4, -3, 0 ], [ 3, -4, -3, 3, -3, 0 ] ], 1 ], + [ [ [ 0, -4, -3, 4, -3, 0 ], [ 3, -4, -3, 2, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 3, -4, -3, 3, -3, 0 ] ], 0.375 ], + [ [ [ 1, -4, -3, 3, -3, 0 ], [ 3, -4, -3, 2, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 3, -4, -3, 3, -3, 0 ] ], 1.375 ] + ], + [ + [ [ [ 1, -4, -3, 3, -3, 0 ], [ 3, -4, -3, 2, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 4, -4, -3, 2, -3, 0 ] ], 1.625 ], + [ [ [ 2, -4, -3, 2, -3, 0 ], [ 3, -4, -3, 2, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 4, -4, -3, 2, -3, 0 ] ], 1.625 ] + ], + [ + [ [ [ 2, -4, -3, 2, -3, 0 ], [ 3, -4, -3, 2, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 3, -4, -3, 2, -3, 1 ] ], 1.625 ], + [ [ [ 2, -4, -3, 2, -3, 0 ], [ 3, -4, -3, 2, -3, 0 ], [ 3, -5, -3, 2, -3, 0 ], [ 3, -4, -3, 2, -3, 1 ] ], 1.75 ] + ], + [ + [ [ [ 2, -4, -3, 2, -3, 0 ], [ 3, -4, -3, 2, -3, 0 ], [ 2, -3, -3, 2, -3, 0 ], [ 3, -4, -3, 2, -3, 1 ] ], 1.75 ], + [ [ [ 2, -4, -3, 2, -3, 0 ], [ 3, -4, -3, 2, -3, 0 ], [ 2, -3, -3, 2, -3, 0 ], [ 3, -4, -3, 3, -3, 0 ] ], 1.75 ] + ], + [ + [ [ [ 2, -4, -3, 2, -3, 0 ], [ 2, -2, -3, 2, -3, 0 ], [ 2, -3, -3, 2, -3, 0 ], [ 3, -4, -3, 3, -3, 0 ] ], 1 ] + ], + [ + [ [ [ 2, -5, -3, 3, -3, 0 ], [ 2, -2, -3, 2, -3, 0 ], [ 2, -3, -3, 2, -3, 0 ], [ 3, -4, -3, 3, -3, 0 ] ], 1.625 ], + [ [ [ 2, -5, -3, 3, -3, 0 ], [ 2, -2, -3, 2, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 3, -4, -3, 3, -3, 0 ] ], 1.75 ], + [ [ [ 2, -5, -3, 3, -3, 0 ], [ 2, -3, -3, 3, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 3, -4, -3, 3, -3, 0 ] ], 1.625 ] + ], + [ + [ [ [ 1, -3, -3, 3, -3, 0 ], [ 2, -3, -3, 3, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 3, -4, -3, 3, -3, 0 ] ], 1 ], + [ [ [ 1, -3, -3, 3, -3, 0 ], [ 2, -3, -3, 3, -3, 0 ], [ 2, -4, -3, 3, -3, 0 ], [ 2, -2, -3, 3, -3, 0 ] ], 1 ], + [ [ [ 1, -3, -3, 3, -3, 0 ], [ 2, -3, -3, 3, -3, 0 ], [ 1, -2, -3, 3, -3, 0 ], [ 2, -2, -3, 3, -3, 0 ] ], 1.25 ] + ], + [ + [ [ [ 1, -3, -3, 3, -3, 0 ], [ 2, -3, -3, 3, -3, 0 ], [ 2, -3, -4, 3, -3, 0 ], [ 2, -2, -3, 3, -3, 0 ] ], 0.875 ], + [ [ [ 1, -3, -3, 3, -3, 0 ], [ 2, -3, -3, 3, -3, 0 ], [ 2, -3, -4, 3, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 1.625 ], + [ [ [ 1, -3, -4, 3, -3, 0 ], [ 2, -3, -3, 3, -3, 0 ], [ 2, -3, -4, 3, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 0.875 ] + ], + [ + [ [ [ 1, -3, -4, 3, -3, 0 ], [ 2, -3, -3, 3, -3, 0 ], [ 2, -4, -4, 3, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 0.75 ], + [ [ [ 1, -3, -4, 3, -3, 0 ], [ 3, -4, -4, 3, -3, 0 ], [ 2, -4, -4, 3, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 0.5 ], + [ [ [ 1, -3, -4, 3, -3, 0 ], [ 3, -4, -4, 3, -3, 0 ], [ 2, -4, -4, 3, -3, 0 ], [ 2, -3, -4, 4, -3, 0 ] ], 1.125 ] + ], + [ + [ [ [ 1, -3, -4, 3, -3, 0 ], [ 3, -4, -4, 3, -3, 0 ], [ 1, -2, -4, 3, -3, 0 ], [ 2, -3, -4, 4, -3, 0 ] ], 1.625 ] + ], + [ + [ [ [ 1, -3, -4, 3, -3, 0 ], [ 2, -2, -4, 3, -3, 0 ], [ 1, -2, -4, 3, -3, 0 ], [ 2, -3, -4, 4, -3, 0 ] ], 1.75 ] + ], + [ + [ [ [ 1, -3, -4, 3, -3, 0 ], [ 2, -2, -4, 3, -3, 0 ], [ 1, -2, -4, 3, -3, 0 ], [ 2, -2, -3, 3, -3, 0 ] ], 1.75 ], + [ [ [ 1, -3, -4, 3, -3, 0 ], [ 2, -2, -4, 3, -3, 0 ], [ 2, -3, -5, 3, -3, 0 ], [ 2, -2, -3, 3, -3, 0 ] ], 0.75 ] + ], + [ + [ [ [ 1, -3, -4, 3, -3, 0 ], [ 2, -2, -4, 3, -3, 0 ], [ 2, -3, -5, 3, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 0.375 ], + [ [ [ 1, -3, -4, 3, -3, 0 ], [ 2, -3, -4, 3, -3, 0 ], [ 2, -3, -5, 3, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 1.125 ] + ], + [ + [ [ [ 1, -3, -4, 3, -3, 0 ], [ 2, -3, -4, 3, -4, 0 ], [ 2, -3, -5, 3, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 0.5 ], + [ [ [ 1, -3, -4, 2, -3, 0 ], [ 2, -3, -4, 3, -4, 0 ], [ 2, -3, -5, 3, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 1.75 ], + [ [ [ 1, -3, -4, 2, -3, 0 ], [ 2, -3, -4, 3, -4, 0 ], [ 1, -3, -4, 4, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 1.25 ] + ], + [ + [ [ [ 1, -3, -4, 2, -3, 0 ], [ 0, -2, -4, 4, -3, 0 ], [ 1, -3, -4, 4, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 1 ], + [ [ [ -1, -2, -4, 4, -3, 0 ], [ 0, -2, -4, 4, -3, 0 ], [ 1, -3, -4, 4, -3, 0 ], [ 3, -3, -4, 3, -3, 0 ] ], 1.75 ], + [ [ [ -1, -2, -4, 4, -3, 0 ], [ 0, -2, -4, 4, -3, 0 ], [ 1, -3, -4, 4, -3, 0 ], [ 2, -3, -4, 4, -3, 0 ] ], 0.875 ] + ], + [ + [ [ [ -1, -2, -4, 4, -3, 0 ], [ 0, -2, -4, 4, -3, 0 ], [ 0, -1, -4, 4, -3, 0 ], [ 2, -3, -4, 4, -3, 0 ] ], 1.375 ], + [ [ [ -1, -2, -4, 4, -3, 0 ], [ 0, -2, -4, 4, -3, 0 ], [ 0, -1, -4, 4, -3, 0 ], [ 1, -1, -4, 4, -3, 0 ] ], 1.25 ] + ], + [ + [ [ [ -1, -2, -4, 4, -3, 0 ], [ 1, -2, -4, 3, -3, 0 ], [ 0, -1, -4, 4, -3, 0 ], [ 1, -1, -4, 4, -3, 0 ] ], 0.625 ], + [ [ [ -1, -2, -4, 4, -3, 0 ], [ 1, -2, -4, 3, -3, 0 ], [ 0, -1, -4, 4, -3, 0 ], [ 1, -2, -3, 4, -3, 0 ] ], 0.625 ], + [ [ [ -1, -2, -4, 4, -3, 0 ], [ 1, -2, -4, 3, -3, 0 ], [ 0, -2, -4, 4, -3, 0 ], [ 1, -2, -3, 4, -3, 0 ] ], 0.5 ] + ], + [ + [ [ [ -1, -2, -4, 4, -3, 0 ], [ 0, -2, -3, 4, -3, 0 ], [ 0, -2, -4, 4, -3, 0 ], [ 1, -2, -3, 4, -3, 0 ] ], 0.75 ], + [ [ [ -1, -2, -4, 4, -3, 0 ], [ 0, -2, -3, 4, -3, 0 ], [ -1, -2, -3, 5, -3, 0 ], [ 1, -2, -3, 4, -3, 0 ] ], 1.125 ] + ], + [ + [ [ [ -1, -2, -4, 4, -3, 0 ], [ 1, -3, -4, 4, -3, 0 ], [ -1, -2, -3, 5, -3, 0 ], [ 1, -2, -3, 4, -3, 0 ] ], 1.625 ], + [ [ [ -1, -2, -4, 4, -3, 0 ], [ 1, -3, -4, 4, -3, 0 ], [ -1, -2, -3, 5, -3, 0 ], [ 2, -3, -4, 4, -3, 0 ] ], 0.875 ], + [ [ [ -1, -2, -4, 4, -3, 0 ], [ 1, -3, -4, 4, -3, 0 ], [ 0, -2, -3, 4, -3, 0 ], [ 2, -3, -4, 4, -3, 0 ] ], 1.25 ] + ], + [ + [ [ [ -1, -2, -4, 4, -3, 0 ], [ 1, -3, -4, 4, -3, 0 ], [ 1, -3, -4, 4, -4, 0 ], [ 2, -3, -4, 4, -3, 0 ] ], 1 ] + ], + [ + [ [ [ -1, -2, -4, 4, -3, 0 ], [ 1, -3, -4, 4, -3, 0 ], [ 1, -3, -4, 4, -4, 0 ], [ 1, -1, -4, 4, -3, 0 ] ], 1.5 ] + ], + [ + [ [ [ -1, -2, -4, 4, -3, 0 ], [ 1, -2, -4, 4, -4, 0 ], [ 1, -3, -4, 4, -4, 0 ], [ 1, -1, -4, 4, -3, 0 ] ], 1 ], + [ [ [ 1, -3, -4, 3, -4, 0 ], [ 1, -2, -4, 4, -4, 0 ], [ 1, -3, -4, 4, -4, 0 ], [ 1, -1, -4, 4, -3, 0 ] ], 1.25 ], + [ [ [ 1, -3, -4, 3, -4, 0 ], [ 1, -2, -4, 4, -4, 0 ], [ 1, -3, -4, 4, -4, 0 ], [ 2, -2, -4, 4, -4, 0 ] ], 0.5 ] + ], + [ + [ [ [ 1, -3, -4, 3, -4, 0 ], [ 1, -2, -4, 4, -4, 0 ], [ 2, -3, -4, 3, -4, 0 ], [ 2, -2, -4, 4, -4, 0 ] ], 1 ] + ], + [ + [ [ [ 1, -3, -4, 3, -4, 0 ], [ 2, -2, -4, 3, -4, 0 ], [ 2, -3, -4, 3, -4, 0 ], [ 2, -2, -4, 4, -4, 0 ] ], 0.875 ], + [ [ [ 0, -2, -4, 3, -4, 0 ], [ 2, -2, -4, 3, -4, 0 ], [ 2, -3, -4, 3, -4, 0 ], [ 2, -2, -4, 4, -4, 0 ] ], 1.75 ] + ], + [ + [ [ [ 0, -2, -4, 3, -4, 0 ], [ 2, -2, -4, 3, -4, 0 ], [ 2, -3, -4, 3, -4, 0 ], [ 2, -1, -4, 3, -4, 0 ] ], 1.75 ], + [ [ [ 0, -2, -4, 3, -4, 0 ], [ 2, -2, -4, 3, -4, 0 ], [ 1, -1, -4, 3, -4, 0 ], [ 2, -1, -4, 3, -4, 0 ] ], 1.75 ], + [ [ [ 1, -2, -4, 3, -4, 0 ], [ 2, -2, -4, 3, -4, 0 ], [ 1, -1, -4, 3, -4, 0 ], [ 2, -1, -4, 3, -4, 0 ] ], 1.125 ] + ], + [ + [ [ [ 1, -2, -4, 3, -4, 0 ], [ 1, 0, -4, 3, -4, 0 ], [ 1, -1, -4, 3, -4, 0 ], [ 2, -1, -4, 3, -4, 0 ] ], 0.875 ] + ], + [ + [ [ [ 0, 0, -4, 3, -4, 0 ], [ 1, 0, -4, 3, -4, 0 ], [ 1, -1, -4, 3, -4, 0 ], [ 2, -1, -4, 3, -4, 0 ] ], 1.75 ], + [ [ [ 0, 0, -4, 3, -4, 0 ], [ 1, 0, -4, 3, -4, 0 ], [ 0, 1, -4, 3, -4, 0 ], [ 2, -1, -4, 3, -4, 0 ] ], 0.625 ] + ], + [ + [ [ [ -1, 1, -4, 3, -4, 0 ], [ 1, 0, -4, 3, -4, 0 ], [ 0, 1, -4, 3, -4, 0 ], [ 2, -1, -4, 3, -4, 0 ] ], 0.75 ], + [ [ [ -1, 1, -4, 3, -4, 0 ], [ 1, 0, -4, 3, -4, 0 ], [ 1, 0, -5, 3, -4, 0 ], [ 2, -1, -4, 3, -4, 0 ] ], 0.75 ] + ], + [ + [ [ [ -1, 1, -4, 3, -4, 0 ], [ 1, 0, -4, 3, -4, 0 ], [ 1, 0, -5, 3, -4, 0 ], [ 1, 1, -4, 3, -4, 0 ] ], 1.5 ], + [ [ [ -1, 1, -4, 3, -4, 0 ], [ 1, 0, -4, 3, -4, 0 ], [ 0, 0, -4, 4, -4, 0 ], [ 1, 1, -4, 3, -4, 0 ] ], 1.25 ], + [ [ [ -1, 0, -4, 3, -4, 0 ], [ 1, 0, -4, 3, -4, 0 ], [ 0, 0, -4, 4, -4, 0 ], [ 1, 1, -4, 3, -4, 0 ] ], 0.875 ] + ], + [ + [ [ [ -1, 0, -4, 4, -4, -1 ], [ 1, 0, -4, 3, -4, 0 ], [ 0, 0, -4, 4, -4, 0 ], [ 1, 1, -4, 3, -4, 0 ] ], 0.75 ], + [ [ [ -1, 0, -4, 4, -4, -1 ], [ 1, 0, -4, 3, -4, 0 ], [ 0, 0, -4, 4, -4, 0 ], [ 0, 1, -4, 4, -4, 0 ] ], 1 ], + [ [ [ -1, 0, -4, 4, -4, -1 ], [ 0, 0, -3, 4, -4, 0 ], [ 0, 0, -4, 4, -4, 0 ], [ 0, 1, -4, 4, -4, 0 ] ], 1.5 ] + ], + [ + [ [ [ -1, 0, -4, 4, -4, -1 ], [ 1, 0, -5, 4, -4, -1 ], [ 0, 0, -4, 4, -4, 0 ], [ 0, 1, -4, 4, -4, 0 ] ], 1.625 ], + [ [ [ -1, 0, -4, 4, -4, -1 ], [ 1, 0, -5, 4, -4, -1 ], [ 0, 0, -4, 4, -4, 0 ], [ 2, -1, -4, 4, -4, -1 ] ], 0.5 ], + [ [ [ -1, 0, -4, 4, -4, -1 ], [ 1, 0, -5, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 0.75 ] + ], + [ + [ [ [ -1, 0, -4, 4, -4, -1 ], [ 2, -2, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 0.5 ], + [ [ [ 0, -1, -5, 4, -4, -1 ], [ 2, -2, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 1.375 ], + [ [ [ 0, -1, -5, 4, -4, -1 ], [ 2, -2, -4, 4, -4, -1 ], [ 1, -1, -5, 4, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 0.625 ] + ], + [ + [ [ [ 0, -1, -5, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 1, -1, -5, 4, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 0.625 ], + [ [ [ 0, -1, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 1, -1, -5, 4, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 1 ], + [ [ [ 0, -1, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 0, 0, -4, 4, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 1 ] + ], + [ + [ [ [ 0, -1, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 0, -1, -4, 5, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 1 ], + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 0, -1, -4, 5, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 1.375 ] + ], + [ + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 2, -2, -4, 4, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 1.25 ], + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 2, -2, -4, 4, -4, -1 ], [ 3, -3, -4, 4, -4, -1 ] ], 0.875 ] + ], + [ + [ [ [ 0, -3, -4, 4, -3, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 2, -2, -4, 4, -4, -1 ], [ 3, -3, -4, 4, -4, -1 ] ], 0.875 ] + ], + [ + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 2, -2, -4, 4, -4, -1 ], [ 3, -3, -4, 4, -4, -1 ] ], 0.875 ], + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 2, -2, -4, 4, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 1.5 ], + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 1, 0, -4, 4, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 0.875 ] + ], + [ + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 2, -3, -4, 4, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 1.5 ], + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 2, -3, -4, 4, -4, -1 ], [ 2, -2, -4, 4, -4, 0 ] ], 0.375 ] + ], + [ + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 2, -3, -4, 4, -4, -1 ], [ 1, -1, -4, 5, -4, -1 ] ], 0.5 ], + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 0, 0, -4, 4, -4, -1 ], [ 1, -1, -4, 5, -4, -1 ] ], 0.75 ] + ], + [ + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 1, -1, -5, 4, -4, -1 ], [ 1, -1, -4, 5, -4, -1 ] ], 0.5 ] + ], + [ + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 1, -2, -4, 4, -3, -1 ], [ 1, -1, -4, 5, -4, -1 ] ], 0.5 ], + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 2, -2, -5, 4, -4, -1 ], [ 1, -2, -4, 4, -3, -1 ], [ 1, -1, -4, 5, -4, -1 ] ], 1.125 ], + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 2, -2, -5, 4, -4, -1 ], [ 1, -2, -4, 4, -3, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 1.625 ] + ], + [ + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 2, -2, -5, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 0.875 ] + ], + [ + [ [ [ 0, -2, -4, 4, -4, -1 ], [ 0, 0, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 1.375 ], + [ [ [ -1, 0, -4, 4, -4, -1 ], [ 0, 0, -4, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 0.875 ] + ], + [ + [ [ [ -1, 0, -4, 4, -4, -1 ], [ 1, -1, -5, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 1.5 ], + [ [ [ -1, 0, -4, 4, -4, -1 ], [ 1, -1, -5, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 1, -1, -4, 5, -4, -1 ] ], 0.5 ], + [ [ [ 0, -1, -5, 4, -4, -1 ], [ 1, -1, -5, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 1, -1, -4, 5, -4, -1 ] ], 1.375 ] + ], + [ + [ [ [ 0, -1, -5, 4, -4, -1 ], [ 1, -1, -5, 4, -4, -1 ], [ 1, -1, -4, 4, -4, -1 ], [ 3, -1, -5, 4, -4, -2 ] ], 0.625 ], + [ [ [ 0, -1, -5, 4, -4, -1 ], [ 1, -1, -5, 4, -4, -1 ], [ 2, -2, -5, 4, -4, -1 ], [ 3, -1, -5, 4, -4, -2 ] ], 1.5 ] + ], + [ + [ [ [ 0, -1, -5, 4, -4, -1 ], [ 2, -3, -5, 4, -4, -1 ], [ 2, -2, -5, 4, -4, -1 ], [ 3, -1, -5, 4, -4, -2 ] ], 1.5 ], + [ [ [ 1, -2, -5, 4, -4, -2 ], [ 2, -3, -5, 4, -4, -1 ], [ 2, -2, -5, 4, -4, -1 ], [ 3, -1, -5, 4, -4, -2 ] ], 0.5 ], + [ [ [ 1, -2, -5, 4, -4, -2 ], [ 2, -3, -5, 4, -4, -1 ], [ 2, -2, -5, 4, -4, -1 ], [ 3, -2, -5, 4, -4, -1 ] ], 1.25 ] + ], + [ + [ [ [ 1, -2, -5, 4, -4, -2 ], [ 2, -2, -5, 4, -5, -1 ], [ 2, -2, -5, 4, -4, -1 ], [ 3, -2, -5, 4, -4, -1 ] ], 0.625 ], + [ [ [ 1, -3, -5, 4, -4, -1 ], [ 2, -2, -5, 4, -5, -1 ], [ 2, -2, -5, 4, -4, -1 ], [ 3, -2, -5, 4, -4, -1 ] ], 0.75 ], + [ [ [ 1, -3, -5, 4, -4, -1 ], [ 2, -2, -5, 4, -5, -1 ], [ 2, -3, -5, 4, -4, -1 ], [ 3, -2, -5, 4, -4, -1 ] ], 1.625 ] + ], + [ + [ [ [ 1, -2, -5, 4, -5, -1 ], [ 2, -2, -5, 4, -5, -1 ], [ 2, -3, -5, 4, -4, -1 ], [ 3, -2, -5, 4, -4, -1 ] ], 1.5 ], + [ [ [ 1, -2, -5, 4, -5, -1 ], [ 2, -2, -5, 4, -5, -1 ], [ 3, -2, -5, 4, -5, -1 ], [ 3, -2, -5, 4, -4, -1 ] ], 0.5 ], + [ [ [ 1, -2, -5, 4, -5, -1 ], [ 2, -2, -5, 4, -5, -1 ], [ 3, -2, -5, 4, -5, -1 ], [ 3, -2, -4, 4, -5, -1 ] ], 1.5 ] + ], + [ + [ [ [ 1, -2, -5, 4, -5, -1 ], [ 2, -2, -5, 4, -5, -1 ], [ 2, -2, -4, 4, -5, -1 ], [ 3, -2, -4, 4, -5, -1 ] ], 1.375 ], + [ [ [ 1, -2, -5, 4, -5, -1 ], [ 1, -2, -4, 5, -5, -1 ], [ 2, -2, -4, 4, -5, -1 ], [ 3, -2, -4, 4, -5, -1 ] ], 0.625 ], + [ [ [ 0, -2, -4, 5, -5, -1 ], [ 1, -2, -4, 5, -5, -1 ], [ 2, -2, -4, 4, -5, -1 ], [ 3, -2, -4, 4, -5, -1 ] ], 0.75 ] + ], + [ + [ [ [ 0, -2, -4, 5, -5, -1 ], [ 1, -1, -4, 4, -5, -1 ], [ 2, -2, -4, 4, -5, -1 ], [ 3, -2, -4, 4, -5, -1 ] ], 0.875 ], + [ [ [ 0, -2, -4, 5, -5, -1 ], [ 1, -1, -4, 4, -5, -1 ], [ 2, -2, -4, 4, -5, -1 ], [ 4, -2, -4, 3, -5, -1 ] ], 1 ] + ], + [ + [ [ [ 1, -2, -4, 4, -5, -1 ], [ 1, -1, -4, 4, -5, -1 ], [ 2, -2, -4, 4, -5, -1 ], [ 4, -2, -4, 3, -5, -1 ] ], 0.75 ] + ], + [ + [ [ [ 1, -2, -4, 4, -5, -1 ], [ 1, -1, -4, 4, -5, -1 ], [ 2, -2, -4, 4, -5, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 0.75 ] + ], + [ + [ [ [ 1, -2, -4, 4, -5, -1 ], [ 2, -1, -4, 4, -5, -1 ], [ 2, -2, -4, 4, -5, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 0.875 ], + [ [ [ 1, -2, -4, 4, -5, -1 ], [ 2, -1, -4, 4, -5, -1 ], [ 1, -1, -4, 4, -5, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 1.25 ], + [ [ [ 0, -1, -4, 4, -5, -1 ], [ 2, -1, -4, 4, -5, -1 ], [ 1, -1, -4, 4, -5, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 1.125 ] + ], + [ + [ [ [ 1, -1, -4, 3, -5, -1 ], [ 2, -1, -4, 4, -5, -1 ], [ 1, -1, -4, 4, -5, -1 ], [ 2, -1, -4, 4, -4, -1 ] ], 1 ], + [ [ [ 1, -1, -4, 3, -5, -1 ], [ 2, -1, -4, 4, -5, -1 ], [ 1, -1, -4, 4, -5, -1 ], [ 2, 0, -4, 4, -5, -1 ] ], 1.375 ] + ], + [ + [ [ [ 0, -1, -3, 4, -5, -1 ], [ 2, -1, -4, 4, -5, -1 ], [ 1, -1, -4, 4, -5, -1 ], [ 2, 0, -4, 4, -5, -1 ] ], 0.75 ], + [ [ [ 0, -1, -3, 4, -5, -1 ], [ 2, -1, -4, 4, -5, -1 ], [ 2, -1, -4, 3, -5, -1 ], [ 2, 0, -4, 4, -5, -1 ] ], 1.5 ], + [ [ [ 0, -1, -3, 4, -5, -1 ], [ 2, -1, -4, 4, -5, -1 ], [ 2, -1, -4, 3, -5, -1 ], [ 3, -2, -4, 4, -5, -1 ] ], 0.5 ] + ], + [ + [ [ [ 1, -2, -4, 4, -5, -1 ], [ 2, -1, -4, 4, -5, -1 ], [ 2, -1, -4, 3, -5, -1 ], [ 3, -2, -4, 4, -5, -1 ] ], 1.375 ], + [ [ [ 1, -2, -4, 4, -5, -1 ], [ 2, -1, -4, 4, -5, -1 ], [ 2, -2, -4, 4, -5, -1 ], [ 3, -2, -4, 4, -5, -1 ] ], 0.875 ], + [ [ [ 1, -2, -4, 4, -5, -1 ], [ 3, -2, -5, 4, -5, -1 ], [ 2, -2, -4, 4, -5, -1 ], [ 3, -2, -4, 4, -5, -1 ] ], 0.5 ] + ], + [ + [ [ [ 1, -2, -4, 4, -5, -1 ], [ 3, -2, -5, 4, -5, -1 ], [ 2, -2, -4, 4, -5, -1 ], [ 4, -3, -5, 4, -5, -1 ] ], 0.875 ] + ], + [ + [ [ [ 1, -2, -4, 4, -5, -1 ], [ 2, -2, -4, 5, -5, -1 ], [ 2, -2, -4, 4, -5, -1 ], [ 4, -3, -5, 4, -5, -1 ] ], 1 ], + [ [ [ 2, -3, -5, 4, -5, -1 ], [ 2, -2, -4, 5, -5, -1 ], [ 2, -2, -4, 4, -5, -1 ], [ 4, -3, -5, 4, -5, -1 ] ], 1.5 ] + ], + [ + [ [ [ 2, -3, -5, 4, -5, -1 ], [ 2, -2, -4, 5, -5, -1 ], [ 2, -2, -4, 4, -5, -1 ], [ 3, -3, -4, 5, -5, -1 ] ], 1.375 ], + [ [ [ 1, -3, -4, 5, -5, -1 ], [ 2, -2, -4, 5, -5, -1 ], [ 2, -2, -4, 4, -5, -1 ], [ 3, -3, -4, 5, -5, -1 ] ], 1.25 ], + [ [ [ 1, -3, -4, 5, -5, -1 ], [ 2, -2, -4, 5, -5, -1 ], [ 2, -3, -4, 5, -5, -1 ], [ 3, -3, -4, 5, -5, -1 ] ], 0.5 ] + ], + [ + [ [ [ 1, -3, -4, 5, -5, -1 ], [ 2, -2, -4, 5, -5, -1 ], [ 1, -2, -4, 5, -5, -1 ], [ 3, -3, -4, 5, -5, -1 ] ], 0.75 ], + [ [ [ 1, -3, -4, 5, -5, -1 ], [ 2, -3, -4, 5, -5, -1 ], [ 1, -2, -4, 5, -5, -1 ], [ 3, -3, -4, 5, -5, -1 ] ], 1.5 ] + ], + [ + [ [ [ 1, -3, -4, 5, -5, -1 ], [ 2, -4, -4, 5, -5, -1 ], [ 1, -2, -4, 5, -5, -1 ], [ 3, -3, -4, 5, -5, -1 ] ], 1.75 ], + [ [ [ 1, -3, -4, 5, -5, -1 ], [ 2, -4, -4, 5, -5, -1 ], [ 2, -3, -5, 5, -5, -1 ], [ 3, -3, -4, 5, -5, -1 ] ], 1.125 ], + [ [ [ 1, -4, -4, 5, -5, -1 ], [ 2, -4, -4, 5, -5, -1 ], [ 2, -3, -5, 5, -5, -1 ], [ 3, -3, -4, 5, -5, -1 ] ], 1.75 ] + ], + [ + [ [ [ 2, -4, -4, 4, -5, -1 ], [ 2, -4, -4, 5, -5, -1 ], [ 2, -3, -5, 5, -5, -1 ], [ 3, -3, -4, 5, -5, -1 ] ], 1.25 ], + [ [ [ 2, -4, -4, 4, -5, -1 ], [ 2, -4, -4, 5, -5, -1 ], [ 2, -3, -5, 5, -5, -1 ], [ 3, -3, -5, 5, -5, -1 ] ], 1.5 ] + ], + [ + [ [ [ 1, -3, -5, 5, -5, -1 ], [ 2, -4, -4, 5, -5, -1 ], [ 2, -3, -5, 5, -5, -1 ], [ 3, -3, -5, 5, -5, -1 ] ], 1.375 ], + [ [ [ 1, -3, -5, 5, -5, -1 ], [ 3, -4, -5, 5, -5, -1 ], [ 2, -3, -5, 5, -5, -1 ], [ 3, -3, -5, 5, -5, -1 ] ], 1.625 ] + ], + [ + [ [ [ 1, -4, -5, 5, -5, -1 ], [ 3, -4, -5, 5, -5, -1 ], [ 2, -3, -5, 5, -5, -1 ], [ 3, -3, -5, 5, -5, -1 ] ], 1 ] + ], + [ + [ [ [ 1, -4, -5, 5, -5, -1 ], [ 3, -4, -5, 5, -5, -1 ], [ 3, -4, -6, 5, -5, -1 ], [ 3, -3, -5, 5, -5, -1 ] ], 1 ] + ], + [ + [ [ [ 1, -4, -5, 5, -5, -1 ], [ 3, -4, -5, 5, -5, -1 ], [ 3, -3, -6, 5, -5, -1 ], [ 3, -3, -5, 5, -5, -1 ] ], 1.75 ] + ], + [ + [ [ [ 1, -4, -5, 5, -5, -1 ], [ 3, -4, -5, 5, -5, -1 ], [ 4, -5, -5, 5, -5, -1 ], [ 3, -3, -5, 5, -5, -1 ] ], 1.375 ], + [ [ [ 1, -4, -5, 5, -5, -1 ], [ 3, -4, -5, 5, -5, -1 ], [ 4, -5, -5, 5, -5, -1 ], [ 4, -4, -6, 5, -5, -1 ] ], 0.75 ] + ], + [ + [ [ [ 1, -4, -5, 5, -5, -1 ], [ 3, -4, -5, 5, -5, -1 ], [ 3, -3, -5, 5, -5, -1 ], [ 4, -4, -6, 5, -5, -1 ] ], 1.5 ] + ], + [ + [ [ [ 1, -4, -5, 5, -5, -1 ], [ 3, -4, -5, 5, -5, -1 ], [ 3, -4, -5, 6, -5, -1 ], [ 4, -4, -6, 5, -5, -1 ] ], 1.375 ], + [ [ [ 1, -4, -5, 5, -5, -1 ], [ 3, -5, -5, 5, -5, -1 ], [ 3, -4, -5, 6, -5, -1 ], [ 4, -4, -6, 5, -5, -1 ] ], 1.375 ], + [ [ [ 1, -4, -5, 5, -5, -1 ], [ 3, -5, -5, 5, -5, -1 ], [ 3, -4, -5, 6, -5, -1 ], [ 2, -4, -5, 5, -5, 0 ] ], 1.25 ] + ], + [ + [ [ [ 1, -5, -5, 5, -5, 0 ], [ 3, -5, -5, 5, -5, -1 ], [ 3, -4, -5, 6, -5, -1 ], [ 2, -4, -5, 5, -5, 0 ] ], 0.5 ], + [ [ [ 1, -5, -5, 5, -5, 0 ], [ 3, -5, -5, 5, -5, -1 ], [ 4, -4, -5, 4, -5, 0 ], [ 2, -4, -5, 5, -5, 0 ] ], 1 ] + ], + [ + [ [ [ 2, -5, -5, 4, -5, 0 ], [ 3, -5, -5, 5, -5, -1 ], [ 4, -4, -5, 4, -5, 0 ], [ 2, -4, -5, 5, -5, 0 ] ], 1.375 ], + [ [ [ 2, -5, -5, 4, -5, 0 ], [ 2, -3, -5, 4, -5, 0 ], [ 4, -4, -5, 4, -5, 0 ], [ 2, -4, -5, 5, -5, 0 ] ], 1 ] + ], + [ + [ [ [ 2, -5, -5, 4, -5, 0 ], [ 2, -3, -5, 4, -5, 0 ], [ 4, -4, -5, 4, -5, 0 ], [ 3, -4, -5, 4, -5, 0 ] ], 1.625 ] + ], + [ + [ [ [ 1, -4, -5, 4, -5, 0 ], [ 2, -3, -5, 4, -5, 0 ], [ 4, -4, -5, 4, -5, 0 ], [ 3, -4, -5, 4, -5, 0 ] ], 1.375 ], + [ [ [ 1, -4, -5, 4, -5, 0 ], [ 2, -3, -5, 4, -5, 0 ], [ 4, -4, -5, 4, -5, 0 ], [ 2, -2, -5, 4, -5, 0 ] ], 1.75 ] + ], + [ + [ [ [ 2, -4, -5, 3, -5, 0 ], [ 2, -3, -5, 4, -5, 0 ], [ 4, -4, -5, 4, -5, 0 ], [ 2, -2, -5, 4, -5, 0 ] ], 1.375 ], + [ [ [ 2, -4, -5, 3, -5, 0 ], [ 3, -4, -6, 4, -5, 0 ], [ 4, -4, -5, 4, -5, 0 ], [ 2, -2, -5, 4, -5, 0 ] ], 1.25 ], + [ [ [ 2, -4, -5, 3, -5, 0 ], [ 3, -4, -6, 4, -5, 0 ], [ 4, -4, -5, 4, -5, 0 ], [ 3, -4, -4, 4, -5, 0 ] ], 0.75 ] + ], + [ + [ [ [ 2, -4, -5, 3, -5, 0 ], [ 3, -4, -6, 4, -5, 0 ], [ 4, -4, -6, 4, -5, 0 ], [ 3, -4, -4, 4, -5, 0 ] ], 1.125 ], + [ [ [ 2, -4, -5, 3, -5, 0 ], [ 3, -4, -6, 4, -5, 0 ], [ 4, -4, -6, 4, -5, 0 ], [ 4, -4, -6, 3, -5, 0 ] ], 0.875 ] + ], + [ + [ [ [ 2, -4, -5, 3, -5, 0 ], [ 3, -4, -7, 4, -5, 0 ], [ 4, -4, -6, 4, -5, 0 ], [ 4, -4, -6, 3, -5, 0 ] ], 1.375 ], + [ [ [ 3, -5, -6, 3, -5, 0 ], [ 3, -4, -7, 4, -5, 0 ], [ 4, -4, -6, 4, -5, 0 ], [ 4, -4, -6, 3, -5, 0 ] ], 1.75 ] + ], + [ + [ [ [ 3, -5, -6, 3, -5, 0 ], [ 3, -4, -7, 4, -5, 0 ], [ 5, -5, -7, 4, -5, 0 ], [ 4, -4, -6, 3, -5, 0 ] ], 1.125 ], + [ [ [ 3, -5, -6, 3, -5, 0 ], [ 3, -4, -7, 4, -5, 0 ], [ 5, -5, -7, 4, -5, 0 ], [ 5, -5, -7, 3, -5, 0 ] ], 1.5 ] + ], + [ + [ [ [ 3, -5, -6, 3, -5, 0 ], [ 3, -4, -7, 4, -5, 0 ], [ 5, -5, -7, 4, -5, 0 ], [ 4, -5, -6, 4, -5, 0 ] ], 0.625 ], + [ [ [ 3, -5, -6, 3, -5, 0 ], [ 5, -5, -6, 2, -5, 0 ], [ 5, -5, -7, 4, -5, 0 ], [ 4, -5, -6, 4, -5, 0 ] ], 1.375 ], + [ [ [ 3, -5, -6, 3, -5, 0 ], [ 5, -5, -6, 2, -5, 0 ], [ 5, -4, -6, 3, -5, 0 ], [ 4, -5, -6, 4, -5, 0 ] ], 1.375 ] + ], + [ + [ [ [ 3, -5, -6, 3, -5, 0 ], [ 5, -5, -6, 2, -5, 0 ], [ 5, -4, -6, 3, -5, 0 ], [ 5, -5, -6, 3, -5, 0 ] ], 0.75 ] + ], + [ + [ [ [ 3, -5, -6, 3, -5, 0 ], [ 5, -5, -6, 2, -5, 0 ], [ 5, -4, -6, 3, -5, 0 ], [ 6, -5, -6, 2, -5, 0 ] ], 0.5 ], + [ [ [ 4, -5, -6, 2, -5, 0 ], [ 5, -5, -6, 2, -5, 0 ], [ 5, -4, -6, 3, -5, 0 ], [ 6, -5, -6, 2, -5, 0 ] ], 1.125 ] + ], + [ + [ [ [ 4, -5, -6, 2, -5, 0 ], [ 5, -5, -6, 2, -5, 0 ], [ 5, -4, -6, 3, -5, 0 ], [ 4, -4, -6, 3, -5, 0 ] ], 1.25 ], + [ [ [ 4, -5, -6, 2, -5, 0 ], [ 4, -4, -7, 3, -5, 0 ], [ 5, -4, -6, 3, -5, 0 ], [ 4, -4, -6, 3, -5, 0 ] ], 1.25 ], + [ [ [ 4, -5, -6, 2, -5, 0 ], [ "Rest" ], [ 5, -4, -6, 3, -5, 0 ], [ 4, -4, -6, 3, -5, 0 ] ], 0.5 ], + [ [ [ "Rest" ], [ "Rest" ], [ 5, -4, -6, 3, -5, 0 ], [ 4, -4, -6, 3, -5, 0 ] ], 1.75 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 4, -4, -6, 3, -5, 0 ] ], 1.125 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 7.25 ] + ] + ] +], +"last_changes": +[ + [ [ 3, -5, -6, 3, -5, 0 ], [ 5, -5, -6, 2, -5, 0 ], [ 5, -4, -6, 3, -5, 0 ], [ 5, -5, -6, 3, -5, 0 ] ], + [ [ 3, -5, -6, 3, -5, 0 ], [ 5, -5, -6, 2, -5, 0 ], [ 5, -4, -6, 3, -5, 0 ], [ 6, -5, -6, 2, -5, 0 ] ], + [ [ 4, -5, -6, 2, -5, 0 ], [ 5, -5, -6, 2, -5, 0 ], [ 5, -4, -6, 3, -5, 0 ], [ 6, -5, -6, 2, -5, 0 ] ], + [ [ 4, -5, -6, 2, -5, 0 ], [ 5, -5, -6, 2, -5, 0 ], [ 5, -4, -6, 3, -5, 0 ], [ 4, -4, -6, 3, -5, 0 ] ], + [ [ 4, -5, -6, 2, -5, 0 ], [ 4, -4, -7, 3, -5, 0 ], [ 5, -4, -6, 3, -5, 0 ], [ 4, -4, -6, 3, -5, 0 ] ] +], +"cur_uid": "75316bf0", +"ref_uid": "55bd25a1", +"order_seed": 144453, +"dur_seed": 681001, +"motifs_seed": 933698, +"entrances_probs_vals": [ 0, 0, 0, 0.41, 1.84, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 0.41, 1.84, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 0.41, 1.84, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2430, -293 ], [ -869, 1211 ], [ -832, 1285 ], [ -702, 1211 ] ], +"step_probs_vals": [ -1200, 1200, 0.0020576131687243, 0.068181818181818, 0.074074074074074, 0.0625, 0.20576131687243, 0.0625, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61316872427983, 0, 0.98971193415638, 0 ], +"passages_weights": [ 0.48, 0.46, 0.48, 1, 1 ], +"hd_exp": 9, +"hd_invert": 0, +"order": +[ + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 0, 2 ], [ 3, 1 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 0, 2 ], [ 3, 1 ], [ ] ], + [ [ 3, 0 ], [ 1, 2 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 1 ], [ 0, 2, 3 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 0, 2 ], [ 3, 1 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 3 ], [ 0, 2, 1 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 2, 0 ], [ 3, 1 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 0, 3 ], [ 1, 2 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 2 ], [ 1, 3, 0 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 1 ], [ 0, 2, 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 2, 0 ], [ 1, 3 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 2, 1 ], [ 0, 3 ], [ ] ], + [ [ 1 ], [ 0, 2, 3 ], [ ] ], + [ [ 3 ], [ 0, 2, 1 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 0, 3 ], [ 2, 1 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 2, 1 ], [ 0, 3 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 2, 1 ], [ 0, 3 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 0, 2 ], [ 3, 1 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 100, 100 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/781442dc/781442dc_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/781442dc/781442dc_code.scd new file mode 100644 index 0000000..c194eef --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/781442dc/781442dc_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/781442dc/781442dc_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/781442dc/781442dc_mus_model.json new file mode 100644 index 0000000..d2de366 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/781442dc/781442dc_mus_model.json @@ -0,0 +1,117 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.5 ], + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], + [ [ [ 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, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.375 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 0, -1, 0, 0, 0, 1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 1 ], [ -1, 0, 0, 0, 1, 1 ], [ 0, 0, 0, 0, 1, 0 ], [ 0, -1, 0, 0, 0, 1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 1 ], [ -1, 0, 0, 0, 1, 1 ], [ -1, 0, 0, 1, 0, 1 ], [ 0, -1, 0, 0, 0, 1 ] ], 0.25 ], + [ [ [ 0, 0, 0, 0, 0, 1 ], [ -1, 0, 0, 0, 1, 1 ], [ -1, 0, 0, 1, 0, 1 ], [ 0, 0, 0, 0, -1, 1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 1 ], [ -1, 0, 0, 0, 1, 1 ], [ -1, 0, 0, 0, 0, 2 ], [ 0, 0, 0, 0, -1, 1 ] ], 0.875 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 1 ], [ -1, 0, 0, 0, 1, 1 ], [ -1, 0, 0, 0, 0, 2 ], [ "Rest" ] ], 0 ], + [ [ [ 0, -1, 0, 0, 0, 2 ], [ -1, 0, 0, 0, 1, 1 ], [ -1, 0, 0, 0, 0, 2 ], [ "Rest" ] ], 0 ], + [ [ [ 0, -1, 0, 0, 0, 2 ], [ -1, 0, -1, 0, 0, 2 ], [ -1, 0, 0, 0, 0, 2 ], [ "Rest" ] ], 0.25 ], + [ [ [ -1, 0, 0, 0, 1, 2 ], [ -1, 0, -1, 0, 0, 2 ], [ -1, 0, 0, 0, 0, 2 ], [ "Rest" ] ], 0.25 ], + [ [ [ -1, 0, 1, 0, 0, 2 ], [ -1, 0, -1, 0, 0, 2 ], [ -1, 0, 0, 0, 0, 2 ], [ "Rest" ] ], 0.25 ], + [ [ [ -2, 0, 1, 0, 0, 2 ], [ -1, 0, -1, 0, 0, 2 ], [ -1, 0, 0, 0, 0, 2 ], [ "Rest" ] ], 1.375 ] + ], + [ + [ [ [ -2, 0, 1, 0, 0, 2 ], [ -1, 0, -1, 0, 0, 2 ], [ -1, 0, 0, 0, 0, 2 ], [ 0, 0, 0, 0, -1, 1 ] ], 0.5 ], + [ [ [ -2, 0, 1, 0, 0, 2 ], [ -1, 0, 1, 0, 0, 1 ], [ -1, 0, 0, 0, 0, 2 ], [ 0, 0, 0, 0, -1, 1 ] ], 0 ], + [ [ [ -2, 0, 1, 0, 0, 2 ], [ -1, 0, 1, 0, 0, 1 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 1 ] ], 0.625 ], + [ [ [ -2, 0, 1, 0, 0, 2 ], [ 0, 0, -1, 0, -1, 1 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 1 ] ], 0 ], + [ [ [ -2, 0, 1, 0, 0, 2 ], [ 0, 0, -1, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 1 ], [ 0, 0, 0, 0, -1, 1 ] ], 1 ] + ], + [ + [ [ [ -1, 1, 0, 0, -1, 1 ], [ 0, 0, -1, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 1 ], [ 0, 0, 0, 0, -1, 1 ] ], 0 ], + [ [ [ -1, 1, 0, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 1 ], [ 0, 0, 0, 0, -1, 1 ] ], 0.625 ], + [ [ [ 0, -1, 1, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 1 ], [ 0, 0, 0, 0, -1, 1 ] ], 0.625 ], + [ [ [ 0, 0, -1, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 1 ], [ 0, 0, 0, 0, -1, 1 ] ], 0 ], + [ [ [ 0, 0, -1, 0, -1, 1 ], [ 1, -1, 0, -1, -1, 1 ], [ 1, -1, 0, 0, -1, 1 ], [ 0, 0, 0, 0, -1, 1 ] ], 1.125 ] + ], + [ + [ [ [ 0, 0, -1, 0, -1, 1 ], [ 1, -1, 0, -1, -1, 1 ], [ 1, -1, 0, 0, -1, 1 ], [ "Rest" ] ], 0 ], + [ [ [ 0, 0, -1, 0, -1, 1 ], [ 1, -1, 0, -1, -1, 1 ], [ 1, -1, 0, -1, -1, 2 ], [ "Rest" ] ], 0.625 ], + [ [ [ 0, 0, -1, 0, -1, 1 ], [ 1, -1, 0, -1, -1, 1 ], [ 2, -1, -1, -1, -1, 1 ], [ "Rest" ] ], 0.5 ], + [ [ [ 0, 0, -1, 0, -1, 1 ], [ 1, -1, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 1 ], [ "Rest" ] ], 1.375 ] + ], + [ + [ [ [ 0, 0, 0, -1, 0, 1 ], [ 1, -1, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 1 ], [ "Rest" ] ], 0 ], + [ [ [ 0, 0, 0, -1, 0, 1 ], [ 1, -1, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, -1, 1, -1, -1, 1 ] ], 0.375 ], + [ [ [ 2, -1, 0, -2, -1, 1 ], [ 1, -1, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, -1, 1, -1, -1, 1 ] ], 0 ], + [ [ [ 2, -1, 0, -2, -1, 1 ], [ 1, -1, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, -1, -1, -1, 1 ] ], 1 ] + ], + [ + [ [ [ 1, 0, 0, -1, -2, 1 ], [ 1, -1, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, -1, -1, -1, 1 ] ], 0 ], + [ [ [ 1, 0, 0, -1, -2, 1 ], [ 0, 0, 1, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, -1, -1, -1, 1 ] ], 0.625 ], + [ [ [ 1, 0, 0, -1, -2, 1 ], [ 1, 0, -2, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, -1, -1, -1, 1 ] ], 0.25 ], + [ [ [ 1, 0, 0, -1, -2, 1 ], [ 0, 1, -1, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, -1, -1, -1, 1 ] ], 1.375 ] + ], + [ + [ [ [ 1, 1, -1, -1, -1, 0 ], [ 0, 1, -1, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, -1, -1, -1, 1 ] ], 0.375 ], + [ [ [ 0, 0, 0, -2, -1, 1 ], [ 0, 1, -1, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, -1, -1, -1, 1 ] ], 0.375 ], + [ [ [ -1, 1, -1, -1, -1, 1 ], [ 0, 1, -1, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, -1, -1, -1, 1 ] ], 1.25 ] + ], + [ + [ [ [ -1, 1, -1, -1, -1, 1 ], [ 0, 1, -1, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 1 ], [ 0, 0, 0, -1, -1, 2 ] ], 0 ], + [ [ [ -1, 1, -1, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, -1, 1 ], [ 0, 0, 0, -1, -1, 2 ] ], 0 ], + [ [ [ 0, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, -1, 1 ], [ 0, 0, 0, -1, -1, 2 ] ], 0.25 ], + [ [ [ 0, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, -1, 1 ], [ 0, 0, 0, 0, -1, 1 ] ], 0.625 ], + [ [ [ 0, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 2 ] ], 1.375 ], + [ [ [ 0, 0, 0, -1, -1, 0 ], [ "Rest" ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 2 ] ], 0 ], + [ [ [ 0, 0, 0, -1, -1, 0 ], [ "Rest" ], [ 1, 0, 0, -1, -1, 1 ], [ "Rest" ] ], 0 ], + [ [ [ 0, 0, 0, -1, -1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 5.625 ] + ] + ] +], +"last_changes": +[ + [ [ -1, 1, -1, -1, -1, 1 ], [ 0, 1, -1, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 1 ], [ 0, 0, 0, -1, -1, 2 ] ], + [ [ -1, 1, -1, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, -1, 1 ], [ 0, 0, 0, -1, -1, 2 ] ], + [ [ 0, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, -1, 1 ], [ 0, 0, 0, -1, -1, 2 ] ], + [ [ 0, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, -1, 1 ], [ 0, 0, 0, 0, -1, 1 ] ], + [ [ 0, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, -1, -1, 1 ], [ 1, 0, 0, -1, -1, 2 ] ] +], +"cur_uid": "781442dc", +"ref_uid": "nil", +"order_seed": 479669, +"dur_seed": 398026, +"motifs_seed": 801394, +"entrances_probs_vals": [ 0.43, 0, 0, 0, 0.85164835164835, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 1, 0, 0.99206349206349, 0.16483516483516, 0.66, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0, 0.95238095238095, 0, 1.043956043956, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -1983.9009287926, 1100 ], [ -999, 1322.600619195 ], [ -14.860681114551, 1676 ], [ 78.018575851393, 1694 ] ], +"step_probs_vals": [ 0, 1200, 0, 0.5, 0.076131687242798, 0.91477272727273, 0.17489711934156, 0, 0.57818930041152, 0, 1, 0 ], +"passages_weights": [ 0.54, 0.47, 0.52, 0.57, 0.58 ], +"hd_exp": -0.22, +"hd_invert": 0, +"order": +[ + [ [ 3, 1 ], [ 2, 0, 0, 2 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 3, 2 ], [ ] ], + [ [ 2 ], [ 0, 1, 0, 0, 0 ], [ 3 ] ], + [ [ 0, 3 ], [ 1, 2, 1, 2 ], [ ] ], + [ [ 2, 3 ], [ 0, 1, 0, 0, 1 ], [ ] ], + [ [ 1, 0 ], [ 2, 2, 2 ], [ 3 ] ], + [ [ 1, 2 ], [ 0, 3, 0, 3 ], [ ] ], + [ [ 3, 2 ], [ 0, 1, 1, 1 ], [ ] ], + [ [ 1, 2, 3 ], [ 0, 0, 0 ], [ ] ], + [ [ 2 ], [ 3, 1, 0, 3, 3 ], [ ] ] +], +"sus_weights": [ 0.44, 0.41, 0.28 ], +"order_size": [ 10, 10 ], +"passages_size": [ 2, 4 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/7c2de94c/7c2de94c_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/7c2de94c/7c2de94c_code.scd new file mode 100644 index 0000000..dc13462 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/7c2de94c/7c2de94c_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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 = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + if(pDistance < 0, {stepFunc.value(pDistance)}, {0}); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, 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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[-3, 0, 0, 0, 0, 0], [-3, 0, 0, 0, 0, 0], [-3, 0, 0, 0, 0, 0], [-3, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[-3, 0, 0, 0, 0, 0], [-3, 0, 0, 0, 0, 0], [-3, 0, 0, 0, 0, 0], [-3, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/7c2de94c/7c2de94c_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/7c2de94c/7c2de94c_mus_model.json new file mode 100644 index 0000000..37e7285 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/7c2de94c/7c2de94c_mus_model.json @@ -0,0 +1,163 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ] ], 0.125 ], + [ [ [ "Rest" ], [ "Rest" ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 1.125 ], + [ [ [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 1.125 ], + [ [ [ -1, 0, 1, 0, 0, 1 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0.875 ] + ], + [ + [ [ [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0.375 ] + ], + [ + [ [ [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 1, 0, 0, -1, 0, 0 ], [ 3, -1, 0, -1, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ] ], 0.75 ] + ], + [ + [ [ [ 0, -1, 0, 1, 0, 0 ], [ 3, -1, 0, -1, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ] ], 0.375 ] + ], + [ + [ [ [ 0, -1, 0, 1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ] ], 0.125 ] + ], + [ + [ [ [ 0, -1, 0, 1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ] ], 0.75 ] + ], + [ + [ [ [ 0, -1, 0, 1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, -1, 1, 0, 0 ] ], 0.375 ] + ], + [ + [ [ [ 0, -1, 0, 0, 0, -1 ], [ 2, 0, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, -1, 1, 0, 0 ] ], 0.5 ] + ], + [ + [ [ [ 0, -1, 0, 0, 0, -1 ], [ 2, -1, -1, 1, 0, -1 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, -1, 1, 0, 0 ] ], 0 ] + ], + [ + [ [ [ 0, -1, 0, 0, 0, -1 ], [ 2, -1, -1, 1, 0, -1 ], [ 2, 0, 0, 0, 0, -1 ], [ 1, -1, -1, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, -1, 0, 0, 0, -1 ], [ 3, -1, 0, 0, 0, -2 ], [ 2, 0, 0, 0, 0, -1 ], [ 1, -1, -1, 1, 0, 0 ] ], 0.5 ] + ], + [ + [ [ [ 0, -1, 0, 0, 0, -1 ], [ 2, -1, 1, 0, 0, -1 ], [ 2, 0, 0, 0, 0, -1 ], [ 1, -1, -1, 1, 0, 0 ] ], 0.875 ] + ], + [ + [ [ [ 0, -1, 0, 0, 0, -1 ], [ 2, -1, 1, 0, 0, -1 ], [ 2, 0, 0, 0, 0, -1 ], [ 3, -1, 0, 0, 0, -2 ] ], 1.125 ] + ], + [ + [ [ [ 0, -1, 0, 0, 0, -1 ], [ 2, -1, 1, 0, 0, -1 ], [ 3, -1, 1, 0, 0, -2 ], [ 3, -1, 0, 0, 0, -2 ] ], 0.625 ] + ], + [ + [ [ [ 1, -1, 1, 0, 0, -2 ], [ 2, -1, 1, 0, 0, -1 ], [ 3, -1, 1, 0, 0, -2 ], [ 3, -1, 0, 0, 0, -2 ] ], 0.125 ] + ], + [ + [ [ [ 1, -1, 1, 0, 0, -2 ], [ 2, -1, 1, 0, 0, -1 ], [ 3, -1, 1, 0, 0, -2 ], [ 3, -1, 1, -1, 0, -1 ] ], 0.5 ] + ], + [ + [ [ [ 1, -1, 1, 0, 0, -2 ], [ 2, -1, 1, 0, 0, -1 ], [ 3, -1, 1, 0, 0, -2 ], [ 2, -1, 2, 0, 0, -1 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, 1, 0, 0, -2 ], [ 2, -1, 1, 0, 0, -1 ], [ -1, 0, 1, 0, 0, -1 ], [ 2, -1, 2, 0, 0, -1 ] ], 0.75 ] + ], + [ + [ [ [ 1, -1, 1, 0, 0, -2 ], [ 2, -1, 1, 0, 0, -1 ], [ -1, 0, 2, 0, 0, -1 ], [ 2, -1, 2, 0, 0, -1 ] ], 0.125 ] + ], + [ + [ [ [ 1, -1, 1, 0, 0, -2 ], [ 2, -1, 1, 0, 0, -1 ], [ 3, -1, 0, 0, 0, -2 ], [ 2, -1, 2, 0, 0, -1 ] ], 0.625 ] + ], + [ + [ [ [ 1, -1, 1, 0, 0, -2 ], [ 2, -1, 1, 0, 0, -1 ], [ 3, -1, 1, 0, 0, -2 ], [ 2, -1, 2, 0, 0, -1 ] ], 1 ] + ], + [ + [ [ [ 1, -1, 1, 0, 0, -2 ], [ 2, -1, 1, 0, 0, -1 ], [ 3, -1, 1, 0, 0, -2 ], [ 3, -1, 0, 0, 0, -2 ] ], 0.125 ] + ], + [ + [ [ [ 1, -1, 1, 0, 0, -2 ], [ 4, -1, 0, -1, 0, -2 ], [ 3, -1, 1, 0, 0, -2 ], [ 3, -1, 0, 0, 0, -2 ] ], 0.5 ] + ], + [ + [ [ [ 1, -1, 1, 0, 0, -2 ], [ 0, -1, 0, 0, 0, -1 ], [ 3, -1, 1, 0, 0, -2 ], [ 3, -1, 0, 0, 0, -2 ] ], 0.625 ] + ], + [ + [ [ [ 1, -1, 0, 1, 0, -2 ], [ 0, -1, 0, 0, 0, -1 ], [ 3, -1, 1, 0, 0, -2 ], [ 3, -1, 0, 0, 0, -2 ] ], 0.75 ] + ], + [ + [ [ [ 1, -1, 0, 1, 0, -2 ], [ 0, -1, 0, 0, 0, -1 ], [ 3, -1, 0, 1, -1, -2 ], [ 3, -1, 0, 0, 0, -2 ] ], 0.5 ] + ], + [ + [ [ [ 1, -1, 0, 1, 0, -2 ], [ 1, -2, 0, 1, 0, -2 ], [ 3, -1, 0, 1, -1, -2 ], [ 3, -1, 0, 0, 0, -2 ] ], 1 ] + ], + [ + [ [ [ 1, -1, 0, 1, 0, -2 ], [ 1, -2, 0, 1, 0, -2 ], [ 3, -1, -1, 1, 0, -2 ], [ 3, -1, 0, 0, 0, -2 ] ], 0.125 ] + ], + [ + [ [ [ 1, -1, 0, 1, 0, -2 ], [ 1, -2, 0, 1, 0, -2 ], [ 0, -1, 0, 0, 0, -1 ], [ 3, -1, 0, 0, 0, -2 ] ], 0.875 ], + [ [ [ 1, -1, 0, 1, 0, -2 ], [ 1, -2, 0, 1, 0, -2 ], [ 0, -1, 0, 0, 0, -1 ], [ "Rest" ] ], 0.375 ], + [ [ [ 1, -1, 0, 1, 0, -2 ], [ 1, -2, 0, 1, 0, -2 ], [ "Rest" ], [ "Rest" ] ], 0.5 ], + [ [ [ 1, -1, 0, 1, 0, -2 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0.625 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 6.5 ] + ] + ] +], +"last_changes": +[ + [ [ 1, -1, 0, 1, 0, -2 ], [ 0, -1, 0, 0, 0, -1 ], [ 3, -1, 1, 0, 0, -2 ], [ 3, -1, 0, 0, 0, -2 ] ], + [ [ 1, -1, 0, 1, 0, -2 ], [ 0, -1, 0, 0, 0, -1 ], [ 3, -1, 0, 1, -1, -2 ], [ 3, -1, 0, 0, 0, -2 ] ], + [ [ 1, -1, 0, 1, 0, -2 ], [ 1, -2, 0, 1, 0, -2 ], [ 3, -1, 0, 1, -1, -2 ], [ 3, -1, 0, 0, 0, -2 ] ], + [ [ 1, -1, 0, 1, 0, -2 ], [ 1, -2, 0, 1, 0, -2 ], [ 3, -1, -1, 1, 0, -2 ], [ 3, -1, 0, 0, 0, -2 ] ], + [ [ -2, -1, 0, 1, 0, -2 ], [ -2, -2, 0, 1, 0, -2 ], [ -2, -1, 0, 0, 0, -1 ], [ -2, -1, 0, 0, 0, -2 ] ] +], +"cur_uid": "7c2de94c", +"ref_uid": "5201b8af", +"order_seed": 869423, +"dur_seed": 680450, +"motifs_seed": 533263, +"entrances_probs_vals": [ 0, 0, 0, 0, 1.2087912087912, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 0, 1.2087912087912, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 0, 1.2087912087912, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2169.6594427245, 338 ], [ -2522.600619195, 1453 ], [ -1649.5356037152, 1676 ], [ -2894.1176470588, 1694 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.063786008230453, 0.92613636363636, 0.12757201646091, 0, 0.54732510288066, 0, 0.71604938271605, 0, 1, 0 ], +"passages_weights": [ 1, 0, 0.2, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ] +], +"sus_weights": [ 0, 0, 0.61 ], +"order_size": [ 30, 30 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/7e230015/7e230015_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3/7e230015/7e230015_code.scd new file mode 100644 index 0000000..7c7b526 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/7e230015/7e230015_code.scd @@ -0,0 +1,975 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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(-10); +}; + +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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/7e230015/7e230015_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/7e230015/7e230015_mus_model.json new file mode 100644 index 0000000..7948320 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/7e230015/7e230015_mus_model.json @@ -0,0 +1,532 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ "Rest" ], [ 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 ] ], 1 ] + ], + [ + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 0, -1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 0, -1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 0, -1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 0, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 0, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 1 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 0, 0, 0, 0, 0 ], [ -1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 1 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ -1, 0, 1, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 0, 0, 0, 0, 0 ], [ -1, 0, 1, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 0, 0, 0, 0, 0 ], [ -1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 1, 1, 0, 0, 0 ], [ -1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 1, 1, 0, 0, 0 ], [ -1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 1, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -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 ], + [ [ [ -1, 0, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 0, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 0, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ -1, 0, 2, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 0, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ -1, 0, 2, 1, 0, 0 ], [ -1, 0, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 0, 1, 0, 0, 0 ], [ 0, -1, 2, 0, 0, 0 ], [ -1, 0, 2, 1, 0, 0 ], [ -1, 0, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -1, -1, 2, 0, 0, 0 ], [ 0, -1, 2, 0, 0, 0 ], [ -1, 0, 2, 1, 0, 0 ], [ -1, 0, 2, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, -1, 2, 1, 0, 0 ], [ 0, -1, 2, 0, 0, 0 ], [ -1, 0, 2, 1, 0, 0 ], [ -1, 0, 2, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, -1, 2, 1, 0, 0 ], [ -1, 1, 2, 0, 0, 0 ], [ -1, 0, 2, 1, 0, 0 ], [ -1, 0, 2, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, -1, 2, 1, 0, 0 ], [ -1, 1, 2, 0, 0, 0 ], [ -1, 0, 2, 1, 0, 0 ], [ -2, 0, 2, 1, 0, 0 ] ], 1 ], + [ [ [ -2, 1, 2, 1, 0, 0 ], [ -1, 1, 2, 0, 0, 0 ], [ -1, 0, 2, 1, 0, 0 ], [ -2, 0, 2, 1, 0, 0 ] ], 1 ], + [ [ [ -2, 1, 2, 1, 0, 0 ], [ -1, -1, 2, 1, 0, 0 ], [ -1, 0, 2, 1, 0, 0 ], [ -2, 0, 2, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 2, 1, 0, 0 ], [ -1, -1, 2, 1, 0, 0 ], [ -1, 0, 2, 1, 0, 0 ], [ -1, -1, 1, 1, 0, 0 ] ], 1 ], + [ [ [ -1, -1, 3, 1, 0, 0 ], [ -1, -1, 2, 1, 0, 0 ], [ -1, 0, 2, 1, 0, 0 ], [ -1, -1, 1, 1, 0, 0 ] ], 1 ], + [ [ [ -1, -1, 3, 1, 0, 0 ], [ -1, -1, 2, 1, 0, 0 ], [ 0, -1, 1, 1, 0, 0 ], [ -1, -1, 1, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, -1, 3, 1, 0, 0 ], [ -1, -1, 2, 1, 0, 0 ], [ 0, -1, 1, 1, 0, 0 ], [ -1, -1, 1, 1, 0, 1 ] ], 1 ], + [ [ [ -1, -1, 3, 1, 0, 0 ], [ 0, -2, 1, 1, 0, 0 ], [ 0, -1, 1, 1, 0, 0 ], [ -1, -1, 1, 1, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -1, -1, 3, 1, 0, 0 ], [ 0, -2, 1, 1, 0, 0 ], [ 0, -2, 1, 1, 0, 1 ], [ -1, -1, 1, 1, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -1, -1, 3, 1, 0, 0 ], [ 0, -2, 1, 1, 0, 0 ], [ 0, -2, 1, 1, 0, 1 ], [ 1, -3, 1, 1, 0, 0 ] ], 1 ], + [ [ [ 0, -2, 2, 1, 0, 0 ], [ 0, -2, 1, 1, 0, 0 ], [ 0, -2, 1, 1, 0, 1 ], [ 1, -3, 1, 1, 0, 0 ] ], 1 ], + [ [ [ 0, -2, 2, 1, 0, 0 ], [ 0, -2, 1, 1, 0, 0 ], [ 0, -2, 1, 2, 0, 0 ], [ 1, -3, 1, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, -2, 2, 1, 0, 0 ], [ 0, -2, 1, 1, 0, 0 ], [ 0, -2, 1, 2, 0, 0 ], [ 1, -2, 1, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, -2, 2, 1, 0, 0 ], [ 0, -2, 1, 1, 0, 0 ], [ 0, -2, 1, 2, 0, 0 ], [ 0, -2, 0, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, -2, 1, 2, 0, 0 ], [ 0, -2, 1, 1, 0, 0 ], [ 0, -2, 1, 2, 0, 0 ], [ 0, -2, 0, 2, 0, 0 ] ], 1 ], + [ [ [ -1, -2, 1, 2, 0, 0 ], [ 0, -2, 1, 1, 0, 0 ], [ 0, -2, 1, 2, 0, 0 ], [ -1, -2, 1, 3, 0, 0 ] ], 1 ], + [ [ [ -1, -2, 1, 2, 0, 0 ], [ -1, -3, 1, 2, 0, 0 ], [ 0, -2, 1, 2, 0, 0 ], [ -1, -2, 1, 3, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, -2, 1, 2, 0, 0 ], [ -1, -3, 1, 2, 0, 0 ], [ 0, -2, 1, 2, 0, 0 ], [ 0, -3, 1, 2, 0, 0 ] ], 1 ], + [ [ [ -1, -2, 1, 2, 0, 0 ], [ -2, -1, 1, 2, 0, 0 ], [ 0, -2, 1, 2, 0, 0 ], [ 0, -3, 1, 2, 0, 0 ] ], 1 ], + [ [ [ -1, -2, 1, 2, 0, 0 ], [ -2, -1, 1, 2, 0, 0 ], [ 1, -2, 1, 1, 0, 0 ], [ 0, -3, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, -2, 1, 2, 0, 0 ], [ -2, -1, 1, 2, 0, 0 ], [ 1, -2, 1, 1, 0, 0 ], [ -1, -1, 1, 2, 0, 0 ] ], 1 ], + [ [ [ 0, -2, 1, 1, 0, 0 ], [ -2, -1, 1, 2, 0, 0 ], [ 1, -2, 1, 1, 0, 0 ], [ -1, -1, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 0, 1, 2, 0, 0 ], [ -2, -1, 1, 2, 0, 0 ], [ 1, -2, 1, 1, 0, 0 ], [ -1, -1, 1, 2, 0, 0 ] ], 1 ], + [ [ [ -1, 0, 1, 2, 0, 0 ], [ -2, -1, 1, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ], [ -1, -1, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, -1, 1, 2, 0, 0 ], [ -2, -1, 1, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ], [ -1, -1, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, -1, 1, 2, 0, 0 ], [ -2, -1, 1, 2, 0, 0 ], [ -1, -1, 0, 2, 0, 0 ], [ -1, -1, 1, 2, 0, 0 ] ], 1 ], + [ [ [ -3, -1, 1, 2, 0, 0 ], [ -2, -1, 1, 2, 0, 0 ], [ -1, -1, 0, 2, 0, 0 ], [ -2, -1, 2, 2, 0, 0 ] ], 1 ], + [ [ [ -3, -1, 1, 2, 0, 0 ], [ -1, -1, 1, 1, 0, 0 ], [ -1, -1, 0, 2, 0, 0 ], [ -2, -1, 2, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, -1, 1, 2, 0, 0 ], [ -1, -1, 1, 1, 0, 0 ], [ -1, -1, 2, 2, 0, 0 ], [ -2, -1, 2, 2, 0, 0 ] ], 1 ], + [ [ [ -3, -1, 1, 2, 0, 0 ], [ -2, -2, 2, 2, 0, 0 ], [ -1, -1, 2, 2, 0, 0 ], [ -2, -1, 2, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, -1, 1, 2, 0, 0 ], [ -2, -2, 2, 2, 0, 0 ], [ -1, -1, 2, 2, 0, 0 ], [ -1, -2, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, -1, 1, 2, 0, 0 ], [ -2, -2, 2, 2, 0, 0 ], [ -1, -1, 2, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ] ], 1 ], + [ [ [ -3, -1, 1, 2, 0, 0 ], [ -2, -2, 2, 2, 0, 0 ], [ 0, -2, 1, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ] ], 1 ], + [ [ [ -3, -1, 1, 2, 0, 0 ], [ -2, -1, 2, 2, 0, 0 ], [ 0, -2, 1, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, -1, 1, 2, 0, 0 ], [ -1, -2, 1, 2, 0, 0 ], [ 0, -2, 1, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ] ], 1 ], + [ [ [ -2, -2, 1, 2, 0, 0 ], [ -1, -2, 1, 2, 0, 0 ], [ 0, -2, 1, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, -1, 1, 2, 0, 0 ], [ -1, -2, 1, 2, 0, 0 ], [ 0, -2, 1, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ] ], 1 ], + [ [ [ -2, -1, 1, 2, 0, 0 ], [ -1, -2, 1, 2, 0, 0 ], [ -1, 0, 1, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 0, 1, 2, 0, 0 ], [ -1, -2, 1, 2, 0, 0 ], [ -1, 0, 1, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ] ], 1 ], + [ [ [ -3, 0, 1, 2, 0, 0 ], [ -2, -1, 1, 2, 0, 0 ], [ -1, 0, 1, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 0, 1, 2, 0, 0 ], [ -3, 1, 1, 2, 0, 0 ], [ -1, 0, 1, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 0, 1, 2, 0, 0 ], [ -3, 1, 1, 2, 0, 0 ], [ -1, 0, 1, 2, 0, 0 ], [ -3, 2, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 0, 1, 2, 0, 0 ], [ -3, 1, 1, 2, 0, 0 ], [ -2, 1, 1, 2, 0, 0 ], [ -3, 2, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 0, 1, 2, 0, 0 ], [ -3, 1, 1, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ], [ -3, 2, 1, 2, 0, 0 ] ], 1 ], + [ [ [ -3, 0, 1, 2, 0, 0 ], [ -3, 1, 1, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ], [ -2, 1, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 1, 1, 2, 0, 0 ], [ -3, 1, 1, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ], [ -2, 1, 1, 2, 0, 0 ] ], 1 ], + [ [ [ -4, 1, 1, 2, 0, 0 ], [ -2, 0, 0, 2, 0, 0 ], [ -2, 0, 1, 2, 0, 0 ], [ -2, 1, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 1, 1, 2, 0, 0 ], [ -2, 0, 0, 2, 0, 0 ], [ -3, 1, 1, 2, 0, 0 ], [ -2, 1, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 1, 1, 2, 0, 0 ], [ -2, 0, 0, 2, 0, 0 ], [ -2, 1, 1, 1, 0, 0 ], [ -2, 1, 1, 2, 0, 0 ] ], 1 ], + [ [ [ -4, 1, 1, 2, 0, 0 ], [ -4, 2, 1, 2, 0, 0 ], [ -2, 1, 1, 1, 0, 0 ], [ -2, 1, 1, 2, 0, 0 ] ], 1 ], + [ [ [ -3, 1, 1, 1, 0, 0 ], [ -4, 2, 1, 2, 0, 0 ], [ -2, 1, 1, 1, 0, 0 ], [ -2, 1, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 1, 1, 1, 0, 0 ], [ -4, 2, 1, 2, 0, 0 ], [ -2, 1, 1, 1, 0, 0 ], [ -1, 1, 1, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 1, 1, 1, 0, 0 ], [ -3, 2, 1, 1, 0, 0 ], [ -2, 1, 1, 1, 0, 0 ], [ -1, 1, 1, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 1, 1, 1, 0, 0 ], [ -3, 2, 1, 1, 0, 0 ], [ -2, 1, 1, 1, 0, 0 ], [ -2, 2, 1, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 1, 1, 1, 0, 0 ], [ -3, 2, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 0, 0 ], [ -2, 2, 1, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 1, 1, 1, 0, 0 ], [ -3, 2, 1, 1, 0, 1 ], [ -3, 3, 1, 1, 0, 0 ], [ -2, 2, 1, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 2, 1, 1, 0, 0 ], [ -3, 2, 1, 1, 0, 1 ], [ -3, 3, 1, 1, 0, 0 ], [ -2, 2, 1, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 1, 1, 0, 0 ], [ -4, 4, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 0, 0 ], [ -2, 2, 1, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 2, 1, 1, 0, 0 ], [ -4, 4, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 0, 0 ], [ -3, 4, 1, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 1, 1, 0, 0 ], [ -4, 4, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 0, 0 ], [ -2, 3, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 2, 1, 1, 0, 0 ], [ -3, 3, 0, 1, 0, 0 ], [ -3, 3, 1, 1, 0, 0 ], [ -2, 3, 0, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 1, 1, 0, 0 ], [ -4, 3, 1, 2, 0, 0 ], [ -3, 3, 1, 1, 0, 0 ], [ -2, 3, 0, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 1, 1, 0, 0 ], [ -4, 3, 1, 2, 0, 0 ], [ -4, 3, 2, 2, 0, 0 ], [ -2, 3, 0, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 1, 1, 0, 0 ], [ -4, 3, 1, 2, 0, 0 ], [ -3, 2, 1, 2, 0, 0 ], [ -2, 3, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 2, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 0, 0 ], [ -3, 2, 1, 2, 0, 0 ], [ -2, 3, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 2, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 0, 0 ], [ -3, 2, 1, 2, 0, 0 ], [ -1, 1, 1, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 3, 1, 2, 0, 0 ], [ -3, 3, 1, 1, 0, 0 ], [ -3, 2, 1, 2, 0, 0 ], [ -1, 1, 1, 1, 0, 0 ] ], 1 ], + [ [ [ -5, 3, 1, 2, 0, 0 ], [ -2, 2, 0, 2, 0, 0 ], [ -3, 2, 1, 2, 0, 0 ], [ -1, 1, 1, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 1, 1, 2, 0, 0 ], [ -2, 2, 0, 2, 0, 0 ], [ -3, 2, 1, 2, 0, 0 ], [ -1, 1, 1, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 1, 1, 2, 0, 0 ], [ -2, 1, 1, 2, 0, 0 ], [ -3, 2, 1, 2, 0, 0 ], [ -1, 1, 1, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 1, 1, 2, 0, 0 ], [ -2, 1, 1, 2, 0, 0 ], [ -2, 1, 1, 1, 0, 0 ], [ -1, 1, 1, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 1, 1, 2, 0, 0 ], [ -3, 2, 1, 2, 0, 0 ], [ -2, 1, 1, 1, 0, 0 ], [ -1, 1, 1, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 1, 1, 2, 0, 0 ], [ -3, 2, 1, 2, 0, 0 ], [ -2, 1, 1, 1, 1, 0 ], [ -1, 1, 1, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 1, 1, 2, 0, 0 ], [ -3, 2, 1, 2, 0, 0 ], [ -2, 1, 1, 1, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -2, 1, 2, 1, 1, 0 ], [ -3, 2, 1, 2, 0, 0 ], [ -2, 1, 1, 1, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -2, 1, 2, 1, 1, 0 ], [ -3, 1, 1, 1, 1, 0 ], [ -2, 1, 1, 1, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 2, 1, 1, 0 ], [ -4, 1, 2, 2, 1, 0 ], [ -2, 1, 1, 1, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 2, 1, 1, 0 ], [ -3, 1, 2, 1, 1, 0 ], [ -2, 1, 1, 1, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -2, 1, 2, 1, 1, 0 ], [ -3, 1, 2, 1, 1, 0 ], [ -2, 1, 1, 1, 1, 0 ], [ -3, 2, 2, 1, 1, 0 ] ], 1 ], + [ [ [ -2, 1, 2, 1, 1, 0 ], [ -3, 1, 2, 1, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ], [ -3, 2, 2, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 2, 1, 1, 0 ], [ -4, 3, 2, 1, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ], [ -3, 2, 2, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 3, 2, 1, 1, 0 ], [ -4, 3, 2, 1, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ], [ -3, 2, 2, 1, 1, 0 ] ], 1 ], + [ [ [ -3, 3, 2, 1, 1, 0 ], [ -4, 2, 2, 1, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ], [ -3, 2, 2, 1, 1, 0 ] ], 1 ], + [ [ [ -3, 3, 2, 1, 1, 0 ], [ -4, 2, 2, 1, 1, 0 ], [ -4, 3, 2, 1, 1, 0 ], [ -3, 2, 2, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 3, 2, 1, 1, 0 ], [ -5, 4, 2, 1, 1, 0 ], [ -4, 3, 2, 1, 1, 0 ], [ -3, 2, 2, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 4, 2, 1, 1, 0 ], [ -5, 4, 2, 1, 1, 0 ], [ -4, 3, 2, 1, 1, 0 ], [ -3, 2, 2, 1, 1, 0 ] ], 1 ], + [ [ [ -4, 4, 2, 1, 1, 0 ], [ -5, 4, 2, 1, 1, 0 ], [ -4, 3, 2, 1, 1, 0 ], [ -3, 3, 2, 1, 1, 0 ] ], 1 ], + [ [ [ -4, 4, 2, 1, 1, 0 ], [ -4, 3, 1, 1, 1, 0 ], [ -4, 3, 2, 1, 1, 0 ], [ -3, 3, 2, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 4, 2, 1, 1, 0 ], [ -4, 3, 1, 1, 1, 0 ], [ -4, 3, 2, 1, 1, 0 ], [ -3, 3, 1, 1, 2, 0 ] ], 1 ], + [ [ [ -3, 3, 1, 1, 1, 0 ], [ -4, 3, 1, 1, 1, 0 ], [ -4, 3, 2, 1, 1, 0 ], [ -3, 3, 1, 1, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 3, 1, 1, 1, 0 ], [ -4, 3, 1, 1, 1, 0 ], [ -4, 3, 2, 1, 1, 0 ], [ -3, 4, 1, 1, 1, 0 ] ], 1 ], + [ [ [ -4, 4, 1, 1, 1, 0 ], [ -4, 3, 1, 1, 1, 0 ], [ -4, 3, 2, 1, 1, 0 ], [ -3, 4, 1, 1, 1, 0 ] ], 1 ], + [ [ [ -4, 4, 1, 1, 1, 0 ], [ -4, 3, 1, 1, 1, 0 ], [ -3, 3, 1, 1, 1, 0 ], [ -3, 4, 1, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 4, 1, 1, 1, 0 ], [ -4, 4, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 1, 0 ], [ -3, 4, 1, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 4, 1, 1, 1, 0 ], [ -4, 4, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 1, 0 ], [ -4, 5, 1, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 4, 1, 1, 1, 0 ], [ -4, 4, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 1, 0 ], [ -3, 4, 1, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 3, 1, 1, 0, 0 ], [ -4, 4, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 1, 0 ], [ -3, 4, 1, 1, 0, 0 ] ], 1 ], + [ [ [ -2, 3, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 1, 0 ], [ -3, 4, 1, 1, 0, 0 ] ], 1 ], + [ [ [ -2, 3, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 1, 0 ], [ -2, 3, 1, 1, 1, -1 ] ], 1 ] + ], + [ + [ [ [ -2, 3, 1, 1, 0, 0 ], [ -3, 3, 0, 1, 1, 0 ], [ -3, 3, 1, 1, 1, 0 ], [ -2, 3, 1, 1, 1, -1 ] ], 1 ] + ], + [ + [ [ [ -2, 3, 1, 1, 0, 0 ], [ -2, 3, 1, 1, 0, -1 ], [ -3, 3, 1, 1, 1, 0 ], [ -2, 3, 1, 1, 1, -1 ] ], 1 ], + [ [ [ -2, 3, 1, 1, 0, 0 ], [ -2, 3, 1, 1, 0, -1 ], [ -3, 4, 1, 1, 0, 0 ], [ -2, 3, 1, 1, 1, -1 ] ], 1 ] + ], + [ + [ [ [ -2, 3, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 1, 0 ], [ -3, 4, 1, 1, 0, 0 ], [ -2, 3, 1, 1, 1, -1 ] ], 1 ], + [ [ [ -2, 3, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 1, 0 ], [ -3, 4, 1, 1, 0, 0 ], [ -4, 4, 1, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 3, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 1, 0 ], [ -3, 4, 1, 1, 0, 0 ], [ -3, 3, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 3, 1, 1, 0, 0 ], [ -3, 3, 1, 1, 1, 0 ], [ -3, 4, 0, 1, 1, 0 ], [ -3, 3, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 3, 1, 1, 0, 0 ], [ -3, 4, 1, 1, 1, 0 ], [ -3, 4, 0, 1, 1, 0 ], [ -3, 3, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 3, 1, 1, 1, 0 ], [ -3, 4, 1, 1, 1, 0 ], [ -3, 4, 0, 1, 1, 0 ], [ -3, 3, 0, 1, 1, 0 ] ], 1 ], + [ [ [ -3, 3, 1, 1, 1, 0 ], [ -3, 4, 1, 1, 1, 0 ], [ -4, 4, 1, 1, 1, 0 ], [ -3, 3, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 4, 0, 1, 1, 0 ], [ -3, 4, 1, 1, 1, 0 ], [ -4, 4, 1, 1, 1, 0 ], [ -3, 3, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 4, 0, 1, 1, 0 ], [ -3, 4, 1, 1, 1, 0 ], [ -4, 4, 1, 1, 1, 0 ], [ -4, 4, 0, 1, 1, 0 ] ], 1 ], + [ [ [ -4, 4, 1, 2, 1, 0 ], [ -3, 4, 1, 1, 1, 0 ], [ -4, 4, 1, 1, 1, 0 ], [ -4, 4, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 5, 1, 1, 1, 0 ], [ -3, 4, 1, 1, 1, 0 ], [ -4, 4, 1, 1, 1, 0 ], [ -4, 4, 0, 1, 1, 0 ] ], 1 ], + [ [ [ -4, 5, 1, 1, 1, 0 ], [ -4, 5, 0, 1, 1, 0 ], [ -4, 4, 1, 1, 1, 0 ], [ -4, 4, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 4, 0, 1, 1, 0 ], [ -4, 5, 0, 1, 1, 0 ], [ -4, 4, 1, 1, 1, 0 ], [ -4, 4, 0, 1, 1, 0 ] ], 1 ], + [ [ [ -3, 4, 0, 1, 1, 0 ], [ -4, 5, 0, 1, 1, 0 ], [ -4, 4, 1, 1, 1, 0 ], [ -4, 5, 1, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 4, 0, 1, 1, 0 ], [ -4, 5, 0, 1, 1, 0 ], [ -4, 4, 1, 1, 1, 0 ], [ -3, 4, 1, 1, 1, 0 ] ], 1 ], + [ [ [ -3, 4, 0, 1, 1, 0 ], [ -4, 4, 0, 1, 1, 0 ], [ -4, 4, 1, 1, 1, 0 ], [ -3, 4, 1, 1, 1, 0 ] ], 1 ], + [ [ [ -3, 4, 0, 1, 1, 0 ], [ -4, 4, 0, 1, 1, 0 ], [ -3, 3, 0, 1, 1, 0 ], [ -3, 4, 1, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 4, 0, 1, 1, 0 ], [ -4, 4, 0, 1, 1, 0 ], [ -3, 3, 0, 1, 1, 0 ], [ -4, 5, 0, 1, 1, 0 ] ], 1 ], + [ [ [ -5, 4, 0, 1, 1, 0 ], [ -4, 4, 0, 1, 1, 0 ], [ -3, 3, 0, 1, 1, 0 ], [ -4, 5, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 4, 0, 1, 1, 0 ], [ -4, 4, 0, 1, 1, 0 ], [ -3, 3, 0, 1, 1, 0 ], [ -3, 4, 0, 1, 1, 0 ] ], 1 ], + [ [ [ -4, 3, 0, 1, 1, 0 ], [ -4, 4, 0, 1, 1, 0 ], [ -3, 3, 0, 1, 1, 0 ], [ -3, 4, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 3, 0, 1, 1, 0 ], [ -4, 4, 0, 1, 1, 0 ], [ -4, 5, 0, 1, 1, 0 ], [ -3, 4, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 3, 0, 1, 1, 0 ], [ -3, 3, -1, 1, 1, 0 ], [ -4, 5, 0, 1, 1, 0 ], [ -3, 4, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -6, 5, 0, 1, 1, 0 ], [ -3, 3, -1, 1, 1, 0 ], [ -4, 5, 0, 1, 1, 0 ], [ -3, 4, 0, 1, 1, 0 ] ], 1 ], + [ [ [ -6, 5, 0, 1, 1, 0 ], [ -3, 3, -1, 1, 1, 0 ], [ -4, 5, 0, 1, 1, 0 ], [ -4, 6, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -6, 5, 0, 1, 1, 0 ], [ -3, 3, -1, 1, 1, 0 ], [ -5, 6, -1, 1, 1, 0 ], [ -4, 6, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -6, 6, -1, 1, 1, 0 ], [ -3, 3, -1, 1, 1, 0 ], [ -5, 6, -1, 1, 1, 0 ], [ -4, 6, 0, 1, 1, 0 ] ], 1 ], + [ [ [ -6, 6, -1, 1, 1, 0 ], [ -3, 3, -1, 1, 1, 0 ], [ -5, 6, 0, 1, 1, 0 ], [ -4, 6, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -6, 6, -1, 1, 1, 0 ], [ -5, 6, -1, 1, 1, 0 ], [ -5, 6, 0, 1, 1, 0 ], [ -4, 6, 0, 1, 1, 0 ] ], 1 ], + [ [ [ -6, 6, 0, 1, 1, 0 ], [ -5, 6, -1, 1, 1, 0 ], [ -5, 6, 0, 1, 1, 0 ], [ -4, 6, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 0, 1, 1, 0 ], [ -5, 6, -1, 1, 1, 0 ], [ -5, 6, 0, 1, 1, 0 ], [ -4, 5, 0, 1, 1, 0 ] ], 1 ], + [ [ [ -6, 6, 0, 1, 1, 0 ], [ -5, 6, -1, 1, 1, 0 ], [ -4, 6, -1, 1, 1, 0 ], [ -4, 5, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 5, -1, 1, 1, 0 ], [ -5, 6, -1, 1, 1, 0 ], [ -4, 6, -1, 1, 1, 0 ], [ -4, 5, 0, 1, 1, 0 ] ], 1 ], + [ [ [ -5, 5, -1, 1, 1, 0 ], [ -4, 5, -1, 1, 1, 0 ], [ -4, 6, -1, 1, 1, 0 ], [ -4, 5, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 5, -1, 1, 1, 0 ], [ -4, 5, -1, 1, 1, 0 ], [ -3, 5, -2, 1, 1, 0 ], [ -4, 5, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 5, -1, 1, 1, 0 ], [ -4, 5, -1, 1, 1, 0 ], [ -3, 5, -2, 1, 1, 0 ], [ -3, 5, -1, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 5, -2, 1, 1, 0 ], [ -4, 5, -1, 1, 1, 0 ], [ -3, 5, -2, 1, 1, 0 ], [ -3, 5, -1, 1, 1, 0 ] ], 1 ], + [ [ [ -4, 5, -2, 1, 1, 0 ], [ -4, 5, -1, 1, 1, 0 ], [ -3, 5, -2, 1, 1, 0 ], [ -4, 6, -1, 1, 1, 0 ] ], 1 ], + [ [ [ -4, 5, -2, 1, 1, 0 ], [ -4, 5, -1, 1, 1, 0 ], [ -4, 5, -1, 2, 1, 0 ], [ -4, 6, -1, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 5, -2, 1, 1, 0 ], [ -4, 5, -1, 1, 1, 0 ], [ -4, 5, -1, 2, 1, 0 ], [ -3, 5, -2, 1, 1, 0 ] ], 1 ], + [ [ [ -4, 5, -2, 1, 1, 0 ], [ -4, 5, -1, 1, 1, 0 ], [ -3, 5, -1, 1, 1, 0 ], [ -3, 5, -2, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 5, -2, 1, 1, 0 ], [ -4, 5, -1, 1, 1, 0 ], [ -2, 4, -2, 1, 1, 0 ], [ -3, 5, -2, 1, 1, 0 ] ], 1 ], + [ [ [ -4, 5, -2, 1, 1, 0 ], [ -4, 5, -1, 1, 1, 0 ], [ -2, 4, -2, 1, 1, 0 ], [ -3, 4, -2, 1, 1, 0 ] ], 1 ], + [ [ [ -4, 5, -2, 1, 1, 0 ], [ -3, 5, -2, 1, 1, 0 ], [ -2, 4, -2, 1, 1, 0 ], [ -3, 4, -2, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 5, -2, 1, 1, 0 ], [ -2, 5, -2, 0, 1, 0 ], [ -2, 4, -2, 1, 1, 0 ], [ -3, 4, -2, 1, 1, 0 ] ], 1 ], + [ [ [ -4, 5, -2, 1, 1, 0 ], [ -2, 5, -2, 0, 1, 0 ], [ -2, 4, -2, 1, 1, 0 ], [ -4, 6, -2, 1, 1, 0 ] ], 1 ], + [ [ [ -4, 5, -2, 1, 1, 0 ], [ -2, 5, -2, 0, 1, 0 ], [ -3, 5, -2, 1, 1, 0 ], [ -4, 6, -2, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 5, -2, 1, 1, 0 ], [ -2, 5, -2, 0, 1, 0 ], [ -3, 5, -2, 1, 1, 0 ], [ -4, 6, -2, 1, 1, 0 ] ], 1 ], + [ [ [ -5, 5, -2, 1, 1, 0 ], [ -4, 5, -2, 1, 1, 0 ], [ -3, 5, -2, 1, 1, 0 ], [ -4, 6, -2, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 5, -2, 1, 1, 0 ], [ -4, 5, -2, 1, 1, 0 ], [ -4, 7, -2, 1, 1, 0 ], [ -4, 6, -2, 1, 1, 0 ] ], 1 ], + [ [ [ -5, 5, -2, 1, 1, 0 ], [ -5, 6, -2, 1, 1, 0 ], [ -4, 7, -2, 1, 1, 0 ], [ -4, 6, -2, 1, 1, 0 ] ], 1 ], + [ [ [ -6, 6, -2, 1, 1, 0 ], [ -5, 6, -2, 1, 1, 0 ], [ -4, 7, -2, 1, 1, 0 ], [ -4, 6, -2, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -6, 7, -2, 1, 1, 0 ], [ -5, 6, -2, 1, 1, 0 ], [ -4, 7, -2, 1, 1, 0 ], [ -4, 6, -2, 1, 1, 0 ] ], 1 ], + [ [ [ -6, 7, -2, 1, 1, 0 ], [ -5, 6, -2, 1, 1, 0 ], [ -5, 7, -2, 1, 1, 0 ], [ -4, 6, -2, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -6, 7, -2, 1, 1, 0 ], [ -5, 6, -2, 1, 1, 0 ], [ -5, 7, -2, 1, 1, 0 ], [ -4, 7, -2, 1, 1, 0 ] ], 1 ], + [ [ [ -6, 7, -2, 1, 1, 0 ], [ "Rest" ], [ -5, 7, -2, 1, 1, 0 ], [ -4, 7, -2, 1, 1, 0 ] ], 1 ], + [ [ [ -6, 7, -2, 1, 1, 0 ], [ "Rest" ], [ -5, 7, -2, 1, 1, 0 ], [ "Rest" ] ], 1 ], + [ [ [ -6, 7, -2, 1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -5, 5, -2, 1, 1, 0 ], [ -5, 6, -2, 1, 1, 0 ], [ -4, 7, -2, 1, 1, 0 ], [ -4, 6, -2, 1, 1, 0 ] ], + [ [ -6, 6, -2, 1, 1, 0 ], [ -5, 6, -2, 1, 1, 0 ], [ -4, 7, -2, 1, 1, 0 ], [ -4, 6, -2, 1, 1, 0 ] ], + [ [ -6, 7, -2, 1, 1, 0 ], [ -5, 6, -2, 1, 1, 0 ], [ -4, 7, -2, 1, 1, 0 ], [ -4, 6, -2, 1, 1, 0 ] ], + [ [ -6, 7, -2, 1, 1, 0 ], [ -5, 6, -2, 1, 1, 0 ], [ -5, 7, -2, 1, 1, 0 ], [ -4, 6, -2, 1, 1, 0 ] ], + [ [ -6, 7, -2, 1, 1, 0 ], [ -5, 6, -2, 1, 1, 0 ], [ -5, 7, -2, 1, 1, 0 ], [ -4, 7, -2, 1, 1, 0 ] ] +], +"cur_uid": "7e230015", +"ref_uid": "nil", +"order_seed": 389930, +"dur_seed": 736878, +"motifs_seed": 479673, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ -1200, 1200, 0.0020576131687243, 0.068181818181818, 0.074074074074074, 0.0625, 0.20576131687243, 0.0625, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.78600823045268, 0.068181818181818, 0.98971193415638, 0.0625 ], +"passages_weights": [ 1, 1, 0.48, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 0, 3 ], [ 2, 1 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 3, 1 ], [ 2, 0 ], [ ] ], + [ [ 2 ], [ 1, 3, 0 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 0, 3 ], [ 1, 2 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 2, 0 ], [ 3, 1 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0, 3 ], [ 2, 1 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 2, 0 ], [ 3, 1 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 0, 2 ], [ 1, 3 ], [ ] ], + [ [ 0, 2 ], [ 3, 1 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 3, 0 ], [ 1, 2 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 0, 3 ], [ 1, 2 ], [ ] ], + [ [ 2, 0 ], [ 1, 3 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 1, 2 ], [ 0, 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 2, 1 ], [ 0, 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 100, 100 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3/tmp/tmp_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3/tmp/tmp_mus_model.json new file mode 100644 index 0000000..487fc67 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3/tmp/tmp_mus_model.json @@ -0,0 +1,532 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 2.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 ] ], 1.625 ] + ], + [ + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 3.5 ] + ], + [ + [ [ [ 0, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 0, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 2.5 ] + ], + [ + [ [ [ 0, 0, 0, -1, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.375 ] + ], + [ + [ [ [ 0, 0, 0, -1, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, -1, 1, 0, 0, 0 ], [ 0, 0, 1, -1, 0, 0 ] ], 1.875 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ], [ 0, 0, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 1, -1, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ], [ 0, 0, 1, -1, 0, 0 ] ], 3.375 ] + ], + [ + [ [ [ 1, -1, 1, 0, 0, 0 ], [ 2, -1, 1, -1, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ], [ 0, 0, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 1, -1, 1, 0, 0, 0 ], [ 2, -1, 1, -1, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ], [ 1, -1, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 2, 0, 1, -1, 0, 0 ], [ 2, -1, 1, -1, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ], [ 1, -1, 1, -1, 0, 0 ] ], 1.5 ] + ], + [ + [ [ [ 2, 0, 1, -1, 0, 0 ], [ 2, -1, 1, -1, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ], [ 2, -1, 1, -2, 0, 0 ] ], 1 ], + [ [ [ 3, 0, 1, -2, 0, 0 ], [ 2, -1, 1, -1, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ], [ 2, -1, 1, -2, 0, 0 ] ], 1.75 ] + ], + [ + [ [ [ 3, 0, 1, -2, 0, 0 ], [ 1, 1, 1, -2, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ], [ 2, -1, 1, -2, 0, 0 ] ], 1 ], + [ [ [ 3, 0, 1, -2, 0, 0 ], [ 1, 1, 1, -2, 0, 0 ], [ 1, 0, 1, -2, 0, 0 ], [ 2, -1, 1, -2, 0, 0 ] ], 3.625 ] + ], + [ + [ [ [ 3, 0, 1, -2, 0, 0 ], [ 1, 1, 1, -2, 0, 0 ], [ 1, 0, 1, -2, 0, 0 ], [ 0, 1, 1, -2, 0, 0 ] ], 1.5 ] + ], + [ + [ [ [ 3, 0, 1, -2, 0, 0 ], [ 1, 1, 1, -2, 0, 0 ], [ 0, 2, 1, -2, 0, 0 ], [ 0, 1, 1, -2, 0, 0 ] ], 3 ] + ], + [ + [ [ [ 2, 1, 1, -2, 0, 0 ], [ 1, 1, 1, -2, 0, 0 ], [ 0, 2, 1, -2, 0, 0 ], [ 0, 1, 1, -2, 0, 0 ] ], 1 ], + [ [ [ 2, 1, 1, -2, 0, 0 ], [ 1, 1, 1, -2, 0, 0 ], [ 0, 2, 1, -2, 0, 0 ], [ -1, 3, 1, -2, 0, 0 ] ], 1 ], + [ [ [ 2, 1, 1, -2, 0, 0 ], [ 1, 2, 1, -2, 0, 0 ], [ 0, 2, 1, -2, 0, 0 ], [ -1, 3, 1, -2, 0, 0 ] ], 1.75 ] + ], + [ + [ [ [ 1, 3, 1, -2, 0, 0 ], [ 1, 2, 1, -2, 0, 0 ], [ 0, 2, 1, -2, 0, 0 ], [ -1, 3, 1, -2, 0, 0 ] ], 1 ], + [ [ [ 1, 3, 1, -2, 0, 0 ], [ 0, 3, 1, -2, 0, 0 ], [ 0, 2, 1, -2, 0, 0 ], [ -1, 3, 1, -2, 0, 0 ] ], 2.5 ] + ], + [ + [ [ [ 1, 3, 1, -2, 0, 0 ], [ 0, 3, 1, -2, 0, 0 ], [ 0, 2, 1, -2, 0, 0 ], [ 0, 2, 0, -2, 0, 0 ] ], 1.75 ] + ], + [ + [ [ [ 1, 3, 1, -2, 0, 0 ], [ 0, 3, 1, -2, 0, 0 ], [ 0, 2, 1, -2, 0, 0 ], [ 0, 1, 1, -2, 0, 0 ] ], 1.125 ] + ], + [ + [ [ [ 1, 3, 1, -2, 0, 0 ], [ 0, 3, 1, -2, 0, 0 ], [ -1, 1, 1, -1, 0, 0 ], [ 0, 1, 1, -2, 0, 0 ] ], 1 ], + [ [ [ 1, 3, 1, -2, 0, 0 ], [ 0, 2, 1, -2, 0, 0 ], [ -1, 1, 1, -1, 0, 0 ], [ 0, 1, 1, -2, 0, 0 ] ], 1 ], + [ [ [ 1, 2, 1, -2, 0, 0 ], [ 0, 2, 1, -2, 0, 0 ], [ -1, 1, 1, -1, 0, 0 ], [ 0, 1, 1, -2, 0, 0 ] ], 1.125 ] + ], + [ + [ [ [ 1, 1, 1, -2, 0, 1 ], [ 0, 2, 1, -2, 0, 0 ], [ -1, 1, 1, -1, 0, 0 ], [ 0, 1, 1, -2, 0, 0 ] ], 3.25 ] + ], + [ + [ [ [ 1, 1, 1, -2, 0, 1 ], [ 0, 1, 1, -2, 0, 1 ], [ -1, 1, 1, -1, 0, 0 ], [ 0, 1, 1, -2, 0, 0 ] ], 1.875 ] + ], + [ + [ [ [ 1, 1, 1, -2, 0, 1 ], [ 0, 1, 1, -2, 0, 1 ], [ -1, 1, 1, -1, 0, 0 ], [ -1, 1, 1, -1, 0, 1 ] ], 1 ], + [ [ [ 1, 1, 1, -1, 0, 0 ], [ 0, 1, 1, -2, 0, 1 ], [ -1, 1, 1, -1, 0, 0 ], [ -1, 1, 1, -1, 0, 1 ] ], 1 ], + [ [ [ 1, 1, 1, -1, 0, 0 ], [ 0, 1, 1, -1, 0, 0 ], [ -1, 1, 1, -1, 0, 0 ], [ -1, 1, 1, -1, 0, 1 ] ], 2.25 ] + ], + [ + [ [ [ 1, 1, 1, -1, 0, 0 ], [ 0, 1, 1, -1, 0, 0 ], [ -1, 1, 1, -1, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 2, 1, -1, 0, 0 ], [ 0, 1, 1, -1, 0, 0 ], [ -1, 1, 1, -1, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 2, 1, -1, 0, 0 ], [ 0, 1, 1, -1, 0, 0 ], [ -1, 2, 1, -1, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ] ], 2.625 ] + ], + [ + [ [ [ 0, 2, 1, -1, 0, 0 ], [ 0, 1, 1, -1, 0, 0 ], [ -1, 2, 1, -1, 0, 0 ], [ -1, 3, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 2, 1, -1, 0, 0 ], [ -2, 3, 1, -1, 0, 0 ], [ -1, 2, 1, -1, 0, 0 ], [ -1, 3, 1, -1, 0, 0 ] ], 2.75 ] + ], + [ + [ [ [ 0, 2, 1, -1, 0, 0 ], [ -2, 3, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ], [ -1, 3, 1, -1, 0, 0 ] ], 3.5 ] + ], + [ + [ [ [ 0, 2, 1, -1, 0, 0 ], [ -2, 3, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ], [ -1, 3, 0, -1, 0, 0 ] ], 1 ], + [ [ [ -1, 3, 1, -1, 0, 0 ], [ -2, 3, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ], [ -1, 3, 0, -1, 0, 0 ] ], 1 ], + [ [ [ -1, 3, 1, -1, 0, 0 ], [ -2, 3, 1, -1, 0, 0 ], [ -3, 3, 1, 0, 0, 0 ], [ -1, 3, 0, -1, 0, 0 ] ], 1.875 ] + ], + [ + [ [ [ -1, 3, 1, -1, 0, 0 ], [ -2, 3, 1, -1, 0, 0 ], [ -3, 3, 1, 0, 0, 0 ], [ -2, 3, 1, 0, 0, 0 ] ], 2.75 ] + ], + [ + [ [ [ -1, 3, 1, -1, 0, 0 ], [ -2, 3, 1, -1, 0, 0 ], [ -3, 3, 1, 0, 0, 0 ], [ -2, 3, 2, -1, 0, 0 ] ], 2.375 ] + ], + [ + [ [ [ -2, 3, 2, 0, 0, 0 ], [ -2, 3, 1, -1, 0, 0 ], [ -3, 3, 1, 0, 0, 0 ], [ -2, 3, 2, -1, 0, 0 ] ], 1 ], + [ [ [ -2, 3, 2, 0, 0, 0 ], [ -2, 3, 1, -1, 0, 0 ], [ -3, 3, 1, 0, 0, 0 ], [ -2, 3, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 3, 2, 0, 0, 0 ], [ -3, 3, 2, 0, 0, 0 ], [ -3, 3, 1, 0, 0, 0 ], [ -2, 3, 0, 0, 0, 0 ] ], 3.25 ] + ], + [ + [ [ [ -2, 3, 2, 0, 0, 0 ], [ -3, 3, 2, 0, 0, 0 ], [ -3, 3, 1, 0, 0, 0 ], [ -2, 3, 2, 0, -1, 0 ] ], 1 ], + [ [ [ -2, 3, 2, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -3, 3, 1, 0, 0, 0 ], [ -2, 3, 2, 0, -1, 0 ] ], 1 ], + [ [ [ -2, 3, 2, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -4, 3, 2, 1, 0, 0 ], [ -2, 3, 2, 0, -1, 0 ] ], 1.125 ] + ], + [ + [ [ [ -2, 3, 2, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -4, 3, 2, 1, 0, 0 ], [ -3, 2, 2, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 4, 1, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -4, 3, 2, 1, 0, 0 ], [ -3, 2, 2, 1, 0, 0 ] ], 1.25 ] + ], + [ + [ [ [ -3, 3, 2, 1, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -4, 3, 2, 1, 0, 0 ], [ -3, 2, 2, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 3, 2, 1, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -3, 3, 2, 0, 0, 0 ], [ -3, 2, 2, 1, 0, 0 ] ], 2.375 ] + ], + [ + [ [ [ -3, 4, 3, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -3, 3, 2, 0, 0, 0 ], [ -3, 2, 2, 1, 0, 0 ] ], 3 ] + ], + [ + [ [ [ -3, 4, 3, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -3, 4, 3, -1, 0, 0 ], [ -3, 2, 2, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 4, 3, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -3, 4, 3, -1, 0, 0 ], [ -3, 3, 3, 0, 0, 0 ] ], 1 ], + [ [ [ -3, 4, 3, 0, 0, 0 ], [ -2, 3, 3, 0, 0, 0 ], [ -3, 4, 3, -1, 0, 0 ], [ -3, 3, 3, 0, 0, 0 ] ], 2.75 ] + ], + [ + [ [ [ -3, 4, 3, 0, 0, 0 ], [ -2, 3, 3, 0, 0, 0 ], [ -4, 4, 3, 0, 0, 0 ], [ -3, 3, 3, 0, 0, 0 ] ], 1 ], + [ [ [ -3, 4, 3, 0, 0, 0 ], [ -3, 5, 3, 0, 0, 0 ], [ -4, 4, 3, 0, 0, 0 ], [ -3, 3, 3, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 4, 3, 0, 0, 0 ], [ -3, 5, 3, 0, 0, 0 ], [ -4, 4, 3, 0, 0, 0 ], [ -4, 5, 3, 0, 0, 0 ] ], 3.5 ] + ], + [ + [ [ [ -3, 4, 3, 0, 0, 0 ], [ -3, 5, 3, 0, 0, 0 ], [ -4, 4, 3, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -3, 4, 3, 0, 0, 0 ], [ -3, 5, 3, 0, 0, 0 ], [ -3, 3, 3, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -3, 4, 3, 0, 0, 0 ], [ -2, 4, 2, 0, 0, 0 ], [ -3, 3, 3, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ] ], 1.875 ] + ], + [ + [ [ [ -3, 4, 3, 0, 0, 0 ], [ -2, 3, 3, 0, 0, 0 ], [ -3, 3, 3, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 3, 2, 0, 0, 0 ], [ -2, 3, 3, 0, 0, 0 ], [ -3, 3, 3, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ] ], 2.5 ] + ], + [ + [ [ [ -2, 4, 3, 0, 0, 0 ], [ -2, 3, 3, 0, 0, 0 ], [ -3, 3, 3, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 4, 3, 0, 0, 0 ], [ -2, 3, 3, 0, 0, 0 ], [ -3, 4, 3, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ] ], 3.25 ] + ], + [ + [ [ [ -1, 3, 2, 0, 0, 0 ], [ -2, 3, 3, 0, 0, 0 ], [ -3, 4, 3, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 3, 2, 0, 0, 0 ], [ -3, 5, 3, 0, 0, 0 ], [ -3, 4, 3, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ] ], 2.625 ] + ], + [ + [ [ [ -1, 3, 2, 0, 0, 0 ], [ -2, 4, 2, 0, 0, 0 ], [ -3, 4, 3, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ] ], 1.125 ] + ], + [ + [ [ [ -1, 3, 2, 0, 0, 0 ], [ -2, 4, 2, 0, 0, 0 ], [ -3, 4, 3, 0, 0, 0 ], [ -3, 3, 2, 0, 0, 0 ] ], 1.625 ] + ], + [ + [ [ [ -1, 3, 2, 0, 0, 0 ], [ -2, 4, 2, 0, 0, 0 ], [ -2, 3, 2, 0, 0, 0 ], [ -3, 3, 2, 0, 0, 0 ] ], 2.75 ] + ], + [ + [ [ [ -1, 3, 2, 0, 0, 0 ], [ -2, 4, 2, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -3, 3, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 3, 2, 0, 0, 0 ], [ -2, 4, 2, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -4, 5, 2, 0, 0, 0 ] ], 2 ] + ], + [ + [ [ [ -2, 5, 2, 0, 0, 0 ], [ -2, 4, 2, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -4, 5, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 5, 2, 0, 0, 0 ], [ -3, 5, 2, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -4, 5, 2, 0, 0, 0 ] ], 3.25 ] + ], + [ + [ [ [ -2, 5, 2, 0, 0, 0 ], [ -3, 5, 2, 0, 0, 0 ], [ -4, 6, 2, 0, 0, 0 ], [ -4, 5, 2, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 5, 2, 0, 0, 0 ], [ -3, 5, 2, 0, 0, 0 ], [ -3, 5, 1, 0, 0, 0 ], [ -4, 5, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 5, 2, 0, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -3, 5, 1, 0, 0, 0 ], [ -4, 5, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 5, 2, -1, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -3, 5, 1, 0, 0, 0 ], [ -4, 5, 2, 0, 0, 0 ] ], 1.375 ] + ], + [ + [ [ [ -1, 5, 2, -1, 0, 0 ], [ -3, 4, 2, 0, 0, 0 ], [ -3, 5, 1, 0, 0, 0 ], [ -3, 5, 2, -1, 0, 0 ] ], 1 ], + [ [ [ -1, 5, 2, -1, 0, 0 ], [ -3, 5, 1, -1, 0, 0 ], [ -3, 5, 1, 0, 0, 0 ], [ -3, 5, 2, -1, 0, 0 ] ], 1.875 ] + ], + [ + [ [ [ -1, 5, 2, -1, 0, 0 ], [ -3, 5, 1, -1, 0, 0 ], [ -3, 5, 1, 0, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ] ], 2.875 ] + ], + [ + [ [ [ -1, 5, 2, -1, 0, 0 ], [ -3, 5, 1, -1, 0, 0 ], [ -2, 5, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ] ], 1 ], + [ [ [ -1, 5, 2, -1, 0, 0 ], [ -2, 4, 2, -1, 0, 0 ], [ -2, 5, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -2, 4, 2, -1, 0, 0 ], [ -2, 5, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ] ], 3.25 ] + ], + [ + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -1, 3, 1, -1, 0, 0 ], [ -2, 5, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -1, 3, 1, -1, 0, 0 ], [ -2, 5, 1, -1, 0, 0 ], [ -2, 3, 1, -1, 0, 0 ] ], 1.625 ] + ], + [ + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -1, 3, 1, -1, 0, 0 ], [ -2, 5, 1, -1, 0, 0 ], [ -3, 5, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ], [ -2, 5, 1, -1, 0, 0 ], [ -3, 5, 1, -1, 0, 0 ] ], 2.375 ] + ], + [ + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -3, 6, 1, -1, 0, 0 ], [ -2, 5, 1, -1, 0, 0 ], [ -3, 5, 1, -1, 0, 0 ] ], 2.375 ] + ], + [ + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -3, 6, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ], [ -3, 5, 1, -1, 0, 0 ] ], 3.125 ] + ], + [ + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -3, 6, 1, -1, 0, 0 ], [ -1, 3, 0, -1, 0, 0 ], [ -3, 5, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -1, 4, 1, -1, 0, 0 ], [ -1, 3, 0, -1, 0, 0 ], [ -3, 5, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -1, 4, 1, -1, 0, 0 ], [ -1, 3, 0, -1, 0, 0 ], [ -1, 3, 1, -1, 0, 0 ] ], 3.25 ] + ], + [ + [ [ [ 1, 2, 1, -1, 0, 0 ], [ -1, 4, 1, -1, 0, 0 ], [ -1, 3, 0, -1, 0, 0 ], [ -1, 3, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 1, 2, 1, -1, 0, 0 ], [ 0, 3, 0, -1, 0, 0 ], [ -1, 3, 0, -1, 0, 0 ], [ -1, 3, 1, -1, 0, 0 ] ], 1.75 ] + ], + [ + [ [ [ 0, 4, 1, -1, 0, 0 ], [ 0, 3, 0, -1, 0, 0 ], [ -1, 3, 0, -1, 0, 0 ], [ -1, 3, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 4, 1, -1, 0, 0 ], [ 0, 2, 1, -1, 0, 0 ], [ -1, 3, 0, -1, 0, 0 ], [ -1, 3, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 4, 1, -1, 0, 0 ], [ 0, 2, 1, -1, 0, 0 ], [ -1, 2, 1, -1, 0, 0 ], [ -1, 3, 1, -1, 0, 0 ] ], 1.75 ] + ], + [ + [ [ [ 0, 4, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ], [ -1, 2, 1, -1, 0, 0 ], [ -1, 3, 1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 4, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ], [ -2, 3, 1, -1, 0, 0 ], [ -1, 3, 1, -1, 0, 0 ] ], 2.375 ] + ], + [ + [ [ [ 0, 4, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ], [ -2, 3, 1, -1, 0, 0 ], [ 0, 3, 1, -2, 0, 0 ] ], 1 ], + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ], [ -2, 3, 1, -1, 0, 0 ], [ 0, 3, 1, -2, 0, 0 ] ], 1 ], + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -1, 3, 1, -1, 0, 0 ], [ -2, 3, 1, -1, 0, 0 ], [ 0, 3, 1, -2, 0, 0 ] ], 3.25 ] + ], + [ + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -1, 3, 1, -2, 0, 0 ], [ -2, 3, 1, -1, 0, 0 ], [ 0, 3, 1, -2, 0, 0 ] ], 1.375 ] + ], + [ + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -1, 3, 1, -1, 0, -1 ], [ -2, 3, 1, -1, 0, 0 ], [ 0, 3, 1, -2, 0, 0 ] ], 1 ], + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -1, 3, 1, -1, 0, -1 ], [ -2, 3, 1, -1, 0, 0 ], [ 0, 3, 1, -1, 0, -1 ] ], 1 ], + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -1, 3, 1, -1, 0, -1 ], [ -2, 4, 1, -1, 0, 0 ], [ 0, 3, 1, -1, 0, -1 ] ], 1.25 ] + ], + [ + [ [ [ 0, 3, 1, -1, 0, 0 ], [ -1, 2, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ], [ 0, 3, 1, -1, 0, -1 ] ], 2.75 ] + ], + [ + [ [ [ -1, 3, 1, 0, 0, -1 ], [ -1, 2, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ], [ 0, 3, 1, -1, 0, -1 ] ], 1 ], + [ [ [ -1, 3, 1, 0, 0, -1 ], [ -1, 3, 1, -1, 0, 0 ], [ -2, 4, 1, -1, 0, 0 ], [ 0, 3, 1, -1, 0, -1 ] ], 1 ], + [ [ [ -1, 3, 1, 0, 0, -1 ], [ -1, 3, 1, -1, 0, 0 ], [ -1, 3, 1, -1, 0, -1 ], [ 0, 3, 1, -1, 0, -1 ] ], 1.5 ] + ], + [ + [ [ [ -1, 3, 1, 0, 0, -1 ], [ -2, 3, 1, 0, 0, -1 ], [ -1, 3, 1, -1, 0, -1 ], [ 0, 3, 1, -1, 0, -1 ] ], 1.625 ] + ], + [ + [ [ [ 0, 4, 1, -1, 0, -1 ], [ -2, 3, 1, 0, 0, -1 ], [ -1, 3, 1, -1, 0, -1 ], [ 0, 3, 1, -1, 0, -1 ] ], 1 ], + [ [ [ 0, 4, 1, -1, 0, -1 ], [ -2, 3, 1, 0, 0, -1 ], [ -1, 3, 1, -1, 0, -1 ], [ -1, 4, 1, -1, 0, -1 ] ], 1 ], + [ [ [ 0, 4, 1, -1, 0, -1 ], [ -2, 4, 1, -1, 0, -1 ], [ -1, 3, 1, -1, 0, -1 ], [ -1, 4, 1, -1, 0, -1 ] ], 3 ] + ], + [ + [ [ [ 0, 4, 1, -1, 0, -1 ], [ -2, 4, 1, -1, 0, -1 ], [ -1, 3, 1, -1, 0, -1 ], [ -2, 4, 1, 0, 0, -1 ] ], 1 ], + [ [ [ 1, 3, 0, -1, 0, -1 ], [ -2, 4, 1, -1, 0, -1 ], [ -1, 3, 1, -1, 0, -1 ], [ -2, 4, 1, 0, 0, -1 ] ], 2.625 ] + ], + [ + [ [ [ 1, 3, 0, -1, 0, -1 ], [ -2, 4, 1, -1, 0, -1 ], [ -1, 3, 1, -1, 0, -1 ], [ -1, 4, 2, -1, 0, -1 ] ], 1 ], + [ [ [ 0, 3, 1, -1, 0, -1 ], [ -2, 4, 1, -1, 0, -1 ], [ -1, 3, 1, -1, 0, -1 ], [ -1, 4, 2, -1, 0, -1 ] ], 1 ], + [ [ [ 0, 3, 1, -1, 0, -1 ], [ -2, 4, 1, -1, 0, -1 ], [ -1, 4, 1, -1, 0, -1 ], [ -1, 4, 2, -1, 0, -1 ] ], 2.75 ] + ], + [ + [ [ [ 0, 3, 1, -1, 0, -1 ], [ -3, 4, 2, 0, 0, -1 ], [ -1, 4, 1, -1, 0, -1 ], [ -1, 4, 2, -1, 0, -1 ] ], 2.375 ] + ], + [ + [ [ [ 0, 3, 1, -1, 0, -1 ], [ -3, 4, 2, 0, 0, -1 ], [ -1, 4, 1, -1, 0, -1 ], [ -1, 4, 2, 0, 0, -2 ] ], 3.375 ] + ], + [ + [ [ [ 0, 3, 1, -1, 0, -1 ], [ -3, 4, 2, 0, 0, -1 ], [ -1, 4, 1, -1, 0, -1 ], [ -1, 3, 2, -1, 0, -1 ] ], 2.875 ] + ], + [ + [ [ [ -1, 5, 1, -1, 0, -1 ], [ -3, 4, 2, 0, 0, -1 ], [ -1, 4, 1, -1, 0, -1 ], [ -1, 3, 2, -1, 0, -1 ] ], 1 ], + [ [ [ -1, 5, 1, -1, 0, -1 ], [ -2, 4, 2, -1, 0, -1 ], [ -1, 4, 1, -1, 0, -1 ], [ -1, 3, 2, -1, 0, -1 ] ], 1 ], + [ [ [ -1, 5, 1, -1, 0, -1 ], [ -2, 4, 2, -1, 0, -1 ], [ -1, 4, 1, -1, 0, -1 ], [ -1, 3, 1, -1, 0, -1 ] ], 1.875 ] + ], + [ + [ [ [ -1, 5, 1, -1, 0, -1 ], [ -2, 4, 1, -1, 0, -1 ], [ -1, 4, 1, -1, 0, -1 ], [ -1, 3, 1, -1, 0, -1 ] ], 3.25 ] + ], + [ + [ [ [ -1, 5, 1, -1, 0, -1 ], [ -2, 5, 1, -1, -1, -1 ], [ -1, 4, 1, -1, 0, -1 ], [ -1, 3, 1, -1, 0, -1 ] ], 1 ], + [ [ [ -1, 5, 1, -1, 0, -1 ], [ -2, 5, 1, -1, -1, -1 ], [ -2, 5, 1, -1, 0, -1 ], [ -1, 3, 1, -1, 0, -1 ] ], 3.625 ] + ], + [ + [ [ [ -1, 5, 1, -1, 0, -1 ], [ -1, 4, 1, -1, 0, -1 ], [ -2, 5, 1, -1, 0, -1 ], [ -1, 3, 1, -1, 0, -1 ] ], 1 ], + [ [ [ -1, 5, 1, -1, 0, -1 ], [ -1, 4, 1, -1, 0, -1 ], [ -2, 5, 1, -1, 0, -1 ], [ -2, 4, 1, -1, 0, -1 ] ], 3.25 ] + ], + [ + [ [ [ -1, 5, 1, -1, 0, -1 ], [ -1, 4, 1, -1, 0, -1 ], [ -2, 5, 1, -1, 0, -1 ], [ -3, 6, 1, -1, 0, -1 ] ], 1.375 ] + ], + [ + [ [ [ -1, 5, 1, -1, 0, -1 ], [ -1, 4, 1, -1, 0, -1 ], [ -3, 7, 1, -1, 0, -1 ], [ -3, 6, 1, -1, 0, -1 ] ], 1.125 ] + ], + [ + [ [ [ -1, 5, 1, -1, 0, -1 ], [ -2, 6, 1, -1, 0, -1 ], [ -3, 7, 1, -1, 0, -1 ], [ -3, 6, 1, -1, 0, -1 ] ], 1.5 ] + ], + [ + [ [ [ -2, 7, 1, -1, 0, -1 ], [ -2, 6, 1, -1, 0, -1 ], [ -3, 7, 1, -1, 0, -1 ], [ -3, 6, 1, -1, 0, -1 ] ], 1 ], + [ [ [ -2, 7, 1, -1, 0, -1 ], [ -2, 6, 1, -1, 0, -1 ], [ -2, 6, 0, -1, 0, -1 ], [ -3, 6, 1, -1, 0, -1 ] ], 2.375 ] + ], + [ + [ [ [ -1, 6, 0, -1, 0, -1 ], [ -2, 6, 1, -1, 0, -1 ], [ -2, 6, 0, -1, 0, -1 ], [ -3, 6, 1, -1, 0, -1 ] ], 3.625 ] + ], + [ + [ [ [ -1, 6, 0, -1, 0, -1 ], [ -2, 6, 1, -1, 0, -1 ], [ -2, 6, 0, -1, 0, -1 ], [ -2, 5, 0, -1, 0, -1 ] ], 1 ], + [ [ [ -4, 6, 1, 0, 0, -1 ], [ -2, 6, 1, -1, 0, -1 ], [ -2, 6, 0, -1, 0, -1 ], [ -2, 5, 0, -1, 0, -1 ] ], 2.125 ] + ], + [ + [ [ [ -3, 6, 1, -1, 0, -1 ], [ -2, 6, 1, -1, 0, -1 ], [ -2, 6, 0, -1, 0, -1 ], [ -2, 5, 0, -1, 0, -1 ] ], 1 ], + [ [ [ -3, 6, 1, -1, 0, -1 ], [ -1, 5, 0, -1, 0, -1 ], [ -2, 6, 0, -1, 0, -1 ], [ -2, 5, 0, -1, 0, -1 ] ], 3.375 ] + ], + [ + [ [ [ -3, 6, 0, -1, 0, -1 ], [ -1, 5, 0, -1, 0, -1 ], [ -2, 6, 0, -1, 0, -1 ], [ -2, 5, 0, -1, 0, -1 ] ], 1 ], + [ [ [ -3, 6, 0, -1, 0, -1 ], [ -1, 5, 0, -1, 0, -1 ], [ -2, 6, 0, -1, 0, -1 ], [ -3, 7, 0, -1, 0, -1 ] ], 1.625 ] + ], + [ + [ [ [ -3, 6, 0, -1, 0, -1 ], [ -1, 5, 0, -1, 0, -1 ], [ -2, 6, 0, -1, 0, -1 ], [ -2, 6, -1, -1, 0, -1 ] ], 1 ], + [ [ [ -3, 6, 0, -1, 0, -1 ], [ -2, 7, 0, -1, 0, -1 ], [ -2, 6, 0, -1, 0, -1 ], [ -2, 6, -1, -1, 0, -1 ] ], 1 ], + [ [ [ -3, 6, 0, -1, 0, -1 ], [ -2, 7, 0, -1, 0, -1 ], [ -2, 6, 0, -1, 1, -1 ], [ -2, 6, -1, -1, 0, -1 ] ], 1.75 ] + ], + [ + [ [ [ -3, 6, 0, -1, 0, -1 ], [ -2, 7, 0, -1, 0, -1 ], [ -2, 6, 0, -1, 1, -1 ], [ -2, 6, 0, -1, 0, -1 ] ], 1 ], + [ [ [ -3, 7, 0, -1, 0, -1 ], [ -2, 7, 0, -1, 0, -1 ], [ -2, 6, 0, -1, 1, -1 ], [ -2, 6, 0, -1, 0, -1 ] ], 2.625 ] + ], + [ + [ [ [ -3, 7, 0, -1, 0, -1 ], [ -2, 7, 0, -1, 0, -1 ], [ -2, 6, 0, -1, 1, -1 ], [ -3, 6, 0, -1, 1, -1 ] ], 1 ], + [ [ [ -2, 6, 0, -1, 1, -2 ], [ -2, 7, 0, -1, 0, -1 ], [ -2, 6, 0, -1, 1, -1 ], [ -3, 6, 0, -1, 1, -1 ] ], 2.25 ] + ], + [ + [ [ [ -2, 6, 0, -1, 1, -2 ], [ -2, 7, 0, -1, 0, -1 ], [ -3, 7, 0, -1, 1, -1 ], [ -3, 6, 0, -1, 1, -1 ] ], 2.125 ] + ], + [ + [ [ [ -2, 6, 0, -1, 1, -2 ], [ -2, 7, -1, -1, 1, -1 ], [ -3, 7, 0, -1, 1, -1 ], [ -3, 6, 0, -1, 1, -1 ] ], 1.375 ] + ], + [ + [ [ [ -3, 6, -1, -1, 1, -1 ], [ -2, 7, -1, -1, 1, -1 ], [ -3, 7, 0, -1, 1, -1 ], [ -3, 6, 0, -1, 1, -1 ] ], 1 ], + [ [ [ -3, 6, -1, -1, 1, -1 ], [ -2, 7, -1, -1, 1, -1 ], [ -3, 7, 0, -1, 1, -1 ], [ -3, 7, -1, -1, 1, -1 ] ], 1.5 ] + ], + [ + [ [ [ -3, 6, -1, -1, 1, -1 ], [ -2, 7, -1, -1, 1, -1 ], [ -2, 6, -1, -1, 1, -1 ], [ -3, 7, -1, -1, 1, -1 ] ], 3.125 ] + ], + [ + [ [ [ -1, 7, -1, -1, 1, -1 ], [ -2, 7, -1, -1, 1, -1 ], [ -2, 6, -1, -1, 1, -1 ], [ -3, 7, -1, -1, 1, -1 ] ], 1 ], + [ [ [ -1, 7, -1, -1, 1, -1 ], [ -2, 7, -1, -1, 1, -1 ], [ -3, 8, -1, -1, 1, -1 ], [ -3, 7, -1, -1, 1, -1 ] ], 2.625 ] + ], + [ + [ [ [ -1, 7, -1, -1, 1, -1 ], [ -2, 7, -1, -2, 1, -1 ], [ -3, 8, -1, -1, 1, -1 ], [ -3, 7, -1, -1, 1, -1 ] ], 1 ], + [ [ [ -2, 9, -1, -1, 1, -1 ], [ -2, 7, -1, -2, 1, -1 ], [ -3, 8, -1, -1, 1, -1 ], [ -3, 7, -1, -1, 1, -1 ] ], 2.625 ] + ], + [ + [ [ [ -2, 9, -1, -1, 1, -1 ], [ -2, 7, -1, -2, 1, -1 ], [ -3, 8, -1, -1, 1, -1 ], [ -4, 9, -1, -1, 1, -1 ] ], 1 ], + [ [ [ -2, 9, -1, -1, 1, -1 ], [ -2, 7, -1, -2, 1, -1 ], [ -4, 10, -1, -1, 1, -1 ], [ -4, 9, -1, -1, 1, -1 ] ], 3.5 ] + ], + [ + [ [ [ -2, 9, -1, -2, 1, -1 ], [ -2, 7, -1, -2, 1, -1 ], [ -4, 10, -1, -1, 1, -1 ], [ -4, 9, -1, -1, 1, -1 ] ], 1 ], + [ [ [ -2, 9, -1, -2, 1, -1 ], [ -4, 8, -1, -1, 1, -1 ], [ -4, 10, -1, -1, 1, -1 ], [ -4, 9, -1, -1, 1, -1 ] ], 3.125 ] + ], + [ + [ [ [ -2, 9, -1, -2, 1, -1 ], [ -4, 8, -1, -1, 1, -1 ], [ -3, 9, -2, -1, 1, -1 ], [ -4, 9, -1, -1, 1, -1 ] ], 1.25 ] + ], + [ + [ [ [ -2, 9, -1, -2, 1, -1 ], [ -4, 8, -1, -1, 1, -1 ], [ -3, 9, -2, -1, 1, -1 ], [ -3, 9, -1, -2, 1, -1 ] ], 3.125 ] + ], + [ + [ [ [ -2, 8, -1, -2, 1, -1 ], [ -4, 8, -1, -1, 1, -1 ], [ -3, 9, -2, -1, 1, -1 ], [ -3, 9, -1, -2, 1, -1 ] ], 1 ], + [ [ [ -2, 8, -1, -2, 1, -1 ], [ -4, 8, -1, -1, 1, -1 ], [ -3, 9, -2, -1, 1, -1 ], [ -3, 8, -1, -2, 1, -1 ] ], 1 ], + [ [ [ -2, 8, -1, -2, 1, -1 ], [ -4, 8, -1, -1, 1, -1 ], [ -3, 8, -1, -1, 1, -1 ], [ -3, 8, -1, -2, 1, -1 ] ], 2.375 ] + ], + [ + [ [ [ -2, 8, -1, -2, 1, -1 ], [ -4, 8, -1, -1, 1, -1 ], [ -3, 8, -1, -1, 1, -1 ], [ -4, 8, 0, -1, 1, -1 ] ], 1 ], + [ [ [ -2, 8, -1, -2, 1, -1 ], [ -4, 8, -1, -1, 1, -1 ], [ -2, 8, -1, -2, 0, -1 ], [ -4, 8, 0, -1, 1, -1 ] ], 2.875 ] + ], + [ + [ [ [ -2, 8, -1, -2, 1, -1 ], [ -4, 8, -1, -1, 1, -1 ], [ -3, 8, -1, -2, 1, 0 ], [ -4, 8, 0, -1, 1, -1 ] ], 1 ], + [ [ [ -2, 8, -1, -2, 1, -1 ], [ -4, 8, -1, -1, 1, -1 ], [ -3, 8, -1, -2, 1, 0 ], [ -3, 8, 0, -2, 1, -1 ] ], 1 ], + [ [ [ -2, 8, -1, -2, 1, -1 ], [ -3, 8, -1, -2, 1, -1 ], [ -3, 8, -1, -2, 1, 0 ], [ -3, 8, 0, -2, 1, -1 ] ], 1.625 ] + ], + [ + [ [ [ -2, 8, -1, -2, 1, -1 ], [ -4, 8, -1, -2, 1, 0 ], [ -3, 8, -1, -2, 1, 0 ], [ -3, 8, 0, -2, 1, -1 ] ], 1 ], + [ [ [ -2, 8, -1, -2, 1, -1 ], [ -4, 8, -1, -2, 1, 0 ], [ -3, 8, -1, -2, 1, 0 ], [ -3, 8, -1, -2, 0, -1 ] ], 1 ], + [ [ [ -2, 8, -1, -2, 1, -1 ], [ -4, 8, -1, -2, 1, 0 ], [ -3, 8, -1, -2, 1, -1 ], [ -3, 8, -1, -2, 0, -1 ] ], 1.875 ] + ], + [ + [ [ [ -2, 7, -1, -2, 1, -1 ], [ -4, 8, -1, -2, 1, 0 ], [ -3, 8, -1, -2, 1, -1 ], [ -3, 8, -1, -2, 0, -1 ] ], 1 ], + [ [ [ -2, 7, -1, -2, 1, -1 ], [ -4, 8, -1, -1, 1, -1 ], [ -3, 8, -1, -2, 1, -1 ], [ -3, 8, -1, -2, 0, -1 ] ], 2.125 ] + ], + [ + [ [ [ -2, 7, -1, -2, 1, -1 ], [ -4, 8, -1, -1, 1, -1 ], [ -2, 8, 0, -2, 0, -1 ], [ -3, 8, -1, -2, 0, -1 ] ], 1 ], + [ [ [ -2, 7, -1, -2, 1, -1 ], [ -3, 8, -1, -2, 1, -1 ], [ -2, 8, 0, -2, 0, -1 ], [ -3, 8, -1, -2, 0, -1 ] ], 1 ], + [ [ [ -2, 8, -1, -2, 0, -1 ], [ -3, 8, -1, -2, 1, -1 ], [ -2, 8, 0, -2, 0, -1 ], [ -3, 8, -1, -2, 0, -1 ] ], 1.75 ] + ], + [ + [ [ [ -3, 8, -1, -2, 1, 0 ], [ -3, 8, -1, -2, 1, -1 ], [ -2, 8, 0, -2, 0, -1 ], [ -3, 8, -1, -2, 0, -1 ] ], 1 ], + [ [ [ -3, 8, -1, -2, 1, 0 ], [ -3, 8, -1, -2, 1, -1 ], [ -2, 8, -1, -2, 1, -1 ], [ -3, 8, -1, -2, 0, -1 ] ], 3.375 ] + ], + [ + [ [ [ -3, 8, -1, -2, 1, 0 ], [ -3, 8, -1, -2, 1, -1 ], [ -2, 8, -1, -2, 1, -1 ], [ -3, 8, -2, -2, 1, -1 ] ], 2.125 ], + [ [ [ -3, 8, -1, -2, 1, 0 ], [ "Rest" ], [ -2, 8, -1, -2, 1, -1 ], [ -3, 8, -2, -2, 1, -1 ] ], 1 ], + [ [ [ -3, 8, -1, -2, 1, 0 ], [ "Rest" ], [ -2, 8, -1, -2, 1, -1 ], [ "Rest" ] ], 1 ], + [ [ [ -3, 8, -1, -2, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.25 ] + ] + ] +], +"last_changes": +[ + [ [ -2, 7, -1, -2, 1, -1 ], [ -3, 8, -1, -2, 1, -1 ], [ -2, 8, 0, -2, 0, -1 ], [ -3, 8, -1, -2, 0, -1 ] ], + [ [ -2, 8, -1, -2, 0, -1 ], [ -3, 8, -1, -2, 1, -1 ], [ -2, 8, 0, -2, 0, -1 ], [ -3, 8, -1, -2, 0, -1 ] ], + [ [ -3, 8, -1, -2, 1, 0 ], [ -3, 8, -1, -2, 1, -1 ], [ -2, 8, 0, -2, 0, -1 ], [ -3, 8, -1, -2, 0, -1 ] ], + [ [ -3, 8, -1, -2, 1, 0 ], [ -3, 8, -1, -2, 1, -1 ], [ -2, 8, -1, -2, 1, -1 ], [ -3, 8, -1, -2, 0, -1 ] ], + [ [ -3, 8, -1, -2, 1, 0 ], [ -3, 8, -1, -2, 1, -1 ], [ -2, 8, -1, -2, 1, -1 ], [ -3, 8, -2, -2, 1, -1 ] ] +], +"cur_uid": "tmp", +"ref_uid": "nil", +"order_seed": 389930, +"dur_seed": 362766, +"motifs_seed": 479673, +"entrances_probs_vals": [ 0, 0, 2.9365079365079, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 2.7380952380952, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 2.7380952380952, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ -1200, 1200, 0.0020576131687243, 0.068181818181818, 0.074074074074074, 0.0625, 0.20576131687243, 0.0625, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.78600823045268, 0.068181818181818, 0.98971193415638, 0.0625 ], +"passages_weights": [ 1, 1, 0.48, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 0, 3 ], [ 2, 1 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 3, 1 ], [ 2, 0 ], [ ] ], + [ [ 2 ], [ 1, 3, 0 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 0, 3 ], [ 1, 2 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 2, 0 ], [ 3, 1 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0, 3 ], [ 2, 1 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 2, 0 ], [ 3, 1 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 0, 2 ], [ 1, 3 ], [ ] ], + [ [ 0, 2 ], [ 3, 1 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 3, 0 ], [ 1, 2 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 0, 3 ], [ 1, 2 ], [ ] ], + [ [ 2, 0 ], [ 1, 3 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 1, 2 ], [ 0, 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 2, 1 ], [ 0, 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 100, 100 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise.json new file mode 100644 index 0000000..f1e7021 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise.json @@ -0,0 +1,21 @@ +{ +"ledger": +[ + "4874dd07", + "44490863", + "4bf1af12", + "6522664c", + "7ede7adb", + "521654f8", + "6db2efcc", + "4b40ed47", + "4e9f1dcc", + "78a94ed1", + "531df78c", + "7276dc78", + "43214be8", + "7c30c182", + "4ef018fc", + "615c4008" +] +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise.json_bak b/resources/resources_bak_2024_01_03/string_quartet_3_rise.json_bak new file mode 100644 index 0000000..3b179c3 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise.json_bak @@ -0,0 +1,20 @@ +{ +"ledger": +[ + "4874dd07", + "44490863", + "4bf1af12", + "6522664c", + "7ede7adb", + "521654f8", + "6db2efcc", + "4b40ed47", + "4e9f1dcc", + "78a94ed1", + "531df78c", + "7276dc78", + "43214be8", + "7c30c182", + "4ef018fc" +] +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/43214be8_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/43214be8_code.scd new file mode 100644 index 0000000..42b64ff --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/43214be8_code.scd @@ -0,0 +1,981 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/43214be8_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/43214be8_mus_model.json new file mode 100644 index 0000000..ec6964f --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/43214be8_mus_model.json @@ -0,0 +1,158 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -7, 6, 4, -1, 1, 2 ], [ -5, 5, 4, 0, 0, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -6, 6, 4, 0, 1, 2 ] ], 1 ], + [ [ [ -6, 6, 4, -1, 0, 2 ], [ -5, 5, 4, 0, 0, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -6, 6, 4, 0, 1, 2 ] ], 1 ], + [ [ [ -6, 6, 4, -1, 0, 2 ], [ -5, 5, 4, 0, 0, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -7, 6, 5, 0, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 4, -1, 0, 2 ], [ -5, 6, 3, 0, 0, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -7, 6, 5, 0, 0, 2 ] ], 1 ], + [ [ [ -6, 6, 4, -1, 0, 2 ], [ -5, 6, 3, 0, 0, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -7, 6, 4, 1, 0, 2 ] ], 1 ], + [ [ [ -6, 6, 3, 0, 0, 2 ], [ -5, 6, 3, 0, 0, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -7, 6, 4, 1, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 3, 0, 0, 2 ], [ -5, 6, 3, 0, 0, 2 ], [ -5, 6, 2, 0, 0, 2 ], [ -7, 6, 4, 1, 0, 2 ] ], 1 ], + [ [ [ -6, 6, 3, 0, 0, 2 ], [ -5, 6, 3, 0, 0, 2 ], [ -5, 6, 2, 0, 0, 2 ], [ -6, 7, 3, 0, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 3, 0, 0, 2 ], [ -5, 6, 2, -1, 0, 2 ], [ -5, 6, 2, 0, 0, 2 ], [ -6, 7, 3, 0, 0, 2 ] ], 1 ], + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -5, 6, 2, -1, 0, 2 ], [ -5, 6, 2, 0, 0, 2 ], [ -6, 7, 3, 0, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -5, 6, 2, -1, 0, 2 ], [ -6, 7, 2, 1, 0, 2 ], [ -6, 7, 3, 0, 0, 2 ] ], 1 ], + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -6, 7, 2, 1, 0, 2 ], [ -6, 7, 3, 0, 0, 2 ] ], 1 ], + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -6, 7, 2, 1, 0, 2 ], [ -5, 6, 2, 1, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -5, 6, 2, 1, -1, 1 ], [ -5, 6, 2, 1, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -6, 6, 2, 2, -1, 2 ], [ -5, 6, 2, 1, -1, 2 ] ], 1 ], + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -6, 6, 2, 2, -1, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -7, 5, 2, 3, 0, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ], + [ [ [ -8, 6, 2, 2, 0, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -7, 5, 2, 3, 0, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ], + [ [ [ -8, 6, 2, 2, 0, 2 ], [ -7, 5, 2, 2, -1, 2 ], [ -7, 5, 2, 3, 0, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 2, 2, -1, 2 ], [ -7, 5, 2, 2, -1, 2 ], [ -7, 5, 2, 3, 0, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 2, 2, -1, 2 ], [ -7, 5, 2, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ], + [ [ [ -7, 6, 2, 2, -1, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 2, 2, -1, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 2, 2, -1, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 2, 2, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 2, 2, -1, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 6, 2, 2, -1, 2 ] ], 1 ], + [ [ [ -6, 5, 1, 2, 0, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 6, 2, 2, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 5, 1, 2, 0, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -5, 5, 0, 2, 0, 2 ], [ -6, 6, 2, 2, -1, 2 ] ], 1 ], + [ [ [ -6, 5, 1, 2, 0, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -5, 5, 0, 2, 0, 2 ], [ -6, 6, 1, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 5, 1, 2, 0, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -6, 6, 1, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 5, 1, 3, -1, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -6, 6, 1, 2, 0, 2 ] ], 1 ], + [ [ [ -6, 5, 1, 3, -1, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 5, 1, 2, -2, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 5, 1, 2, -2, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ], + [ [ [ -7, 5, 1, 2, -2, 2 ], [ -7, 5, 1, 3, -2, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ], + [ [ [ -7, 5, 1, 2, -1, 2 ], [ -7, 5, 1, 3, -2, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 5, 1, 2, -1, 2 ], [ -7, 5, 1, 3, -2, 2 ], [ -5, 5, 1, 1, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ], + [ [ [ -6, 5, 1, 2, -2, 2 ], [ -7, 5, 1, 3, -2, 2 ], [ -5, 5, 1, 1, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ], + [ [ [ -6, 5, 1, 2, -2, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -5, 5, 1, 1, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 5, 0, 3, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -5, 5, 1, 1, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ], + [ [ [ -8, 5, 0, 3, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 1, 2, -2, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 1, 2, -2, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 4, 1, 3, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ] ], 1 ], + [ [ [ -8, 4, 1, 3, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 1 ], + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -2, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -9, 8, 0, 5, -2, 2 ], [ -8, 7, 0, 5, -2, 2 ], [ -9, 7, 1, 5, -2, 2 ], [ -8, 7, 1, 5, -2, 2 ] ], + [ [ -9, 8, 0, 5, -2, 2 ], [ -8, 7, 0, 5, -2, 2 ], [ -9, 7, 1, 5, -2, 2 ], [ -9, 7, 0, 6, -2, 2 ] ], + [ [ -9, 8, 0, 5, -2, 2 ], [ -8, 7, 0, 5, -2, 2 ], [ -9, 7, 0, 5, -2, 2 ], [ -9, 7, 0, 6, -2, 2 ] ], + [ [ -9, 8, 0, 5, -2, 2 ], [ -8, 7, 0, 5, -2, 2 ], [ -9, 7, 0, 5, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ] ], + [ [ -8, 7, -1, 5, -2, 2 ], [ -8, 7, 0, 5, -2, 2 ], [ -9, 7, 0, 5, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ] ] +], +"cur_uid": "43214be8", +"ref_uid": "7276dc78", +"order_seed": 553436, +"dur_seed": 804010, +"motifs_seed": 337121, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0061728395061728, 0.10227272727273, 0.074074074074074, 0.10227272727273, 0.2037037037037, 0.090909090909091, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 0.08, 0.47, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 0, 3, 1 ], [ 2 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 3 ], [ 0, 2, 1 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 25, 25.244897959184 ], +"passages_size": [ 0, 0 ], +"motif_edited": "true", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/lilypond/part_I.ly new file mode 100644 index 0000000..e9eae1a --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/lilypond/part_I.ly @@ -0,0 +1,48 @@ +{ + { gis'1^\markup { \pad-markup #0.2 "-11"} } + \bar "|" + { fis1^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} } + \bar "|" + { c'1^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + \bar "|" + { c'2 fis'2^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + \bar "|" + { b'2 g2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g2 cis'2^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a'2 ais'2^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 } + \bar "|" + { ais1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais2 d'2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { d'2 g'2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g'2 b'2^\markup { \pad-markup #0.2 "+50"}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/lilypond/part_II.ly new file mode 100644 index 0000000..bd2901a --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/lilypond/part_II.ly @@ -0,0 +1,48 @@ +{ + { d'1^\markup { \pad-markup #0.2 "+38"} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 } + \bar "|" + { g'1^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { g'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { b'2 d'2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }} } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} } + \bar "|" + { f'1^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } + \bar "|" + { f'1 } + \bar "|" + { f'1^\markup { \pad-markup #0.2 "-35"} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} } + \bar "|" + { d'1^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} } + \bar "|" + { g1^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g2 c'2^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'2 f'2^\markup { \pad-markup #0.2 "-35"} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/lilypond/part_III.ly new file mode 100644 index 0000000..192a5db --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/lilypond/part_III.ly @@ -0,0 +1,48 @@ +{ + { g'1^\markup { \pad-markup #0.2 "+36"} ~ } + \bar "|" + { g'2 b'2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 } + \bar "|" + { a1^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } + \bar "|" + { a2 d'2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 } + \bar "|" + { cis1^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }} ~ } + \bar "|" + { cis2 dis'2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} } + \bar "|" + { ais'1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'2 d2^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d2 g2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/lilypond/part_IV.ly new file mode 100644 index 0000000..534e787 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/43214be8/lilypond/part_IV.ly @@ -0,0 +1,48 @@ +{ + { ais,2^\markup { \pad-markup #0.2 "+21"} f2^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f2 b2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b2 e'2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2 d2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { d2 a2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a2 dis'2^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'2 g'2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + \bar "|" + { g'2 e,2^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } + \bar "|" + { e,1 } + \bar "|" + { ais,1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} } + \bar "|" + { e1^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} } + \bar "|" + { dis,1^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} } + \bar "|" + { b,1^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} } + \bar "|" + { c,1^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} } + \bar "|" + { f,1^\markup { \pad-markup #0.2 "+1"}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/44490863_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/44490863_code.scd new file mode 100644 index 0000000..23ccdf1 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/44490863_code.scd @@ -0,0 +1,981 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/44490863_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/44490863_mus_model.json new file mode 100644 index 0000000..b1d0e34 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/44490863_mus_model.json @@ -0,0 +1,154 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -1, 2, 0, 0, 1, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 1, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 1, 1, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 1, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 2, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 1, 0, 1, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 0, 0, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 2, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 0, 0, 2, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 1, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 1, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ -2, 2, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -2, 3, 1, 0, 0, 0 ], [ -2, 2, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 2, 0, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -2, 3, 1, 0, 0, 0 ], [ -2, 2, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 2, 0, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -2, 3, 1, 0, 0, 0 ], [ -2, 2, 2, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 0, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ -2, 2, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 2, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ -2, 2, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 2, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ -2, 3, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 4, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ -2, 3, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -3, 4, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -2, 3, 2, 0, 0, 0 ], [ -2, 3, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 4, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -2, 3, 2, 0, 0, 0 ], [ -2, 4, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 2, 2, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -2, 3, 2, 0, 0, 0 ], [ -2, 4, 2, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 2, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 1, 0 ], [ -2, 4, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 3, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 1, 0 ], [ -2, 4, 2, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 3, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 1, 0 ], [ -2, 2, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 3, 1, 0, 0, 0 ], [ -2, 3, 1, 0, 1, 0 ], [ -1, 2, 1, 0, 1, 0 ], [ -2, 2, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 3, 1, 0, 0, 0 ], [ -2, 3, 1, 0, 1, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -2, 2, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 3, 2, 0, 1, 0 ], [ -2, 3, 1, 0, 1, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -2, 2, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 3, 2, 0, 1, 0 ], [ -2, 3, 1, 0, 1, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -2, 3, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 3, 2, 0, 1, 0 ], [ -2, 3, 1, 0, 1, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 1, 0 ] ], 1 ], + [ [ [ -2, 2, 1, 0, 1, 0 ], [ -2, 3, 1, 0, 1, 0 ], [ -1, 2, 1, 0, 0, 0 ], [ -1, 2, 1, 0, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 1, 0, 1, 0 ], [ -2, 3, 1, 0, 1, 0 ], [ -1, 2, 0, 0, 1, 0 ], [ -1, 2, 1, 0, 1, 0 ] ], 1 ], + [ [ [ -2, 2, 1, 0, 1, 0 ], [ -2, 2, 1, 1, 1, 0 ], [ -1, 2, 0, 0, 1, 0 ], [ -1, 2, 1, 0, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 1, 0, 1, 0 ], [ -2, 2, 1, 1, 1, 0 ], [ -1, 2, 0, 0, 1, 0 ], [ -3, 2, 1, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 1, 0, 1, 0 ], [ -1, 2, 1, 0, 1, 0 ], [ -1, 2, 0, 0, 1, 0 ], [ -3, 2, 1, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 1, 0, 1, 0 ], [ -1, 2, 1, 0, 1, 0 ], [ -2, 2, 1, 1, 1, 0 ], [ -3, 2, 1, 1, 1, 0 ] ], 1 ], + [ [ [ -2, 1, 1, 1, 1, 0 ], [ -1, 2, 1, 0, 1, 0 ], [ -2, 2, 1, 1, 1, 0 ], [ -3, 2, 1, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 1, 1, 1, 0 ], [ -1, 2, 1, 0, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 2, 1, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 1, 1, 1, 0 ], [ -1, 2, 1, 0, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -2, 1, 1, 1, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 1, 1, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -2, 0, 2, 2, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 1, 2, 2, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -2, 1, 1, 1, 1, 0 ], [ -1, 2, 1, 0, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], + [ [ -2, 1, 1, 1, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], + [ [ -2, 1, 1, 1, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], + [ [ -2, 0, 2, 2, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], + [ [ -5, 1, 2, 2, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ] +], +"cur_uid": "44490863", +"ref_uid": "4874dd07", +"order_seed": 903957, +"dur_seed": 360025, +"motifs_seed": 692248, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0061728395061728, 0.10227272727273, 0.074074074074074, 0.10227272727273, 0.2037037037037, 0.090909090909091, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 1, 0.47, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 1, 2 ], [ 0, 3 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 0, 2 ], [ 1, 3 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 3, 0 ], [ 1, 2 ], [ ] ], + [ [ 1, 2 ], [ 0, 3 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 0, 3 ], [ 2, 1 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 2, 0 ], [ 3, 1 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 5.0408163265306, 25.244897959184 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/lilypond/part_I.ly new file mode 100644 index 0000000..a351af0 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/lilypond/part_I.ly @@ -0,0 +1,48 @@ +{ + { b1^\markup { \pad-markup #0.2 "-12"} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b2 fis'2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } + \bar "|" + { fis'2^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} gis'2^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } + \bar "|" + { gis'2 b'2^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b'1 } + \bar "|" + { fis1^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { fis2 ais2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } + \bar "|" + { ais1 } + \bar "|" + { cis'1^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { cis'2 c''2^\markup { \pad-markup #0.2 "-20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''2 fis2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis2 cis'2^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { b'1 } + \bar "|" + { a1^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a2 e'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/lilypond/part_II.ly new file mode 100644 index 0000000..93d3bf8 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/lilypond/part_II.ly @@ -0,0 +1,48 @@ +{ + { g'1^\markup { \pad-markup #0.2 "+2"} ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'2 b'2^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 } + \bar "|" + { b1^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b2 cis'2^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { cis'1 } + \bar "|" + { d'1^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { d'1 } + \bar "|" + { f'1^\markup { \pad-markup #0.2 "-22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} ~ } + \bar "|" + { f'2 b'2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'2 fis'2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 } + \bar "|" + { gis'1^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { gis'1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} } + \bar "|" + { c''1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { c''2 b'2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } + \bar "|" + { b'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/lilypond/part_III.ly new file mode 100644 index 0000000..606adf0 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/lilypond/part_III.ly @@ -0,0 +1,48 @@ +{ + { fis'1^\markup { \pad-markup #0.2 "-10"} } + \bar "|" + { g2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} e'2^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2 fis'2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 } + \bar "|" + { fis'1^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'2 a'2^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { a'2 b'2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 } + \bar "|" + { g1^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + \bar "|" + { g1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/lilypond/part_IV.ly new file mode 100644 index 0000000..b3eb4c8 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/44490863/lilypond/part_IV.ly @@ -0,0 +1,48 @@ +{ + { gis'2^\markup { \pad-markup #0.2 "-45"} b'2^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b'1 } + \bar "|" + { e1^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} } + \bar "|" + { fis1^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 } + \bar "|" + { b,1^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b,1 } + \bar "|" + { d1^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + \bar "|" + { d2 fis2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { fis2 gis2^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } + \bar "|" + { gis1 } + \bar "|" + { ais1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} } + \bar "|" + { cis'1^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { cis'1 } + \bar "|" + { ais'1^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } + \bar "|" + { ais'2 b2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b2 d'2^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 } + \bar "|" + { a'2^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} e,2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/4874dd07_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/4874dd07_code.scd new file mode 100644 index 0000000..c4e3d1b --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/4874dd07_code.scd @@ -0,0 +1,979 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/4874dd07_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/4874dd07_mus_model.json new file mode 100644 index 0000000..74fb11d --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/4874dd07_mus_model.json @@ -0,0 +1,121 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 2, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 2, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 2, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -2, 3, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 2, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ -1, 3, 0, 0, 0, 0 ], [ -2, 3, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 2, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ -1, 3, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -1, 2, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 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, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 1, -1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 1, -1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 1, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 1, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ] ], 1 ], + [ [ [ 1, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, -1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, -1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 2, 1, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 2, 0, 0, 1, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ 0, -1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], + [ [ -1, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], + [ [ -1, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], + [ [ -1, 2, 1, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], + [ [ -1, 2, 0, 0, 1, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ] +], +"cur_uid": "4874dd07", +"ref_uid": "nil", +"order_seed": 701987, +"dur_seed": 150121, +"motifs_seed": 970221, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0061728395061728, 0.10227272727273, 0.074074074074074, 0.10227272727273, 0.2037037037037, 0.090909090909091, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 1, 0.47, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 0, 3 ], [ 1, 2 ], [ ] ], + [ [ 2, 1 ], [ 0, 3 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 3 ], [ 0, 2, 1 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 2, 0 ], [ 1, 3 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 4.8265306122449, 25 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/lilypond/part_I.ly new file mode 100644 index 0000000..63f4a0e --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/lilypond/part_I.ly @@ -0,0 +1,38 @@ +{ + { r2 c'2^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'2 g2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + \bar "|" + { a1^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} } + \bar "|" + { ais1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + \bar "|" + { ais1 } + \bar "|" + { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { c'2 f'2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 } + \bar "|" + { g'1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'1 } + \bar "|" + { ais'1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { ais'1 } + \bar "|" + { c''1^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c''1 } + \bar "|" + { b1^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/lilypond/part_II.ly new file mode 100644 index 0000000..8b4aa3d --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/lilypond/part_II.ly @@ -0,0 +1,38 @@ +{ + { r1 } + \bar "|" + { r2 g'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'2 a'2^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a'2 c''2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''2 g'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'2 c''2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 } + \bar "|" + { f1^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } + \bar "|" + { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { c'2 g'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/lilypond/part_III.ly new file mode 100644 index 0000000..f3dc391 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/lilypond/part_III.ly @@ -0,0 +1,38 @@ +{ + { r1 } + \bar "|" + { c1^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c1 ~ } + \bar "|" + { c1 ~ } + \bar "|" + { c1 } + \bar "|" + { g1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { g1 } + \bar "|" + { gis1^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { gis1 } + \bar "|" + { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'2 c2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { c1 ~ } + \bar "|" + { c1 ~ } + \bar "|" + { c2 g2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g1 } + \bar "|" + { d'1^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + \bar "|" + { d'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/lilypond/part_IV.ly new file mode 100644 index 0000000..c4f4ab6 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4874dd07/lilypond/part_IV.ly @@ -0,0 +1,38 @@ +{ + { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { c'1 } + \bar "|" + { d'1^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'2 c2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c1 ~ } + \bar "|" + { c1 } + \bar "|" + { f1^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { f2 g2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { g2 f'2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'2 c''2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c''1 } + \bar "|" + { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { c'2 f2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } + \bar "|" + { f2 g2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g2 fis'2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/4b40ed47_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/4b40ed47_code.scd new file mode 100644 index 0000000..42b64ff --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/4b40ed47_code.scd @@ -0,0 +1,981 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/4b40ed47_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/4b40ed47_mus_model.json new file mode 100644 index 0000000..85dcea4 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/4b40ed47_mus_model.json @@ -0,0 +1,86 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -4, 2, 4, 2, 1, 0 ], [ -3, 2, 3, 2, 1, -1 ], [ -4, 2, 3, 2, 1, 0 ], [ -3, 2, 3, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 2, 4, 2, 1, 0 ], [ -3, 2, 3, 2, 1, -1 ], [ -5, 2, 4, 2, 1, 1 ], [ -3, 2, 3, 2, 0, 0 ] ], 1 ], + [ [ [ -4, 2, 4, 2, 1, 0 ], [ -3, 2, 3, 2, 1, -1 ], [ -5, 2, 4, 2, 1, 1 ], [ -3, 2, 3, 2, 2, -1 ] ], 1 ] + ], + [ + [ [ [ -4, 2, 4, 2, 1, 0 ], [ -4, 1, 4, 2, 1, 1 ], [ -5, 2, 4, 2, 1, 1 ], [ -3, 2, 3, 2, 2, -1 ] ], 1 ], + [ [ [ -5, 2, 5, 2, 1, 1 ], [ -4, 1, 4, 2, 1, 1 ], [ -5, 2, 4, 2, 1, 1 ], [ -3, 2, 3, 2, 2, -1 ] ], 1 ], + [ [ [ -5, 2, 5, 2, 1, 1 ], [ -4, 1, 4, 2, 1, 1 ], [ -5, 2, 4, 2, 1, 1 ], [ -5, 1, 4, 2, 1, 1 ] ], 1 ] + ], + [ + [ [ [ -5, 2, 5, 2, 1, 1 ], [ -4, 1, 4, 2, 1, 1 ], [ -3, 1, 4, 2, 1, 0 ], [ -5, 1, 4, 2, 1, 1 ] ], 1 ] + ], + [ + [ [ [ -5, 2, 5, 2, 1, 1 ], [ -4, 1, 4, 2, 1, 1 ], [ -3, 1, 4, 2, 1, 0 ], [ -5, 1, 4, 3, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 2, 5, 2, 1, 1 ], [ -4, 1, 4, 2, 1, 1 ], [ -4, 1, 5, 2, 1, 1 ], [ -5, 1, 4, 3, 1, 0 ] ], 1 ], + [ [ [ -5, 1, 4, 4, 1, 0 ], [ -4, 1, 4, 2, 1, 1 ], [ -4, 1, 5, 2, 1, 1 ], [ -5, 1, 4, 3, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 1, 4, 4, 1, 0 ], [ -4, 1, 4, 2, 1, 1 ], [ -6, 1, 4, 3, 1, 1 ], [ -5, 1, 4, 3, 1, 0 ] ], 1 ], + [ [ [ -5, 1, 4, 4, 1, 0 ], [ -4, 1, 4, 2, 1, 1 ], [ -6, 1, 4, 3, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ], 1 ], + [ [ [ -5, 2, 4, 2, 1, 1 ], [ -4, 1, 4, 2, 1, 1 ], [ -6, 1, 4, 3, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 2, 4, 2, 1, 1 ], [ -4, 1, 4, 3, 1, 0 ], [ -6, 1, 4, 3, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 1, 5, 2, 1, 0 ], [ -4, 1, 4, 3, 1, 0 ], [ -6, 1, 4, 3, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 0, 4, 3, 1, 1 ], [ -4, 1, 4, 3, 1, 0 ], [ -6, 1, 4, 3, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 0, 4, 3, 1, 1 ], [ -4, 1, 4, 3, 0, 1 ], [ -6, 1, 4, 3, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 0, 4, 3, 1, 1 ], [ -4, 1, 4, 3, 0, 1 ], [ -5, 1, 4, 2, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 0, 4, 3, 1, 1 ], [ -3, 1, 4, 1, 1, 0 ], [ -5, 1, 4, 2, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ], 1 ], + [ [ [ -3, 1, 4, 2, 1, 0 ], [ -3, 1, 4, 1, 1, 0 ], [ -5, 1, 4, 2, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -4, 0, 4, 3, 1, 1 ], [ -4, 1, 4, 3, 1, 0 ], [ -6, 1, 4, 3, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ], + [ [ -4, 0, 4, 3, 1, 1 ], [ -4, 1, 4, 3, 0, 1 ], [ -6, 1, 4, 3, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ], + [ [ -4, 0, 4, 3, 1, 1 ], [ -4, 1, 4, 3, 0, 1 ], [ -5, 1, 4, 2, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ], + [ [ -4, 0, 4, 3, 1, 1 ], [ -3, 1, 4, 1, 1, 0 ], [ -5, 1, 4, 2, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ], + [ [ -3, 1, 4, 2, 1, 0 ], [ -3, 1, 4, 1, 1, 0 ], [ -5, 1, 4, 2, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ] +], +"cur_uid": "4b40ed47", +"ref_uid": "6db2efcc", +"order_seed": 401316, +"dur_seed": 325935, +"motifs_seed": 749229, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0061728395061728, 0.10227272727273, 0.074074074074074, 0.10227272727273, 0.2037037037037, 0.090909090909091, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 1, 0.47, 0.43, 1, 0.4 ], +"hd_exp": 4, +"hd_invert": 0, +"order": +[ + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 10.091836734694, 10.091836734694 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/lilypond/part_I.ly new file mode 100644 index 0000000..669e421 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/lilypond/part_I.ly @@ -0,0 +1,22 @@ +{ + { a'1^\markup { \pad-markup #0.2 "+1"} } + \bar "|" + { c''1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } + \bar "|" + { c''2 gis2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { gis2 a2^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a2 b2^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/lilypond/part_II.ly new file mode 100644 index 0000000..1c18623 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/lilypond/part_II.ly @@ -0,0 +1,22 @@ +{ + { dis'2^\markup { \pad-markup #0.2 "-48"} dis'2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }} } + \bar "|" + { c''1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } + \bar "|" + { f1^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f2 gis2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} ~ } + \bar "|" + { gis1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/lilypond/part_III.ly new file mode 100644 index 0000000..370f202 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/lilypond/part_III.ly @@ -0,0 +1,22 @@ +{ + { fis'1^\markup { \pad-markup #0.2 "+11"} ~ } + \bar "|" + { fis'2 gis'2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'2 a'2^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }} ~ } + \bar "|" + { a'1 } + \bar "|" + { c''1^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} } + \bar "|" + { d'1^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/lilypond/part_IV.ly new file mode 100644 index 0000000..34d5f50 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4b40ed47/lilypond/part_IV.ly @@ -0,0 +1,22 @@ +{ + { fis'1^\markup { \pad-markup #0.2 "+38"} ~ } + \bar "|" + { fis'1 } + \bar "|" + { g'1^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'2 g'2^\markup { \pad-markup #0.2 "-26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } + \bar "|" + { g'1 } + \bar "|" + { dis'1^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} } + \bar "|" + { dis'2^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} ais'2^\markup { \pad-markup #0.2 "+44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'2 b'2^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/4bf1af12_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/4bf1af12_code.scd new file mode 100644 index 0000000..42b64ff --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/4bf1af12_code.scd @@ -0,0 +1,981 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/4bf1af12_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/4bf1af12_mus_model.json new file mode 100644 index 0000000..8d43276 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/4bf1af12_mus_model.json @@ -0,0 +1,87 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -5, 1, 2, 2, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 1, 2, 2, 1, 0 ], [ -3, 0, 2, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 1, 2, 2, 1, 0 ], [ -3, 0, 2, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 1, 2, 2, 1, 0 ], [ -3, 0, 2, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -2, 0, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 0, 2, 2, 1, 0 ], [ -3, 0, 2, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -2, 0, 2, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 0, 2, 2, 1, 0 ], [ -3, 0, 2, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 0, 2, 2, 1, 0 ], [ -3, 0, 2, 2, 1, 0 ], [ -2, 0, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 1, 2, 2, 1, 0 ], [ -3, 0, 2, 2, 1, 0 ], [ -2, 0, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 1, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -2, 0, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 1, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 1, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -3, 1, 3, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 1, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ], [ -3, 1, 3, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 1, 2, 2, 1, 0 ], [ -4, 1, 2, 3, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ], [ -3, 1, 3, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 1, 2, 2, 1, 0 ], [ -4, 1, 2, 3, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -3, 1, 3, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 1, 2, 2, 1, 0 ], [ -4, 1, 2, 3, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -2, 0, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 1, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -2, 0, 2, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -2, 0, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 2, 2, 2, 1, 0 ], [ -4, 1, 2, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -2, 0, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 2, 2, 2, 1, 0 ], [ -4, 1, 2, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 2, 2, 2, 1, 0 ], [ -4, 1, 2, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 2, 2, 2, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -4, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -2, 0, 2, 2, 1, 0 ] ], + [ [ -4, 2, 2, 2, 1, 0 ], [ -4, 1, 2, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -2, 0, 2, 2, 1, 0 ] ], + [ [ -4, 2, 2, 2, 1, 0 ], [ -4, 1, 2, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], + [ [ -4, 2, 2, 2, 1, 0 ], [ -4, 1, 2, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], + [ [ -4, 2, 2, 2, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ] +], +"cur_uid": "4bf1af12", +"ref_uid": 44490863, +"order_seed": 556699, +"dur_seed": 515215, +"motifs_seed": 916157, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0061728395061728, 0.10227272727273, 0.074074074074074, 0.10227272727273, 0.2037037037037, 0.090909090909091, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 1, 0.47, 0.43, 1, 0.9 ], +"hd_exp": 9, +"hd_invert": 0, +"order": +[ + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 0 ], [ 1, 2, 3 ], [ ] ], + [ [ 3, 0 ], [ 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 0, 3 ], [ 2, 1 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 10, 10.091836734694 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/lilypond/part_I.ly new file mode 100644 index 0000000..28e0f1c --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/lilypond/part_I.ly @@ -0,0 +1,22 @@ +{ + { g'1^\markup { \pad-markup #0.2 "-21"} ~ } + \bar "|" + { g'2 a'2^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a'2 e'2^\markup { \pad-markup #0.2 "-36"} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 } + \bar "|" + { g'1^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { g'1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { a'1 } + \bar "|" + { e'1^\markup { \pad-markup #0.2 "-36"}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/lilypond/part_II.ly new file mode 100644 index 0000000..e6c2955 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/lilypond/part_II.ly @@ -0,0 +1,22 @@ +{ + { b'1^\markup { \pad-markup #0.2 "-34"} } + \bar "|" + { c''1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { c''1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a'2 b'2^\markup { \pad-markup #0.2 "-34"} ~ } + \bar "|" + { b'2 e'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { e'2 b'2^\markup { \pad-markup #0.2 "-34"} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'2 c''2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/lilypond/part_III.ly new file mode 100644 index 0000000..9111a1e --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/lilypond/part_III.ly @@ -0,0 +1,22 @@ +{ + { g2^\markup { \pad-markup #0.2 "-21"} a2^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 } + \bar "|" + { b1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { b1 } + \bar "|" + { cis'1^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { cis'2 e'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { e'2 e2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { e1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/lilypond/part_IV.ly new file mode 100644 index 0000000..5c0d977 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4bf1af12/lilypond/part_IV.ly @@ -0,0 +1,22 @@ +{ + { e,1^\markup { \pad-markup #0.2 "-36"} ~ } + \bar "|" + { e,1 } + \bar "|" + { a,1^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a,2 e2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 } + \bar "|" + { b1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4c745666/4c745666_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4c745666/4c745666_code.scd new file mode 100644 index 0000000..0b55c37 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4c745666/4c745666_code.scd @@ -0,0 +1,977 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4c745666/4c745666_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4c745666/4c745666_mus_model.json new file mode 100644 index 0000000..06875fc --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4c745666/4c745666_mus_model.json @@ -0,0 +1,166 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1 ], + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 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 ] + ], + [ + [ [ [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 1, 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, 1, 0, 0, 0, -1 ], [ -1, 1, 0, 1, 0, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 1, 1, 0, 0, 0, -1 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ -1, 1, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ 1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ -2, 2, 0, 1, 1, 0 ] ], 1 ], + [ [ [ 1, 0, 0, 0, 0, 0 ], [ -1, 2, 0, 1, -1, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ -2, 2, 0, 1, 1, 0 ] ], 1 ], + [ [ [ -2, 2, 0, 2, 0, 0 ], [ -1, 2, 0, 1, -1, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ -2, 2, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 0, 2, 0, 0 ], [ -1, 2, 0, 1, -1, 0 ], [ -3, 3, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 0, 2, 0, 0 ], [ -1, 2, 0, 1, -1, 0 ], [ -3, 3, 0, 1, 1, 0 ], [ -1, 2, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -2, 2, 0, 2, 0, 0 ], [ -2, 3, 0, 1, 0, 0 ], [ -3, 3, 0, 1, 1, 0 ], [ -1, 2, 0, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 0, 2, 0, 0 ], [ -2, 3, 0, 1, 0, 0 ], [ -2, 2, 1, 1, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -2, 3, 0, 1, 0, 0 ], [ -2, 2, 1, 1, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -2, 2, 1, 1, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -3, 2, 0, 1, 1, 0 ], [ -1, 2, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -3, 2, 0, 1, 1, 0 ], [ -1, 2, 0, 1, 0, -1 ] ], 1 ], + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -2, 2, 0, 1, 0, 1 ], [ -3, 2, 0, 1, 1, 0 ], [ -1, 2, 0, 1, 0, -1 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -1, 2, 0, 1, 1, -1 ], [ -3, 2, 0, 1, 1, 0 ], [ -1, 2, 0, 1, 0, -1 ] ], 1 ], + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -1, 2, 0, 1, 1, -1 ], [ -3, 2, 0, 1, 1, 0 ], [ -1, 2, 0, 0, 1, 0 ] ], 1 ], + [ [ [ -2, 2, 0, 1, 1, -1 ], [ -1, 2, 0, 1, 1, -1 ], [ -3, 2, 0, 1, 1, 0 ], [ -1, 2, 0, 0, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 0, 1, 1, -1 ], [ -1, 2, 0, 1, 1, -1 ], [ -3, 2, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ], + [ [ [ -2, 2, 0, 1, 1, -1 ], [ -1, 2, 0, 1, 0, 0 ], [ -3, 2, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 0, 1, 2, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ -3, 2, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ], + [ [ [ -2, 1, 0, 1, 2, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ -4, 3, 0, 1, 2, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ], + [ [ [ -2, 1, 0, 1, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ], [ -4, 3, 0, 1, 2, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ], [ -4, 3, 0, 1, 2, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 0, 0, 2, 0 ], [ -2, 3, 0, 0, 2, 0 ], [ -4, 3, 0, 1, 2, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ], + [ [ [ -3, 3, 0, 0, 2, 0 ], [ -2, 3, 0, 0, 2, 0 ], [ -4, 3, 0, 1, 2, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 3, 0, 0, 2, 0 ], [ -2, 3, 0, 0, 2, 0 ], [ -4, 3, 0, 1, 2, 0 ], [ -1, 3, 0, 0, 2, -1 ] ], 1 ], + [ [ [ -3, 3, 0, 0, 2, 0 ], [ -2, 3, 1, 0, 2, 0 ], [ -4, 3, 0, 1, 2, 0 ], [ -1, 3, 0, 0, 2, -1 ] ], 1 ], + [ [ [ -3, 3, 0, 0, 2, 0 ], [ -2, 3, 1, 0, 2, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -1, 3, 0, 0, 2, -1 ] ], 1 ] + ], + [ + [ [ [ -3, 3, 0, 0, 2, 0 ], [ -4, 3, 0, 1, 1, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -1, 3, 0, 0, 2, -1 ] ], 1 ], + [ [ [ -3, 3, 0, 0, 1, 1 ], [ -4, 3, 0, 1, 1, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -1, 3, 0, 0, 2, -1 ] ], 1 ] + ], + [ + [ [ [ -3, 3, 0, 0, 1, 1 ], [ -2, 3, 0, 0, 0, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -1, 3, 0, 0, 2, -1 ] ], 1 ], + [ [ [ -3, 3, 0, 1, 1, 0 ], [ -2, 3, 0, 0, 0, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -1, 3, 0, 0, 2, -1 ] ], 1 ], + [ [ [ -3, 3, 0, 1, 1, 0 ], [ -2, 3, 0, 0, 0, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -2, 3, 0, 0, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 3, 0, 1, 0, 0 ], [ -2, 3, 0, 0, 0, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -2, 3, 0, 0, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 3, 0, 1, 0, 0 ], [ -2, 3, 0, 0, 0, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -1, 3, 0, 1, 0, -1 ] ], 1 ], + [ [ [ -2, 3, 0, 1, 0, 0 ], [ -2, 3, 0, 0, 0, 0 ], [ -1, 3, 0, 0, 0, 0 ], [ -1, 3, 0, 1, 0, -1 ] ], 1 ], + [ [ [ -2, 3, 0, 1, 0, 0 ], [ -2, 3, 0, 1, -1, 0 ], [ -1, 3, 0, 0, 0, 0 ], [ -1, 3, 0, 1, 0, -1 ] ], 1 ] + ], + [ + [ [ [ -1, 3, -1, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 0 ], [ -1, 3, 0, 0, 0, 0 ], [ -1, 3, 0, 1, 0, -1 ] ], 1 ], + [ [ [ -1, 3, -1, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 1 ], [ -1, 3, 0, 1, 0, -1 ] ], 1 ] + ], + [ + [ [ [ -1, 3, -1, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 1 ], [ -2, 3, 0, 2, -1, 0 ] ], 1 ], + [ [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 1 ], [ -2, 3, 0, 2, -1, 0 ] ], 1 ], + [ [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 0 ], [ -3, 4, 0, 1, -1, 0 ], [ -2, 3, 0, 2, -1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 4, 0, 1, -1, 0 ], [ -3, 4, 0, 1, -1, 0 ], [ -2, 3, 0, 2, -1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 4, 0, 1, -1, 0 ], [ -3, 4, 0, 1, -1, 0 ], [ 0, 3, -1, 0, -1, 0 ] ], 1 ], + [ [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 4, 0, 1, -1, 0 ], [ -2, 3, -1, 1, 0, 0 ], [ 0, 3, -1, 0, -1, 0 ] ], 1 ], + [ [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 4, 0, 1, -1, 0 ], [ "Rest" ], [ 0, 3, -1, 0, -1, 0 ] ], 1 ], + [ [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 4, 0, 1, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ -2, 3, -1, 1, -1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, -1, 0, -1, 2 ], [ 0, -1, -1, 1, -1, 2 ], [ 1, 0, -1, 0, -1, 1 ], [ 0, -1, -1, 1, -1, 1 ] ], + [ [ 0, 0, -1, 1, -1, 1 ], [ 0, -1, -1, 1, -1, 2 ], [ 1, 0, -1, 0, -1, 1 ], [ 0, -1, -1, 1, -1, 1 ] ], + [ [ 0, 0, -1, 1, -1, 1 ], [ 0, -1, -1, 1, -1, 2 ], [ 0, -1, -1, 2, -1, 1 ], [ 0, -1, -1, 1, -1, 1 ] ], + [ [ 0, 0, -1, 1, -1, 1 ], [ 1, -1, -1, 0, -1, 1 ], [ 0, -1, -1, 2, -1, 1 ], [ 0, -1, -1, 1, -1, 1 ] ], + [ [ 0, 0, -1, 1, -1, 1 ], [ 1, 0, -1, 0, -1, 1 ], [ 0, -1, -1, 2, -1, 1 ], [ 0, -1, -1, 1, -1, 1 ] ] +], +"cur_uid": "4c745666", +"ref_uid": "nil", +"order_seed": 885120, +"dur_seed": 331456, +"motifs_seed": 712350, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0020576131687243, 0.068181818181818, 0.074074074074074, 0.0625, 0.20576131687243, 0.0625, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.78600823045268, 0.068181818181818, 0.98971193415638, 0.0625 ], +"passages_weights": [ 1, 1, 1, 1, 0.1 ], +"hd_exp": 1, +"hd_invert": 0, +"order": +[ + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 3, 0 ], [ 1, 2 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 0, 3 ], [ 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 2, 1 ], [ 0, 3 ], [ ] ], + [ [ 0 ], [ 1, 2, 3 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 2, 0 ], [ 1, 3 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 0, 3 ], [ 2, 1 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 24.724489795918, 25 ], +"passages_size": [ 0, 0 ], +"motif_edited": "true", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/4e9f1dcc_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/4e9f1dcc_code.scd new file mode 100644 index 0000000..42b64ff --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/4e9f1dcc_code.scd @@ -0,0 +1,981 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/4e9f1dcc_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/4e9f1dcc_mus_model.json new file mode 100644 index 0000000..38e73bd --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/4e9f1dcc_mus_model.json @@ -0,0 +1,86 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -3, 1, 4, 2, 1, 0 ], [ -4, 1, 5, 2, 1, 1 ], [ -5, 1, 4, 2, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -6, 1, 4, 2, 1, 2 ], [ -4, 1, 5, 2, 1, 1 ], [ -5, 1, 4, 2, 1, 1 ], [ -4, 1, 4, 2, 1, 0 ] ], 1 ], + [ [ [ -6, 1, 4, 2, 1, 2 ], [ -4, 1, 5, 2, 1, 1 ], [ -5, 1, 4, 2, 1, 1 ], [ -4, 1, 5, 2, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -6, 1, 4, 2, 1, 2 ], [ -4, 1, 4, 2, 0, 1 ], [ -5, 1, 4, 2, 1, 1 ], [ -4, 1, 5, 2, 0, 1 ] ], 1 ], + [ [ [ -6, 1, 4, 2, 1, 2 ], [ -4, 1, 4, 2, 0, 1 ], [ -5, 1, 5, 2, 0, 2 ], [ -4, 1, 5, 2, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -6, 1, 4, 2, 1, 2 ], [ -4, 1, 5, 2, -1, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -4, 1, 5, 2, 0, 1 ] ], 1 ], + [ [ [ -5, 1, 4, 2, 0, 2 ], [ -4, 1, 5, 2, -1, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -4, 1, 5, 2, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -4, 0, 5, 2, 0, 1 ], [ -4, 1, 5, 2, -1, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -4, 1, 5, 2, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -4, 0, 5, 2, 0, 1 ], [ -3, 1, 5, 2, 0, 0 ], [ -5, 1, 5, 2, 0, 2 ], [ -4, 1, 5, 2, 0, 1 ] ], 1 ], + [ [ [ -5, 2, 5, 2, 0, 1 ], [ -3, 1, 5, 2, 0, 0 ], [ -5, 1, 5, 2, 0, 2 ], [ -4, 1, 5, 2, 0, 1 ] ], 1 ] + ], + [ + [ [ [ -5, 2, 5, 2, 0, 1 ], [ -3, 1, 5, 2, 0, 0 ], [ -5, 1, 5, 2, 0, 2 ], [ -4, 1, 5, 2, -1, 2 ] ], 1 ], + [ [ [ -5, 2, 5, 2, 0, 1 ], [ -5, 1, 5, 2, 0, 3 ], [ -5, 1, 5, 2, 0, 2 ], [ -4, 1, 5, 2, -1, 2 ] ], 1 ], + [ [ [ -4, 1, 5, 1, 0, 2 ], [ -5, 1, 5, 2, 0, 3 ], [ -5, 1, 5, 2, 0, 2 ], [ -4, 1, 5, 2, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -4, 1, 5, 1, 0, 2 ], [ -6, 1, 5, 2, 0, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -4, 1, 5, 2, -1, 2 ] ], 1 ], + [ [ [ -4, 1, 5, 1, 0, 2 ], [ -6, 1, 5, 2, 0, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -5, 2, 5, 2, 0, 2 ] ], 1 ], + [ [ [ -4, 0, 5, 2, 0, 2 ], [ -6, 1, 5, 2, 0, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -5, 2, 5, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -4, 0, 5, 2, 0, 2 ], [ -6, 2, 5, 2, 0, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -5, 2, 5, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -4, 0, 5, 2, 0, 2 ], [ -5, 1, 4, 2, 0, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -5, 2, 5, 2, 0, 2 ] ], 1 ], + [ [ [ -6, 1, 5, 1, 0, 2 ], [ -5, 1, 4, 2, 0, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -5, 2, 5, 2, 0, 2 ] ], 1 ], + [ [ [ -6, 1, 5, 1, 0, 2 ], [ -5, 1, 4, 2, 0, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -5, 1, 5, 2, 0, 3 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -4, 0, 5, 2, 0, 2 ], [ -6, 1, 5, 2, 0, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -5, 2, 5, 2, 0, 2 ] ], + [ [ -4, 0, 5, 2, 0, 2 ], [ -6, 2, 5, 2, 0, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -5, 2, 5, 2, 0, 2 ] ], + [ [ -4, 0, 5, 2, 0, 2 ], [ -5, 1, 4, 2, 0, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -5, 2, 5, 2, 0, 2 ] ], + [ [ -6, 1, 5, 1, 0, 2 ], [ -5, 1, 4, 2, 0, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -5, 2, 5, 2, 0, 2 ] ], + [ [ -6, 1, 5, 1, 0, 2 ], [ -5, 1, 4, 2, 0, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -5, 1, 5, 2, 0, 3 ] ] +], +"cur_uid": "4e9f1dcc", +"ref_uid": "4b40ed47", +"order_seed": 207247, +"dur_seed": 435476, +"motifs_seed": 299289, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0061728395061728, 0.10227272727273, 0.074074074074074, 0.10227272727273, 0.2037037037037, 0.090909090909091, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 1, 0.47, 0.43, 1, 0.3 ], +"hd_exp": 3, +"hd_invert": 0, +"order": +[ + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 1, 2 ], [ 0, 3 ], [ ] ], + [ [ 0, 3 ], [ 1, 2 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 2 ], [ 1, 3, 0 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 10.091836734694, 10.091836734694 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/lilypond/part_I.ly new file mode 100644 index 0000000..bca81dd --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/lilypond/part_I.ly @@ -0,0 +1,22 @@ +{ + { b1^\markup { \pad-markup #0.2 "+36"} } + \bar "|" + { fis'1^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } + \bar "|" + { a'1 } + \bar "|" + { ais'1^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'2 b'2^\markup { \pad-markup #0.2 "-7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/lilypond/part_II.ly new file mode 100644 index 0000000..48f81fd --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/lilypond/part_II.ly @@ -0,0 +1,22 @@ +{ + { gis1^\markup { \pad-markup #0.2 "-23"} ~ } + \bar "|" + { gis1 } + \bar "|" + { dis'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/lilypond/part_III.ly new file mode 100644 index 0000000..6a243ff --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/lilypond/part_III.ly @@ -0,0 +1,22 @@ +{ + { c''1^\markup { \pad-markup #0.2 "-37"} ~ } + \bar "|" + { c''2 d'2^\markup { \pad-markup #0.2 "+25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } + \bar "|" + { d'2 a'2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } + \bar "|" + { a'1 } + \bar "|" + { ais'1^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }} ~ } + \bar "|" + { ais'2 b'2^\markup { \pad-markup #0.2 "-7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }} ~ } + \bar "|" + { b'2 dis2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { dis1 } + \bar "|" + { ais2^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} b2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + \bar "|" + { b1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/lilypond/part_IV.ly new file mode 100644 index 0000000..a370cf4 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4e9f1dcc/lilypond/part_IV.ly @@ -0,0 +1,22 @@ +{ + { b'2^\markup { \pad-markup #0.2 "+36"} e2^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }} ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 } + \bar "|" + { b2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} b2^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } + \bar "|" + { b2 cis'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } + \bar "|" + { cis'1 } + \bar "|" + { f'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } + \bar "|" + { f'2 gis'2^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { gis'1 } + \bar "|" + { f,1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/4ef018fc_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/4ef018fc_code.scd new file mode 100644 index 0000000..57e638d --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/4ef018fc_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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 = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).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.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/4ef018fc_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/4ef018fc_mus_model.json new file mode 100644 index 0000000..71a4e25 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/4ef018fc_mus_model.json @@ -0,0 +1,79 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 3.75 ], + [ [ [ 0, 0, 0, 0, 1, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.75 ] + ], + [ + [ [ [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, -1, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], + [ [ [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, -1, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 1, 0 ] ], 0.75 ], + [ [ [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, -1, 0, 1, 0 ], [ -1, 0, 0, 0, 1, 0 ], [ 0, -1, 0, 0, 1, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, -1, 0, 1, 0 ], [ -1, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 1, -1 ] ], 0.75 ] + ], + [ + [ [ [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, -1, 0, 1, 0 ], [ 0, 0, 0, -1, 1, 0 ], [ 0, 0, 0, 0, 1, -1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 0, 0, 0, -1, 1, 0 ], [ 0, 0, 0, 0, 1, -1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 0, 0, 0, -1, 1, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 2.5 ] + ], + [ + [ [ [ 0, 0, 0, 0, 1, 0 ], [ "Rest" ], [ 0, 0, 0, -1, 1, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 0 ], + [ [ [ -1, 0, 0, 0, 2, 1 ], [ "Rest" ], [ 0, 0, 0, -1, 1, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 0.625 ], + [ [ [ -1, 0, 0, 0, 2, 1 ], [ "Rest" ], [ -2, 0, 0, 1, 2, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 0 ], + [ [ [ -1, 0, 0, 1, 2, 0 ], [ "Rest" ], [ -2, 0, 0, 1, 2, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 1.75 ] + ], + [ + [ [ [ -1, 0, 0, 1, 2, 0 ], [ "Rest" ], [ -1, 0, -1, 0, 2, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 2, 0 ], [ "Rest" ], [ -1, 0, -1, 0, 2, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 1.125 ], + [ [ [ 0, 0, 0, 0, 2, 0 ], [ -1, 0, 1, 0, 2, 0 ], [ -1, 0, -1, 0, 2, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 1.125 ], + [ [ [ 0, 0, 0, 0, 2, 0 ], [ -1, 0, 1, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 2.625 ] + ], + [ + [ [ [ 0, 0, 0, 0, 2, 0 ], [ -1, 0, 1, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ], 0 ], + [ [ [ -1, 2, 0, 0, 2, 0 ], [ -1, 0, 1, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ], 0 ], + [ [ [ -1, 2, 0, 0, 2, 0 ], [ -2, 1, 0, 1, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ], 0.625 ], + [ [ [ -1, 2, 0, 0, 2, 0 ], [ -1, 1, 0, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ], 2.375 ], + [ [ [ -1, 2, 0, 0, 2, 0 ], [ -1, 1, 0, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ "Rest" ] ], 0 ], + [ [ [ -1, 2, 0, 0, 2, 0 ], [ "Rest" ], [ -2, 1, 0, 0, 2, 0 ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ -2, 1, 0, 0, 2, 0 ], [ "Rest" ] ], 1.125 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 4.125 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 2, 0 ], [ -1, 0, 1, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], + [ [ 0, 0, 0, 0, 2, 0 ], [ -1, 0, 1, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ], + [ [ -1, 2, 0, 0, 2, 0 ], [ -1, 0, 1, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ], + [ [ -1, 2, 0, 0, 2, 0 ], [ -2, 1, 0, 1, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ], + [ [ -1, 2, 0, 0, 2, 0 ], [ -1, 1, 0, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ] +], +"cur_uid": "4ef018fc", +"ref_uid": "nil", +"order_seed": 612843, +"dur_seed": 369555, +"motifs_seed": 949457, +"entrances_probs_vals": [ 1, 0, 2.9365079365079, 0.47, 2.8021978021978, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0.48, 0, 2.1031746031746, 0.44, 1.3736263736264, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0.58, 0.95, 4.2063492063492, 0.58, 2.2252747252747, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2021.0526315789, 338 ], [ -1055.1083591331, 1453 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.39094650205761, 0, 0.43621399176955, 0.14772727272727, 0.47942386831276, 0, 0.51440329218107, 0, 0.56378600823045, 0.55113636363636, 0.62139917695473, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 2 ], [ 0 ], [ 1, 3 ] ], + [ [ 0 ], [ 1, 3, 2, 3 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 3 ], [ 0, 2, 0 ], [ 1 ] ], + [ [ 3 ], [ 2, 0, 1, 2 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 5.0408163265306, 13.122448979592 ], +"passages_size": [ 0, 2 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/lilypond/part_I.ly new file mode 100644 index 0000000..a915563 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/lilypond/part_I.ly @@ -0,0 +1,26 @@ +{ + { r1 } + \bar "|" + { r1 } + \bar "|" + { r4 ais4^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ ais8[ a8^\markup { \pad-markup #0.2 "+11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ a4 } + \bar "|" + { b1^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b2. ~ b8[ cis'8^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'4 ~ cis'8[ r8] r2 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/lilypond/part_II.ly new file mode 100644 index 0000000..a3007ee --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/lilypond/part_II.ly @@ -0,0 +1,26 @@ +{ + { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'2 ~ c'8[ fis8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ fis4 } + \bar "|" + { gis1^\markup { \pad-markup #0.2 "-18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { gis2 ~ gis16[ a8.^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}] ~ a4 ~ } + \bar "|" + { a4 ~ a8.[ g16^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}] ~ g2 ~ } + \bar "|" + { g2 ~ g16[ fis8.^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ fis4 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis2. ~ fis8.[ r16] } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/lilypond/part_III.ly new file mode 100644 index 0000000..69c36d3 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/lilypond/part_III.ly @@ -0,0 +1,26 @@ +{ + { r1 } + \bar "|" + { r1 } + \bar "|" + { r4 d'2.^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} } + \bar "|" + { cis'1^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { cis'4 r2. } + \bar "|" + { r1 } + \bar "|" + { dis'1^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { dis'2. ~ dis'8[ e'8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }}] ~ } + \bar "|" + { e'8.[ fis'16^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ fis'2. ~ } + \bar "|" + { fis'4 ~ fis'8[ r8] r2 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/lilypond/part_IV.ly new file mode 100644 index 0000000..762d2c4 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/4ef018fc/lilypond/part_IV.ly @@ -0,0 +1,26 @@ +{ + { r1 } + \bar "|" + { r2. r8[ fis'8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↑" }}] ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'4 g'4^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} ~ g'16[ a'8.^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ a'4 ~ } + \bar "|" + { a'4 ~ a'8.[ b'16^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ b'2 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'2. ~ b'8[ cis''8^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''4 ~ cis''8[ r8] r2 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/521654f8_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/521654f8_code.scd new file mode 100644 index 0000000..42b64ff --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/521654f8_code.scd @@ -0,0 +1,981 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/521654f8_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/521654f8_mus_model.json new file mode 100644 index 0000000..6106aa7 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/521654f8_mus_model.json @@ -0,0 +1,87 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -3, 0, 1, 2, 1, 0 ], [ -3, 1, 1, 3, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ -2, 0, 1, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 0, 1, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ -2, 0, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -3, 1, 1, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ -2, 0, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -3, 1, 1, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ -1, 1, 0, 2, 1, -1 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 1, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ -1, 1, 0, 2, 1, -1 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 1, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -3, 2, 1, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -3, 2, 1, 2, 1, 0 ], [ -3, 1, 1, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 1, 2, 1, 0 ], [ -4, 2, 3, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -5, 2, 2, 2, 1, 0 ], [ -4, 2, 3, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -5, 2, 2, 2, 1, 0 ], [ -4, 2, 3, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 3, 2, 2, 1, 0 ], [ -4, 2, 3, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 2, 3, 3, 1, 0 ], [ -4, 2, 3, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -5, 2, 3, 3, 1, 0 ], [ -4, 2, 3, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -4, 3, 3, 2, 1, 0 ] ], 1 ], + [ [ [ -5, 2, 3, 3, 1, 0 ], [ -4, 2, 3, 2, 1, 0 ], [ -4, 2, 3, 2, 1, 1 ], [ -4, 3, 3, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 2, 3, 3, 1, 0 ], [ -4, 2, 3, 2, 1, 0 ], [ -3, 3, 3, 1, 1, 0 ], [ -4, 3, 3, 2, 1, 0 ] ], 1 ], + [ [ [ -5, 2, 3, 3, 1, 0 ], [ -4, 2, 2, 3, 1, 0 ], [ -3, 3, 3, 1, 1, 0 ], [ -4, 3, 3, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 2, 3, 3, 1, 0 ], [ -4, 2, 2, 3, 1, 0 ], [ -3, 3, 3, 1, 1, 0 ], [ -5, 2, 3, 4, 1, 0 ] ], 1 ], + [ [ [ -5, 2, 3, 3, 1, 0 ], [ -4, 2, 2, 3, 1, 0 ], [ -4, 2, 3, 3, 1, -1 ], [ -5, 2, 3, 4, 1, 0 ] ], 1 ], + [ [ [ -5, 2, 3, 3, 1, 0 ], [ -6, 2, 4, 3, 1, 0 ], [ -4, 2, 3, 3, 1, -1 ], [ -5, 2, 3, 4, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 2, 3, 3, 1, 0 ], [ -6, 2, 4, 3, 1, 0 ], [ -6, 3, 3, 4, 1, 0 ], [ -5, 2, 3, 4, 1, 0 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -5, 2, 3, 3, 1, 0 ], [ -4, 2, 2, 3, 1, 0 ], [ -3, 3, 3, 1, 1, 0 ], [ -4, 3, 3, 2, 1, 0 ] ], + [ [ -5, 2, 3, 3, 1, 0 ], [ -4, 2, 2, 3, 1, 0 ], [ -3, 3, 3, 1, 1, 0 ], [ -5, 2, 3, 4, 1, 0 ] ], + [ [ -5, 2, 3, 3, 1, 0 ], [ -4, 2, 2, 3, 1, 0 ], [ -4, 2, 3, 3, 1, -1 ], [ -5, 2, 3, 4, 1, 0 ] ], + [ [ -5, 2, 3, 3, 1, 0 ], [ -6, 2, 4, 3, 1, 0 ], [ -4, 2, 3, 3, 1, -1 ], [ -5, 2, 3, 4, 1, 0 ] ], + [ [ -5, 2, 3, 3, 1, 0 ], [ -6, 2, 4, 3, 1, 0 ], [ -6, 3, 3, 4, 1, 0 ], [ -5, 2, 3, 4, 1, 0 ] ] +], +"cur_uid": "521654f8", +"ref_uid": "7ede7adb", +"order_seed": 185690, +"dur_seed": 954582, +"motifs_seed": 356283, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0061728395061728, 0.10227272727273, 0.074074074074074, 0.10227272727273, 0.2037037037037, 0.090909090909091, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 1, 0.47, 0.43, 1, 0.6 ], +"hd_exp": 6, +"hd_invert": 0, +"order": +[ + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 0, 3 ], [ 2, 1 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 10.091836734694, 10.091836734694 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/lilypond/part_I.ly new file mode 100644 index 0000000..4b86b39 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/lilypond/part_I.ly @@ -0,0 +1,22 @@ +{ + { f'1^\markup { \pad-markup #0.2 "-25"} ~ } + \bar "|" + { f'2 c''2^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }} ~ } + \bar "|" + { c''2 g2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 } + \bar "|" + { b1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b2 ais'2^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'2 ais'2^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { ais'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/lilypond/part_II.ly new file mode 100644 index 0000000..03e091f --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/lilypond/part_II.ly @@ -0,0 +1,22 @@ +{ + { gis'1^\markup { \pad-markup #0.2 "-9"} ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 } + \bar "|" + { b'2^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }} c''2^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} ~ } + \bar "|" + { c''1 } + \bar "|" + { e'1^\markup { \pad-markup #0.2 "-20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/lilypond/part_III.ly new file mode 100644 index 0000000..8972ef2 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/lilypond/part_III.ly @@ -0,0 +1,22 @@ +{ + { a'2^\markup { \pad-markup #0.2 "+46"} c''2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''2 c'2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } + \bar "|" + { dis'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 } + \bar "|" + { gis'1^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { gis'2 e2^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/lilypond/part_IV.ly new file mode 100644 index 0000000..25ed6e8 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/521654f8/lilypond/part_IV.ly @@ -0,0 +1,22 @@ +{ + { f1^\markup { \pad-markup #0.2 "-25"} } + \bar "|" + { c'1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} } + \bar "|" + { g'1^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'2 b,2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b,2 fis2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} } + \bar "|" + { c'1^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/531df78c_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/531df78c_code.scd new file mode 100644 index 0000000..42b64ff --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/531df78c_code.scd @@ -0,0 +1,981 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/531df78c_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/531df78c_mus_model.json new file mode 100644 index 0000000..4f78cc2 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/531df78c_mus_model.json @@ -0,0 +1,157 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -6, 2, 4, 1, 1, 2 ], [ -5, 3, 4, 1, 1, 2 ], [ -6, 3, 4, 1, 1, 2 ], [ -6, 3, 4, 2, 1, 2 ] ], 1 ], + [ [ [ -7, 4, 4, 1, 1, 2 ], [ -5, 3, 4, 1, 1, 2 ], [ -6, 3, 4, 1, 1, 2 ], [ -6, 3, 4, 2, 1, 2 ] ], 1 ], + [ [ [ -7, 4, 4, 1, 1, 2 ], [ -5, 3, 4, 1, 1, 2 ], [ -6, 3, 4, 1, 1, 2 ], [ -5, 2, 4, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 3, 4, 0, 1, 2 ], [ -5, 3, 4, 1, 1, 2 ], [ -6, 3, 4, 1, 1, 2 ], [ -5, 2, 4, 1, 1, 2 ] ], 1 ], + [ [ [ -5, 3, 4, 0, 1, 2 ], [ -5, 3, 4, 1, 1, 2 ], [ -6, 3, 4, 1, 1, 2 ], [ -6, 4, 4, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 3, 4, 0, 1, 2 ], [ -4, 3, 4, 0, 1, 2 ], [ -6, 3, 4, 1, 1, 2 ], [ -6, 4, 4, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 3, 4, 0, 1, 2 ], [ -4, 3, 4, 0, 1, 2 ], [ -6, 3, 4, 1, 1, 2 ], [ -5, 3, 3, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 3, 4, 0, 1, 2 ], [ -5, 4, 3, 1, 1, 2 ], [ -6, 3, 4, 1, 1, 2 ], [ -5, 3, 3, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 4, 3, 1, 1, 2 ], [ -5, 4, 3, 1, 1, 2 ], [ -6, 3, 4, 1, 1, 2 ], [ -5, 3, 3, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 3, 4, 1, 1, 2 ], [ -5, 4, 3, 1, 1, 2 ], [ -6, 3, 4, 1, 1, 2 ], [ -5, 3, 3, 1, 1, 2 ] ], 1 ], + [ [ [ -5, 3, 4, 1, 1, 2 ], [ -6, 3, 3, 1, 1, 2 ], [ -6, 3, 4, 1, 1, 2 ], [ -5, 3, 3, 1, 1, 2 ] ], 1 ], + [ [ [ -5, 3, 4, 1, 1, 2 ], [ -6, 3, 3, 1, 1, 2 ], [ -5, 2, 3, 1, 1, 2 ], [ -5, 3, 3, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 3, 4, 1, 1, 2 ], [ -5, 2, 4, 1, 1, 2 ], [ -5, 2, 3, 1, 1, 2 ], [ -5, 3, 3, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 3, 4, 1, 1, 2 ], [ -5, 2, 4, 1, 1, 2 ], [ -6, 4, 3, 1, 1, 2 ], [ -5, 3, 3, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 3, 4, 1, 1, 2 ], [ -5, 2, 4, 1, 1, 2 ], [ -4, 1, 4, 1, 1, 2 ], [ -5, 3, 3, 1, 1, 2 ] ], 1 ], + [ [ [ -5, 4, 3, 1, 1, 2 ], [ -5, 2, 4, 1, 1, 2 ], [ -4, 1, 4, 1, 1, 2 ], [ -5, 3, 3, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 4, 3, 1, 1, 2 ], [ -5, 2, 4, 1, 1, 2 ], [ -4, 2, 3, 1, 1, 2 ], [ -5, 3, 3, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 4, 3, 1, 1, 2 ], [ -5, 2, 4, 1, 1, 2 ], [ -4, 2, 3, 1, 1, 2 ], [ -6, 5, 3, 1, 1, 2 ] ], 1 ], + [ [ [ -5, 4, 3, 1, 1, 2 ], [ -5, 4, 3, 0, 1, 2 ], [ -4, 2, 3, 1, 1, 2 ], [ -6, 5, 3, 1, 1, 2 ] ], 1 ], + [ [ [ -5, 4, 3, 1, 1, 2 ], [ -5, 4, 3, 0, 1, 2 ], [ -7, 5, 3, 1, 1, 2 ], [ -6, 5, 3, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 4, 3, 1, 1, 2 ], [ -5, 4, 3, 0, 1, 2 ], [ -7, 5, 3, 1, 1, 2 ], [ -5, 5, 3, 0, 1, 2 ] ], 1 ], + [ [ [ -5, 4, 3, 1, 1, 2 ], [ -6, 5, 2, 1, 1, 2 ], [ -7, 5, 3, 1, 1, 2 ], [ -5, 5, 3, 0, 1, 2 ] ], 1 ], + [ [ [ -6, 5, 3, 1, 1, 2 ], [ -6, 5, 2, 1, 1, 2 ], [ -7, 5, 3, 1, 1, 2 ], [ -5, 5, 3, 0, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 5, 3, 1, 1, 2 ], [ -6, 5, 2, 1, 1, 2 ], [ -6, 5, 3, 0, 1, 2 ], [ -5, 5, 3, 0, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 5, 3, 1, 1, 2 ], [ -6, 5, 2, 1, 1, 2 ], [ -6, 5, 3, 0, 1, 2 ], [ -6, 5, 4, 1, 1, 2 ] ], 1 ], + [ [ [ -6, 5, 3, 1, 1, 2 ], [ -6, 6, 3, 0, 1, 2 ], [ -6, 5, 3, 0, 1, 2 ], [ -6, 5, 4, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 4, 0, 1, 2 ], [ -6, 6, 3, 0, 1, 2 ], [ -6, 5, 3, 0, 1, 2 ], [ -6, 5, 4, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 4, 0, 1, 2 ], [ -6, 6, 3, 0, 1, 2 ], [ -6, 5, 4, 0, 1, 2 ], [ -6, 5, 4, 1, 1, 2 ] ], 1 ], + [ [ [ -6, 6, 4, 0, 1, 2 ], [ -7, 5, 4, 1, 1, 3 ], [ -6, 5, 4, 0, 1, 2 ], [ -6, 5, 4, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 5, 4, 0, 1, 3 ], [ -7, 5, 4, 1, 1, 3 ], [ -6, 5, 4, 0, 1, 2 ], [ -6, 5, 4, 1, 1, 2 ] ], 1 ], + [ [ [ -6, 5, 4, 0, 1, 3 ], [ -6, 6, 4, 0, 1, 2 ], [ -6, 5, 4, 0, 1, 2 ], [ -6, 5, 4, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 5, 4, 0, 1, 3 ], [ -6, 6, 4, 0, 1, 2 ], [ -6, 5, 4, 0, 1, 2 ], [ -6, 6, 5, 0, 1, 2 ] ], 1 ], + [ [ [ -7, 5, 4, 0, 1, 2 ], [ -6, 6, 4, 0, 1, 2 ], [ -6, 5, 4, 0, 1, 2 ], [ -6, 6, 5, 0, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 5, 4, 0, 1, 2 ], [ -6, 6, 4, 0, 1, 2 ], [ -7, 7, 4, 0, 1, 2 ], [ -6, 6, 5, 0, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 5, 4, 0, 1, 2 ], [ -6, 6, 4, 0, 1, 2 ], [ -7, 7, 4, 0, 1, 2 ], [ -7, 6, 4, 0, 1, 2 ] ], 1 ], + [ [ [ -7, 5, 4, 0, 1, 2 ], [ -6, 6, 4, 0, 1, 2 ], [ -7, 6, 4, 1, 1, 2 ], [ -7, 6, 4, 0, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 5, 4, 0, 1, 2 ], [ -6, 6, 4, 0, 1, 2 ], [ -5, 6, 4, -1, 1, 2 ], [ -7, 6, 4, 0, 1, 2 ] ], 1 ], + [ [ [ -8, 7, 4, 0, 1, 2 ], [ -6, 6, 4, 0, 1, 2 ], [ -5, 6, 4, -1, 1, 2 ], [ -7, 6, 4, 0, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 4, 0, 1, 2 ], [ -6, 6, 4, 0, 1, 2 ], [ -5, 6, 4, -1, 1, 2 ], [ -6, 7, 4, -1, 1, 2 ] ], 1 ], + [ [ [ -7, 7, 4, -1, 1, 2 ], [ -6, 6, 4, 0, 1, 2 ], [ -5, 6, 4, -1, 1, 2 ], [ -6, 7, 4, -1, 1, 2 ] ], 1 ], + [ [ [ -7, 7, 4, -1, 1, 2 ], [ -6, 6, 4, -1, 1, 2 ], [ -5, 6, 4, -1, 1, 2 ], [ -6, 7, 4, -1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 4, -1, 1, 2 ], [ -6, 6, 4, -1, 1, 2 ], [ -5, 6, 4, -1, 1, 2 ], [ -6, 7, 4, -1, 1, 2 ] ], 1 ], + [ [ [ -7, 6, 4, -1, 1, 2 ], [ -5, 6, 4, -1, 0, 2 ], [ -5, 6, 4, -1, 1, 2 ], [ -6, 7, 4, -1, 1, 2 ] ], 1 ], + [ [ [ -7, 6, 4, -1, 1, 2 ], [ -5, 6, 4, -1, 0, 2 ], [ -5, 6, 4, -1, 1, 2 ], [ -6, 6, 4, 0, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 4, -1, 1, 2 ], [ -5, 6, 4, -1, 0, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -6, 6, 4, 0, 1, 2 ] ], 1 ], + [ [ [ -7, 6, 4, -1, 1, 2 ], [ -6, 6, 5, 0, 1, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -6, 6, 4, 0, 1, 2 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -7, 6, 4, -1, 1, 2 ], [ -6, 6, 4, -1, 1, 2 ], [ -5, 6, 4, -1, 1, 2 ], [ -6, 7, 4, -1, 1, 2 ] ], + [ [ -7, 6, 4, -1, 1, 2 ], [ -5, 6, 4, -1, 0, 2 ], [ -5, 6, 4, -1, 1, 2 ], [ -6, 7, 4, -1, 1, 2 ] ], + [ [ -7, 6, 4, -1, 1, 2 ], [ -5, 6, 4, -1, 0, 2 ], [ -5, 6, 4, -1, 1, 2 ], [ -6, 6, 4, 0, 1, 2 ] ], + [ [ -7, 6, 4, -1, 1, 2 ], [ -5, 6, 4, -1, 0, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -6, 6, 4, 0, 1, 2 ] ], + [ [ -7, 6, 4, -1, 1, 2 ], [ -6, 6, 5, 0, 1, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -6, 6, 4, 0, 1, 2 ] ] +], +"cur_uid": "531df78c", +"ref_uid": "78a94ed1", +"order_seed": 561112, +"dur_seed": 221568, +"motifs_seed": 960151, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0061728395061728, 0.10227272727273, 0.074074074074074, 0.10227272727273, 0.2037037037037, 0.090909090909091, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 0.08, 0.47, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 2, 1 ], [ 0, 3 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 3, 1 ], [ 2, 0 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 0, 2 ], [ 3, 1 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 3, 0 ], [ 2, 1 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 3, 1 ], [ 2, 0 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 3, 0 ], [ 2, 1 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 25, 25.244897959184 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/lilypond/part_I.ly new file mode 100644 index 0000000..0acee0f --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/lilypond/part_I.ly @@ -0,0 +1,48 @@ +{ + { fis'1^\markup { \pad-markup #0.2 "+21"} } + \bar "|" + { d'1^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} } + \bar "|" + { e'1^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} } + \bar "|" + { f'1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'2 g'2^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { g'1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { a'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'2 c''2^\markup { \pad-markup #0.2 "-24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } + \bar "|" + { c''1 } + \bar "|" + { gis1^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { gis1 } + \bar "|" + { f'1^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'2 gis'2^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { gis'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/lilypond/part_II.ly new file mode 100644 index 0000000..71926a1 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/lilypond/part_II.ly @@ -0,0 +1,48 @@ +{ + { a1^\markup { \pad-markup #0.2 "-48"} ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a2 ais2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { ais2 c'2^\markup { \pad-markup #0.2 "-32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} } + \bar "|" + { fis'1^\markup { \pad-markup #0.2 "+48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} } + \bar "|" + { ais'1^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + \bar "|" + { ais'2 g2^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g2 a2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a2 cis'2^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'2 dis'2^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { dis'2 fis'2^\markup { \pad-markup #0.2 "-42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} } + \bar "|" + { ais'1^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 } + \bar "|" + { d'1^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/lilypond/part_III.ly new file mode 100644 index 0000000..95b2a0b --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/lilypond/part_III.ly @@ -0,0 +1,48 @@ +{ + { a'1^\markup { \pad-markup #0.2 "-48"} ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'2 b'2^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b'2 c''2^\markup { \pad-markup #0.2 "-32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } + \bar "|" + { c''1 } + \bar "|" + { f1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} } + \bar "|" + { d'1^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 } + \bar "|" + { d'1^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { d'2 dis'2^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'2 e'2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + \bar "|" + { e'1 } + \bar "|" + { g'1^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} } + \bar "|" + { gis'1^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 } + \bar "|" + { ais1^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + \bar "|" + { f'1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + \bar "|" + { f'2 c''2^\markup { \pad-markup #0.2 "-24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/lilypond/part_IV.ly new file mode 100644 index 0000000..52220bd --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/531df78c/lilypond/part_IV.ly @@ -0,0 +1,48 @@ +{ + { d2^\markup { \pad-markup #0.2 "-50"} e2^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { e2 b2^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 } + \bar "|" + { c'2^\markup { \pad-markup #0.2 "-32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} a'2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'2 c''2^\markup { \pad-markup #0.2 "-32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 } + \bar "|" + { g'1^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g'1 } + \bar "|" + { gis'1^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } + \bar "|" + { gis'2 a'2^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + \bar "|" + { a'1 } + \bar "|" + { cis1^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { cis1 ~ } + \bar "|" + { cis2 dis2^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { dis2 f2^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { f2 ais,2^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { ais,1 ~ } + \bar "|" + { ais,1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/553fbac7/553fbac7_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/553fbac7/553fbac7_code.scd new file mode 100644 index 0000000..c4e3d1b --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/553fbac7/553fbac7_code.scd @@ -0,0 +1,979 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/553fbac7/553fbac7_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/553fbac7/553fbac7_mus_model.json new file mode 100644 index 0000000..da17f28 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/553fbac7/553fbac7_mus_model.json @@ -0,0 +1,88 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ], [ "Rest" ] ], 1 ], + [ [ [ 0, 1, 1, 0, 0, 0 ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ], [ "Rest" ] ], 1 ], + [ [ [ 0, 1, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ "Rest" ] ], 1 ], + [ [ [ 0, 1, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -2, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 2, 1, -1, -1, -1, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 1 ], + [ [ [ -2, 1, 0, 0, 0, 0 ], [ 1, 1, -1, -1, -1, 0 ], [ 2, 1, -1, -1, -1, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 1, -1, -1, -1, 0 ], [ 1, 1, -1, -1, -1, 0 ], [ 2, 1, -1, -1, -1, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -2, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ] ], + [ [ -2, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], + [ [ -2, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 2, 1, -1, -1, -1, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], + [ [ -2, 1, 0, 0, 0, 0 ], [ 1, 1, -1, -1, -1, 0 ], [ 2, 1, -1, -1, -1, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], + [ [ 0, 1, -1, -1, -1, 0 ], [ 1, 1, -1, -1, -1, 0 ], [ 2, 1, -1, -1, -1, 0 ], [ 1, 1, -1, -1, 0, 0 ] ] +], +"cur_uid": "553fbac7", +"ref_uid": "4874dd07", +"order_seed": 846356, +"dur_seed": 787877, +"motifs_seed": 285247, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0061728395061728, 0.10227272727273, 0.074074074074074, 0.10227272727273, 0.2037037037037, 0.090909090909091, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 1, 0.47, 0.43, 1, 0.9 ], +"hd_exp": 9, +"hd_invert": 0, +"order": +[ + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 0, 3 ], [ 2, 1 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 10.061224489796, 10.091836734694 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/57ef90e6/57ef90e6_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/57ef90e6/57ef90e6_code.scd new file mode 100644 index 0000000..0d8c24b --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/57ef90e6/57ef90e6_code.scd @@ -0,0 +1,975 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/57ef90e6/57ef90e6_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/57ef90e6/57ef90e6_mus_model.json new file mode 100644 index 0000000..0f2fec3 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/57ef90e6/57ef90e6_mus_model.json @@ -0,0 +1,166 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1 ], + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 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 ] + ], + [ + [ [ [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 1, 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, 1, 0, 0, 0, -1 ], [ -1, 1, 0, 1, 0, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 1, 1, 0, 0, 0, -1 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ -1, 1, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ 1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ -2, 2, 0, 1, 1, 0 ] ], 1 ], + [ [ [ 1, 0, 0, 0, 0, 0 ], [ -1, 2, 0, 1, -1, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ -2, 2, 0, 1, 1, 0 ] ], 1 ], + [ [ [ -2, 2, 0, 2, 0, 0 ], [ -1, 2, 0, 1, -1, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ -2, 2, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 0, 2, 0, 0 ], [ -1, 2, 0, 1, -1, 0 ], [ -3, 3, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 0, 2, 0, 0 ], [ -1, 2, 0, 1, -1, 0 ], [ -3, 3, 0, 1, 1, 0 ], [ -1, 2, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -2, 2, 0, 2, 0, 0 ], [ -2, 3, 0, 1, 0, 0 ], [ -3, 3, 0, 1, 1, 0 ], [ -1, 2, 0, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 0, 2, 0, 0 ], [ -2, 3, 0, 1, 0, 0 ], [ -2, 2, 1, 1, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -2, 3, 0, 1, 0, 0 ], [ -2, 2, 1, 1, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -2, 2, 1, 1, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ -1, 2, 0, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -3, 2, 0, 1, 1, 0 ], [ -1, 2, 0, 1, 0, 0 ] ], 1 ], + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -1, 2, -1, 1, 0, 0 ], [ -3, 2, 0, 1, 1, 0 ], [ -1, 2, 0, 1, 0, -1 ] ], 1 ], + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -2, 2, 0, 1, 0, 1 ], [ -3, 2, 0, 1, 1, 0 ], [ -1, 2, 0, 1, 0, -1 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -1, 2, 0, 1, 1, -1 ], [ -3, 2, 0, 1, 1, 0 ], [ -1, 2, 0, 1, 0, -1 ] ], 1 ], + [ [ [ -3, 2, 0, 1, 0, 0 ], [ -1, 2, 0, 1, 1, -1 ], [ -3, 2, 0, 1, 1, 0 ], [ -1, 2, 0, 0, 1, 0 ] ], 1 ], + [ [ [ -2, 2, 0, 1, 1, -1 ], [ -1, 2, 0, 1, 1, -1 ], [ -3, 2, 0, 1, 1, 0 ], [ -1, 2, 0, 0, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 2, 0, 1, 1, -1 ], [ -1, 2, 0, 1, 1, -1 ], [ -3, 2, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ], + [ [ [ -2, 2, 0, 1, 1, -1 ], [ -1, 2, 0, 1, 0, 0 ], [ -3, 2, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 0, 1, 2, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ -3, 2, 0, 1, 1, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ], + [ [ [ -2, 1, 0, 1, 2, 0 ], [ -1, 2, 0, 1, 0, 0 ], [ -4, 3, 0, 1, 2, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ], + [ [ [ -2, 1, 0, 1, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ], [ -4, 3, 0, 1, 2, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ], [ -4, 3, 0, 1, 2, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 0, 0, 2, 0 ], [ -2, 3, 0, 0, 2, 0 ], [ -4, 3, 0, 1, 2, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ], + [ [ [ -3, 3, 0, 0, 2, 0 ], [ -2, 3, 0, 0, 2, 0 ], [ -4, 3, 0, 1, 2, 0 ], [ -2, 2, 0, 1, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 3, 0, 0, 2, 0 ], [ -2, 3, 0, 0, 2, 0 ], [ -4, 3, 0, 1, 2, 0 ], [ -1, 3, 0, 0, 2, -1 ] ], 1 ], + [ [ [ -3, 3, 0, 0, 2, 0 ], [ -2, 3, 1, 0, 2, 0 ], [ -4, 3, 0, 1, 2, 0 ], [ -1, 3, 0, 0, 2, -1 ] ], 1 ], + [ [ [ -3, 3, 0, 0, 2, 0 ], [ -2, 3, 1, 0, 2, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -1, 3, 0, 0, 2, -1 ] ], 1 ] + ], + [ + [ [ [ -3, 3, 0, 0, 2, 0 ], [ -4, 3, 0, 1, 1, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -1, 3, 0, 0, 2, -1 ] ], 1 ], + [ [ [ -3, 3, 0, 0, 1, 1 ], [ -4, 3, 0, 1, 1, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -1, 3, 0, 0, 2, -1 ] ], 1 ] + ], + [ + [ [ [ -3, 3, 0, 0, 1, 1 ], [ -2, 3, 0, 0, 0, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -1, 3, 0, 0, 2, -1 ] ], 1 ], + [ [ [ -3, 3, 0, 1, 1, 0 ], [ -2, 3, 0, 0, 0, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -1, 3, 0, 0, 2, -1 ] ], 1 ], + [ [ [ -3, 3, 0, 1, 1, 0 ], [ -2, 3, 0, 0, 0, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -2, 3, 0, 0, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 3, 0, 1, 0, 0 ], [ -2, 3, 0, 0, 0, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -2, 3, 0, 0, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 3, 0, 1, 0, 0 ], [ -2, 3, 0, 0, 0, 0 ], [ -2, 3, 0, 0, 1, 0 ], [ -1, 3, 0, 1, 0, -1 ] ], 1 ], + [ [ [ -2, 3, 0, 1, 0, 0 ], [ -2, 3, 0, 0, 0, 0 ], [ -1, 3, 0, 0, 0, 0 ], [ -1, 3, 0, 1, 0, -1 ] ], 1 ], + [ [ [ -2, 3, 0, 1, 0, 0 ], [ -2, 3, 0, 1, -1, 0 ], [ -1, 3, 0, 0, 0, 0 ], [ -1, 3, 0, 1, 0, -1 ] ], 1 ] + ], + [ + [ [ [ -1, 3, -1, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 0 ], [ -1, 3, 0, 0, 0, 0 ], [ -1, 3, 0, 1, 0, -1 ] ], 1 ], + [ [ [ -1, 3, -1, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 1 ], [ -1, 3, 0, 1, 0, -1 ] ], 1 ] + ], + [ + [ [ [ -1, 3, -1, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 1 ], [ -2, 3, 0, 2, -1, 0 ] ], 1 ], + [ [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 1 ], [ -2, 3, 0, 2, -1, 0 ] ], 1 ], + [ [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 0 ], [ -3, 4, 0, 1, -1, 0 ], [ -2, 3, 0, 2, -1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 4, 0, 1, -1, 0 ], [ -3, 4, 0, 1, -1, 0 ], [ -2, 3, 0, 2, -1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 4, 0, 1, -1, 0 ], [ -3, 4, 0, 1, -1, 0 ], [ 0, 3, -1, 0, -1, 0 ] ], 1 ], + [ [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 4, 0, 1, -1, 0 ], [ -2, 3, -1, 1, 0, 0 ], [ 0, 3, -1, 0, -1, 0 ] ], 1 ], + [ [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 4, 0, 1, -1, 0 ], [ "Rest" ], [ 0, 3, -1, 0, -1, 0 ] ], 1 ], + [ [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 4, 0, 1, -1, 0 ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ -2, 3, -1, 1, -1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3 ] + ] + ] +], +"last_changes": +[ + [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 1 ], [ -2, 3, 0, 2, -1, 0 ] ], + [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 3, 0, 1, -1, 0 ], [ -3, 4, 0, 1, -1, 0 ], [ -2, 3, 0, 2, -1, 0 ] ], + [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 4, 0, 1, -1, 0 ], [ -3, 4, 0, 1, -1, 0 ], [ -2, 3, 0, 2, -1, 0 ] ], + [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 4, 0, 1, -1, 0 ], [ -3, 4, 0, 1, -1, 0 ], [ 0, 3, -1, 0, -1, 0 ] ], + [ [ -2, 3, -1, 1, -1, 0 ], [ -2, 4, 0, 1, -1, 0 ], [ -2, 3, -1, 1, 0, 0 ], [ 0, 3, -1, 0, -1, 0 ] ] +], +"cur_uid": "57ef90e6", +"ref_uid": "nil", +"order_seed": 486941, +"dur_seed": 852979, +"motifs_seed": 409375, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0020576131687243, 0.068181818181818, 0.074074074074074, 0.0625, 0.20576131687243, 0.0625, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.78600823045268, 0.068181818181818, 0.98971193415638, 0.0625 ], +"passages_weights": [ 1, 1, 1, 1, 0.1 ], +"hd_exp": 1, +"hd_invert": 0, +"order": +[ + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 3 ], [ 2, 0, 1 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 2, 0 ], [ 3, 1 ], [ ] ], + [ [ 3 ], [ 2, 0, 1 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 2 ], [ 1, 3, 0 ], [ ] ], + [ [ 2, 0 ], [ 3, 1 ], [ ] ], + [ [ 3 ], [ 0, 2, 1 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 24.896551724138, 24.896551724138 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/615c4008/615c4008_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/615c4008/615c4008_code.scd new file mode 100644 index 0000000..070e09d --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/615c4008/615c4008_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/615c4008/615c4008_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/615c4008/615c4008_mus_model.json new file mode 100644 index 0000000..65a90eb --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/615c4008/615c4008_mus_model.json @@ -0,0 +1,267 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -8, 5, 2, 4, -2, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 6, 1, 4, -2, 2 ], [ -8, 5, 2, 4, -2, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 6, 1, 4, -2, 2 ], [ -8, 5, 2, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 6, 1, 4, -2, 2 ], [ -7, 4, 1, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 6, 1, 4, -2, 2 ], [ -8, 6, 1, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 6, 1, 4, -2, 2 ], [ -7, 5, 1, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 6, 1, 4, -2, 2 ], [ -8, 7, 1, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 6, 1, 4, -2, 2 ], [ -8, 7, 1, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -7, 7, 1, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 7, 1, 4, -2, 2 ], [ -8, 7, 1, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -7, 7, 1, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 1, 4, -2, 2 ], [ -7, 6, 0, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -7, 7, 1, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 1, 4, -2, 2 ], [ -7, 6, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 7, 1, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 7, 1, 4, -2, 2 ], [ -7, 6, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -6, 6, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -8, 6, 0, 4, -2, 2 ], [ -7, 6, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -6, 6, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 6, 0, 4, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -6, 6, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 4, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -6, 6, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 4, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -6, 7, 0, 3, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -6, 7, 0, 3, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 7, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -7, 7, 1, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 7, 0, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -7, 7, 1, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -7, 6, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 7, 1, 4, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -6, 6, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 8, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 8, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -2, 2 ], [ -7, 8, 0, 3, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 7, 0, 3, -2, 3 ], [ -7, 7, 0, 3, -2, 2 ], [ -7, 8, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 7, 0, 3, -2, 3 ], [ -7, 7, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -2, 3 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 7, 0, 3, -2, 3 ], [ -7, 7, 0, 3, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 7, 0, 3, -2, 3 ], [ -8, 7, 0, 3, -1, 3 ], [ -7, 7, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 7, 0, 3, -2, 3 ], [ -8, 7, 0, 3, -1, 3 ], [ -6, 7, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 7, 0, 3, -2, 3 ], [ -8, 7, 0, 3, -1, 3 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 7, 0, 3, -2, 3 ], [ -7, 7, 1, 3, -2, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -7, 7, 0, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -7, 7, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -7, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 7, 0, 3, -1, 3 ], [ -8, 8, 0, 3, -2, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 7, 0, 3, -1, 3 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -1, 3 ] ], 0.25 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 8, 0, 3, -2, 3 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -1, 3 ] ], 0.25 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 8, 0, 3, -2, 3 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 3, -2, 3 ] ], 0.25 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 8, 0, 4, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 3, -2, 3 ] ], 0.25 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -7, 8, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 3, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 8, 1, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 3, -2, 3 ] ], 0 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 8, 1, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -8, 8, -1, 3, -2, 2 ], [ -8, 8, 1, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -8, 8, -1, 3, -2, 2 ], [ -7, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 4, -2, 2 ], [ -7, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 4, -2, 1 ], [ -7, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.625 ], + [ [ [ -9, 8, 0, 4, -2, 1 ], [ -9, 8, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -10, 8, 0, 4, -2, 2 ], [ -9, 8, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -10, 8, 0, 4, -2, 2 ], [ -9, 9, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -10, 8, 0, 4, -2, 2 ], [ -8, 8, -1, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -10, 8, 0, 4, -2, 2 ], [ -8, 8, -1, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 0, 3, -2, 2 ], [ -8, 8, -1, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 3, -2, 2 ], [ -8, 8, -1, 4, -2, 2 ], [ -9, 9, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 3, -2, 2 ], [ -9, 8, 0, 4, -2, 2 ], [ -9, 9, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -9, 9, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -9, 9, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -9, 9, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -8, 8, -1, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 4, -2, 2 ], [ -7, 8, -1, 4, -2, 2 ], [ -8, 8, -1, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 8, -1, 4, -2, 2 ], [ -7, 8, -1, 4, -2, 2 ], [ -8, 8, -1, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, -1, 4, -2, 2 ], [ -7, 8, -1, 4, -2, 2 ], [ -9, 9, -1, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -7, 8, 0, 4, -3, 2 ], [ -7, 8, -1, 4, -2, 2 ], [ -9, 9, -1, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -7, 8, 0, 4, -3, 2 ], [ -7, 8, -1, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -7, 8, 0, 4, -3, 2 ], [ -7, 8, -1, 4, -2, 2 ], [ -8, 8, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 8, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -7, 8, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 8, -1, 4, -3, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 8, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 6, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -7, 8, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 6, 0, 4, -3, 2 ], [ -7, 6, 0, 4, -3, 2 ] ], 0.25 ], + [ [ [ -8, 6, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 6, 0, 4, -3, 2 ], [ -7, 6, 0, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 6, 0, 4, -3, 2 ], [ -7, 6, 0, 4, -3, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -7, 6, 0, 4, -3, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 7, -1, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 7, -1, 4, -3, 2 ], [ -7, 7, -1, 4, -3, 2 ] ], 0 ], + [ [ [ -8, 7, -1, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 7, -1, 4, -3, 2 ], [ -7, 7, -1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -8, 7, -1, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 7, -1, 4, -3, 2 ], [ -6, 7, 0, 3, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, -1, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 5, -3, 2 ], [ -6, 7, 0, 3, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 0, 5, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 5, -3, 2 ], [ -6, 7, 0, 3, -3, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 5, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 5, -3, 2 ], [ -6, 7, -1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 5, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 5, -3, 2 ], [ -8, 7, 0, 5, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 0, 5, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 7, 0, 4, -3, 2 ], [ -8, 7, 0, 5, -3, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 5, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 5, -3, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 5, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 5, -3, 2 ] ], 0 ], + [ [ [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 5, -3, 2 ] ], 0 ], + [ [ [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 9, 0, 4, -3, 2 ], [ -7, 8, -1, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -7, 8, -1, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 8, 1, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -9, 8, 1, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -9, 8, 1, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 3, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 3, -3, 2 ], [ -8, 9, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 3, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 1, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 6, 1, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -8, 6, 1, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -6, 6, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -8, 6, 1, 4, -3, 2 ], [ -7, 6, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -6, 6, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 6, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -6, 6, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -7, 7, 1, 4, -3, 2 ], [ -7, 6, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -6, 6, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -7, 7, 1, 4, -3, 2 ], [ -7, 6, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -7, 7, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -7, 7, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 7, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 8, 1, 3, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 8, 1, 3, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -8, 9, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 8, 1, 3, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 9, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -8, 8, 2, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 9, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 9, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 7, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 7, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -6, 7, 0, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 0, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -6, 7, 0, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 0, 4, -3, 2 ], [ -8, 7, 0, 4, -3, 2 ], [ -6, 7, 0, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 0, 4, -3, 2 ], [ -8, 7, 0, 4, -3, 2 ], [ -6, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 4, -3, 2 ], [ -6, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 4, -3, 2 ], [ -6, 7, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -7, 9, 0, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ -9, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ] ], + [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ] ], + [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ] ], + [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -7, 9, 0, 4, -3, 2 ] ], + [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ] ] +], +"cur_uid": "615c4008", +"ref_uid": "7276dc78", +"order_seed": 913894, +"dur_seed": 642726, +"motifs_seed": 376961, +"entrances_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"passages_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"exits_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1452.6315789474 ], [ -702, 1694.1176470588 ], [ -702, 1972.7554179567 ] ], +"step_probs_vals": [ -1200, 1200, 0.0041152263374486, 0.0056818181818179, 0.080246913580247, 0.02840909090909, 0.20781893004115, 0.028409090909091, 0.41152263374486, 0, 0.44650205761317, 0.16477272727273, 0.47736625514403, 0, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 0.58, 1, 0.43, 1, 0.82 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 3 ], [ 1, 0, 2, 1, 1, 1 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 1 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 0, 1, 3, 1 ], [ ] ], + [ [ 0, 2 ], [ 3, 1, 1, 3, 3, 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 1, 3, 3 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 3, 0 ], [ 2, 1, 2, 2, 1 ], [ ] ], + [ [ 2, 0 ], [ 3, 1, 3, 1, 1 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 1, 0, 0 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 0, 1, 1, 2 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 1, 1, 0 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 1, 3 ], [ 2, 0, 2, 2 ], [ ] ], + [ [ 0, 3 ], [ 1, 2 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 2, 3, 0, 3 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 3, 2, 2, 0 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 1, 0, 1, 1, 0 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 2, 1 ], [ ] ], + [ [ 1, 3 ], [ 0, 2, 0 ], [ ] ], + [ [ 2 ], [ 1, 3, 0 ], [ ] ], + [ [ 2 ], [ 0, 3, 1, 0, 0, 3, 1, 3 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 0, 1, 3 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 1, 1, 3, 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 2, 2, 0, 2 ], [ ] ], + [ [ 2 ], [ 0, 1, 3, 0 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 2, 3, 3 ], [ ] ] +], +"sus_weights": [ 0.69, 0.17, 0 ], +"order_size": [ 28.275510204082, 28.275510204082 ], +"passages_size": [ 0, 6 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/6522664c_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/6522664c_code.scd new file mode 100644 index 0000000..42b64ff --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/6522664c_code.scd @@ -0,0 +1,981 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/6522664c_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/6522664c_mus_model.json new file mode 100644 index 0000000..e6c59fc --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/6522664c_mus_model.json @@ -0,0 +1,85 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -4, 2, 2, 2, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 2, 2, 2, 1, 0 ], [ -3, 1, 1, 3, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -3, 1, 1, 2, 1, 0 ], [ -3, 1, 1, 3, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -3, 1, 1, 2, 1, 0 ], [ -3, 1, 1, 3, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 1, 2, 1, 0 ], [ -3, 1, 1, 3, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 1, 2, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 1, 2, 1, 0 ], [ -3, 1, 1, 3, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -3, 2, 1, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 1, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 1, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 1, 2, 1, 0 ], [ -3, 1, 3, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -2, 0, 2, 2, 1, 0 ], [ -3, 1, 3, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -2, 0, 2, 2, 1, 0 ], [ -3, 1, 3, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 2, 2, 1, 0 ], [ -3, 1, 3, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -3, 2, 2, 2, 1, 0 ], [ -3, 1, 3, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -4, 3, 2, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 2, 2, 1, 0 ], [ -5, 3, 1, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -4, 3, 2, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 2, 2, 1, 0 ], [ -5, 3, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -4, 3, 2, 2, 1, 0 ] ], 1 ], + [ [ [ -3, 2, 2, 2, 1, 0 ], [ -5, 3, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 2, 1, 2, 1, 0 ], [ -5, 3, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 3, 1, 2, 1, 0 ], [ -5, 3, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -3, 2, 2, 2, 1, 0 ], [ -5, 3, 1, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -4, 3, 2, 2, 1, 0 ] ], + [ [ -3, 2, 2, 2, 1, 0 ], [ -5, 3, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -4, 3, 2, 2, 1, 0 ] ], + [ [ -3, 2, 2, 2, 1, 0 ], [ -5, 3, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ], + [ [ -4, 2, 1, 2, 1, 0 ], [ -5, 3, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ], + [ [ -4, 3, 1, 2, 1, 0 ], [ -5, 3, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ] +], +"cur_uid": "6522664c", +"ref_uid": "4bf1af12", +"order_seed": 347999, +"dur_seed": 441379, +"motifs_seed": 667646, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0061728395061728, 0.10227272727273, 0.074074074074074, 0.10227272727273, 0.2037037037037, 0.090909090909091, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 1, 0.47, 0.43, 1, 0.8 ], +"hd_exp": 8, +"hd_invert": 0, +"order": +[ + [ [ 2, 0 ], [ 3, 1 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ], + [ [ 2, 0 ], [ 3, 1 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 2, 1 ], [ 0, 3 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 2 ], [ 1, 3, 0 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 10.091836734694, 10.091836734694 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/lilypond/part_I.ly new file mode 100644 index 0000000..aa8c464 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/lilypond/part_I.ly @@ -0,0 +1,20 @@ +{ + { g'1^\markup { \pad-markup #0.2 "-21"} ~ } + \bar "|" + { g'1 } + \bar "|" + { fis1^\markup { \pad-markup #0.2 "+26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} } + \bar "|" + { c'1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + \bar "|" + { e'1^\markup { \pad-markup #0.2 "-36"} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2 fis'2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { fis'1 } + \bar "|" + { g'1^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/lilypond/part_II.ly new file mode 100644 index 0000000..9007135 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/lilypond/part_II.ly @@ -0,0 +1,20 @@ +{ + { c''1^\markup { \pad-markup #0.2 "-23"} ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''2 b2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/lilypond/part_III.ly new file mode 100644 index 0000000..77f3a11 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/lilypond/part_III.ly @@ -0,0 +1,20 @@ +{ + { g2^\markup { \pad-markup #0.2 "-21"} e'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'2 b'2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { b'2 g'2^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'1 } + \bar "|" + { d2^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} fis2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { fis1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/lilypond/part_IV.ly new file mode 100644 index 0000000..49e5ac8 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6522664c/lilypond/part_IV.ly @@ -0,0 +1,20 @@ +{ + { b1^\markup { \pad-markup #0.2 "-34"} ~ } + \bar "|" + { b2 c'2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c'2 g'2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'2 g2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/6db2efcc_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/6db2efcc_code.scd new file mode 100644 index 0000000..42b64ff --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/6db2efcc_code.scd @@ -0,0 +1,981 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/6db2efcc_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/6db2efcc_mus_model.json new file mode 100644 index 0000000..d66bfdd --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/6db2efcc_mus_model.json @@ -0,0 +1,86 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -5, 2, 3, 3, 1, 0 ], [ -6, 2, 4, 3, 1, 0 ], [ -6, 3, 3, 4, 1, 0 ], [ -6, 2, 3, 4, 1, 0 ] ], 1 ], + [ [ [ -5, 2, 3, 3, 1, 0 ], [ -6, 2, 3, 3, 2, 0 ], [ -6, 3, 3, 4, 1, 0 ], [ -6, 2, 3, 4, 1, 0 ] ], 1 ], + [ [ [ -5, 2, 3, 3, 1, 0 ], [ -6, 2, 3, 3, 2, 0 ], [ -4, 1, 3, 3, 1, 0 ], [ -6, 2, 3, 4, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 2, 3, 3, 1, 0 ], [ -6, 2, 3, 3, 2, 0 ], [ -4, 1, 3, 3, 1, 0 ], [ -4, 2, 3, 3, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 2, 3, 3, 1, 0 ], [ -6, 2, 3, 3, 2, 0 ], [ -4, 1, 3, 3, 1, 0 ], [ -4, 2, 3, 2, 2, 0 ] ], 1 ], + [ [ [ -6, 2, 3, 4, 2, 0 ], [ -6, 2, 3, 3, 2, 0 ], [ -4, 1, 3, 3, 1, 0 ], [ -4, 2, 3, 2, 2, 0 ] ], 1 ], + [ [ [ -6, 2, 3, 4, 2, 0 ], [ -6, 2, 3, 3, 2, 0 ], [ -5, 2, 3, 3, 2, 0 ], [ -4, 2, 3, 2, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -6, 2, 3, 4, 2, 0 ], [ -6, 2, 3, 3, 2, 0 ], [ -4, 1, 3, 2, 2, 0 ], [ -4, 2, 3, 2, 2, 0 ] ], 1 ], + [ [ [ -4, 2, 2, 2, 2, 0 ], [ -6, 2, 3, 3, 2, 0 ], [ -4, 1, 3, 2, 2, 0 ], [ -4, 2, 3, 2, 2, 0 ] ], 1 ], + [ [ [ -4, 2, 2, 2, 2, 0 ], [ -5, 2, 3, 2, 2, 0 ], [ -4, 1, 3, 2, 2, 0 ], [ -4, 2, 3, 2, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 2, 3, 2, 2, 1 ], [ -5, 2, 3, 2, 2, 0 ], [ -4, 1, 3, 2, 2, 0 ], [ -4, 2, 3, 2, 2, 0 ] ], 1 ], + [ [ [ -5, 2, 3, 2, 2, 1 ], [ -5, 2, 3, 2, 2, 0 ], [ -3, 2, 3, 1, 2, 0 ], [ -4, 2, 3, 2, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 3, 1, 1, 0 ], [ -5, 2, 3, 2, 2, 0 ], [ -3, 2, 3, 1, 2, 0 ], [ -4, 2, 3, 2, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 3, 1, 1, 0 ], [ -5, 2, 3, 2, 2, 0 ], [ -3, 2, 3, 2, 2, -1 ], [ -4, 2, 3, 2, 2, 0 ] ], 1 ], + [ [ [ -3, 2, 3, 1, 1, 0 ], [ -5, 2, 3, 2, 2, 0 ], [ -3, 2, 3, 2, 2, -1 ], [ -3, 2, 4, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -3, 2, 3, 1, 1, 0 ], [ -5, 2, 3, 2, 2, 0 ], [ -5, 2, 4, 2, 1, 0 ], [ -3, 2, 4, 1, 1, 0 ] ], 1 ], + [ [ [ -3, 2, 3, 1, 1, 0 ], [ -3, 2, 4, 0, 1, 0 ], [ -5, 2, 4, 2, 1, 0 ], [ -3, 2, 4, 1, 1, 0 ] ], 1 ], + [ [ [ -4, 2, 4, 2, 1, 0 ], [ -3, 2, 4, 0, 1, 0 ], [ -5, 2, 4, 2, 1, 0 ], [ -3, 2, 4, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 2, 4, 2, 1, 0 ], [ -3, 2, 4, 0, 1, 0 ], [ -4, 2, 3, 2, 1, 0 ], [ -3, 2, 4, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -4, 2, 4, 2, 1, 0 ], [ -3, 2, 3, 2, 1, -1 ], [ -4, 2, 3, 2, 1, 0 ], [ -3, 2, 4, 1, 1, 0 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -3, 2, 3, 1, 1, 0 ], [ -5, 2, 3, 2, 2, 0 ], [ -5, 2, 4, 2, 1, 0 ], [ -3, 2, 4, 1, 1, 0 ] ], + [ [ -3, 2, 3, 1, 1, 0 ], [ -3, 2, 4, 0, 1, 0 ], [ -5, 2, 4, 2, 1, 0 ], [ -3, 2, 4, 1, 1, 0 ] ], + [ [ -4, 2, 4, 2, 1, 0 ], [ -3, 2, 4, 0, 1, 0 ], [ -5, 2, 4, 2, 1, 0 ], [ -3, 2, 4, 1, 1, 0 ] ], + [ [ -4, 2, 4, 2, 1, 0 ], [ -3, 2, 4, 0, 1, 0 ], [ -4, 2, 3, 2, 1, 0 ], [ -3, 2, 4, 1, 1, 0 ] ], + [ [ -4, 2, 4, 2, 1, 0 ], [ -3, 2, 3, 2, 1, -1 ], [ -4, 2, 3, 2, 1, 0 ], [ -3, 2, 4, 1, 1, 0 ] ] +], +"cur_uid": "6db2efcc", +"ref_uid": "521654f8", +"order_seed": 213803, +"dur_seed": 264333, +"motifs_seed": 980711, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0061728395061728, 0.10227272727273, 0.074074074074074, 0.10227272727273, 0.2037037037037, 0.090909090909091, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 1, 0.47, 0.43, 1, 0.5 ], +"hd_exp": 5, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 3 ], [ 2, 0, 1 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 10.091836734694, 10.091836734694 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/lilypond/part_I.ly new file mode 100644 index 0000000..90f111c --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/lilypond/part_I.ly @@ -0,0 +1,22 @@ +{ + { ais1^\markup { \pad-markup #0.2 "-11"} ~ } + \bar "|" + { ais2 g'2^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} } + \bar "|" + { gis'1^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/lilypond/part_II.ly new file mode 100644 index 0000000..88a941a --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/lilypond/part_II.ly @@ -0,0 +1,22 @@ +{ + { f'1^\markup { \pad-markup #0.2 "-9"} } + \bar "|" + { f'1^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { f'1 } + \bar "|" + { fis'2^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} cis'2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'2 ais'2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + \bar "|" + { ais'2 c''2^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }} ~ } + \bar "|" + { c''2 fis2^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } + \bar "|" + { fis1 } + \bar "|" + { dis'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/lilypond/part_III.ly new file mode 100644 index 0000000..898501b --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/lilypond/part_III.ly @@ -0,0 +1,22 @@ +{ + { e2^\markup { \pad-markup #0.2 "+7"} fis2^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis2 gis2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { gis1 ~ } + \bar "|" + { gis1 ~ } + \bar "|" + { gis1 } + \bar "|" + { b1^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} ~ } + \bar "|" + { b2 fis'2^\markup { \pad-markup #0.2 "+11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/lilypond/part_IV.ly new file mode 100644 index 0000000..6098652 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/6db2efcc/lilypond/part_IV.ly @@ -0,0 +1,22 @@ +{ + { c'1^\markup { \pad-markup #0.2 "+21"} ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'2 dis'2^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + \bar "|" + { dis'1 } + \bar "|" + { e'1^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} } + \bar "|" + { e'1^\markup { \pad-markup #0.2 "+44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }} } + \bar "|" + { f'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'2 fis'2^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { fis'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/7276dc78_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/7276dc78_code.scd new file mode 100644 index 0000000..42b64ff --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/7276dc78_code.scd @@ -0,0 +1,981 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/7276dc78_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/7276dc78_mus_model.json new file mode 100644 index 0000000..6d0340b --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/7276dc78_mus_model.json @@ -0,0 +1,158 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -7, 6, 4, -1, 1, 2 ], [ -5, 5, 4, 0, 0, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -6, 6, 4, 0, 1, 2 ] ], 1 ], + [ [ [ -6, 6, 4, -1, 0, 2 ], [ -5, 5, 4, 0, 0, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -6, 6, 4, 0, 1, 2 ] ], 1 ], + [ [ [ -6, 6, 4, -1, 0, 2 ], [ -5, 5, 4, 0, 0, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -7, 6, 5, 0, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 4, -1, 0, 2 ], [ -5, 6, 3, 0, 0, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -7, 6, 5, 0, 0, 2 ] ], 1 ], + [ [ [ -6, 6, 4, -1, 0, 2 ], [ -5, 6, 3, 0, 0, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -7, 6, 4, 1, 0, 2 ] ], 1 ], + [ [ [ -6, 6, 3, 0, 0, 2 ], [ -5, 6, 3, 0, 0, 2 ], [ -6, 6, 4, 0, 0, 2 ], [ -7, 6, 4, 1, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 3, 0, 0, 2 ], [ -5, 6, 3, 0, 0, 2 ], [ -5, 6, 2, 0, 0, 2 ], [ -7, 6, 4, 1, 0, 2 ] ], 1 ], + [ [ [ -6, 6, 3, 0, 0, 2 ], [ -5, 6, 3, 0, 0, 2 ], [ -5, 6, 2, 0, 0, 2 ], [ -6, 7, 3, 0, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 3, 0, 0, 2 ], [ -5, 6, 2, -1, 0, 2 ], [ -5, 6, 2, 0, 0, 2 ], [ -6, 7, 3, 0, 0, 2 ] ], 1 ], + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -5, 6, 2, -1, 0, 2 ], [ -5, 6, 2, 0, 0, 2 ], [ -6, 7, 3, 0, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -5, 6, 2, -1, 0, 2 ], [ -6, 7, 2, 1, 0, 2 ], [ -6, 7, 3, 0, 0, 2 ] ], 1 ], + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -6, 7, 2, 1, 0, 2 ], [ -6, 7, 3, 0, 0, 2 ] ], 1 ], + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -6, 7, 2, 1, 0, 2 ], [ -5, 6, 2, 1, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -5, 6, 2, 1, -1, 1 ], [ -5, 6, 2, 1, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -6, 6, 2, 2, -1, 2 ], [ -5, 6, 2, 1, -1, 2 ] ], 1 ], + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -6, 6, 2, 2, -1, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 2, 1, 0, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -7, 5, 2, 3, 0, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ], + [ [ [ -8, 6, 2, 2, 0, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -7, 5, 2, 3, 0, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ], + [ [ [ -8, 6, 2, 2, 0, 2 ], [ -7, 5, 2, 2, -1, 2 ], [ -7, 5, 2, 3, 0, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 2, 2, -1, 2 ], [ -7, 5, 2, 2, -1, 2 ], [ -7, 5, 2, 3, 0, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 2, 2, -1, 2 ], [ -7, 5, 2, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ], + [ [ [ -7, 6, 2, 2, -1, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 2, 2, -1, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -7, 5, 2, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 2, 2, -1, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 2, 2, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 2, 2, -1, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 6, 2, 2, -1, 2 ] ], 1 ], + [ [ [ -6, 5, 1, 2, 0, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 6, 2, 2, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 5, 1, 2, 0, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -5, 5, 0, 2, 0, 2 ], [ -6, 6, 2, 2, -1, 2 ] ], 1 ], + [ [ [ -6, 5, 1, 2, 0, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -5, 5, 0, 2, 0, 2 ], [ -6, 6, 1, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 5, 1, 2, 0, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -6, 6, 1, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 5, 1, 3, -1, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -7, 6, 2, 2, 0, 2 ], [ -6, 6, 1, 2, 0, 2 ] ], 1 ], + [ [ [ -6, 5, 1, 3, -1, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 5, 1, 2, -2, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 5, 1, 2, -2, 2 ], [ -5, 5, 1, 2, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ], + [ [ [ -7, 5, 1, 2, -2, 2 ], [ -7, 5, 1, 3, -2, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ], + [ [ [ -7, 5, 1, 2, -1, 2 ], [ -7, 5, 1, 3, -2, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 5, 1, 2, -1, 2 ], [ -7, 5, 1, 3, -2, 2 ], [ -5, 5, 1, 1, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ], + [ [ [ -6, 5, 1, 2, -2, 2 ], [ -7, 5, 1, 3, -2, 2 ], [ -5, 5, 1, 1, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ], + [ [ [ -6, 5, 1, 2, -2, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -5, 5, 1, 1, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 5, 0, 3, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -5, 5, 1, 1, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ], + [ [ [ -8, 5, 0, 3, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 1, 2, -2, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 2, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 1, 2, -2, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 4, 1, 3, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ] ], 1 ], + [ [ [ -8, 4, 1, 3, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 1 ], + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -2, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -8, 4, 1, 3, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ] ], + [ [ -8, 4, 1, 3, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 3, -1, 2 ] ], + [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 3, -1, 2 ] ], + [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 3, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], + [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -2, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 4, -2, 2 ] ] +], +"cur_uid": "7276dc78", +"ref_uid": "531df78c", +"order_seed": 350501, +"dur_seed": 664373, +"motifs_seed": 429600, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.069958847736626, 0, 0.31481481481481, 0, 0.38271604938272, 0.13068181818182, 0.45884773662551, 0.14772727272727, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.79218106995885, 0, 1, 0 ], +"passages_weights": [ 1, 0.47, 0.43, 1, 0.45 ], +"hd_exp": 3.87, +"hd_invert": 0, +"order": +[ + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 2 ], [ 1, 3, 0 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 3 ], [ 2, 0, 1 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 3, 0 ], [ 2, 1 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 3 ], [ 2, 0, 1 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 1, 2 ], [ 0, 3 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 2, 0 ], [ 3, 1 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 25.244897959184, 25.244897959184 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/lilypond/part_I.ly new file mode 100644 index 0000000..af7f26d --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/lilypond/part_I.ly @@ -0,0 +1,48 @@ +{ + { gis'1^\markup { \pad-markup #0.2 "-11"} } + \bar "|" + { fis1^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} } + \bar "|" + { c'1^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + \bar "|" + { c'2 fis'2^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + \bar "|" + { b'2 g2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g2 cis'2^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a'2 ais'2^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 } + \bar "|" + { ais1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais2 d'2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { d'2 g'2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g'2 b'2^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/lilypond/part_II.ly new file mode 100644 index 0000000..b3e65e4 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/lilypond/part_II.ly @@ -0,0 +1,48 @@ +{ + { d'1^\markup { \pad-markup #0.2 "+38"} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 } + \bar "|" + { g'1^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { g'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { b'2 d'2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }} } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} } + \bar "|" + { f'1^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } + \bar "|" + { f'1 } + \bar "|" + { f'1^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} } + \bar "|" + { d'1^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} } + \bar "|" + { g1^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g2 c'2^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'2 f'2^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/lilypond/part_III.ly new file mode 100644 index 0000000..192a5db --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/lilypond/part_III.ly @@ -0,0 +1,48 @@ +{ + { g'1^\markup { \pad-markup #0.2 "+36"} ~ } + \bar "|" + { g'2 b'2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 } + \bar "|" + { a1^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } + \bar "|" + { a2 d'2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 } + \bar "|" + { cis1^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }} ~ } + \bar "|" + { cis2 dis'2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} } + \bar "|" + { ais'1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'2 d2^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d2 g2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/lilypond/part_IV.ly new file mode 100644 index 0000000..5fd805f --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7276dc78/lilypond/part_IV.ly @@ -0,0 +1,48 @@ +{ + { ais,2^\markup { \pad-markup #0.2 "+21"} f2^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f2 b2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b2 e'2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2 d2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { d2 a2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a2 dis'2^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'2 g'2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + \bar "|" + { g'2 e,2^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } + \bar "|" + { e,1 } + \bar "|" + { ais,1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} } + \bar "|" + { e1^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} } + \bar "|" + { dis,1^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} } + \bar "|" + { b,1^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} } + \bar "|" + { c,1^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} } + \bar "|" + { f,1^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/78a94ed1_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/78a94ed1_code.scd new file mode 100644 index 0000000..42b64ff --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/78a94ed1_code.scd @@ -0,0 +1,981 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/78a94ed1_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/78a94ed1_mus_model.json new file mode 100644 index 0000000..078670e --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/78a94ed1_mus_model.json @@ -0,0 +1,90 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -6, 1, 5, 1, 0, 2 ], [ -5, 1, 4, 2, 0, 2 ], [ -5, 1, 5, 2, 0, 2 ], [ -4, 2, 5, 1, 0, 2 ] ], 1 ], + [ [ [ -6, 1, 5, 1, 0, 2 ], [ -5, 1, 4, 2, 0, 2 ], [ -3, 0, 5, 1, 0, 2 ], [ -4, 2, 5, 1, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 1, 5, 1, 0, 2 ], [ -5, 1, 4, 2, 0, 2 ], [ -3, 0, 5, 1, 0, 2 ], [ -4, 1, 5, 1, 0, 2 ] ], 1 ], + [ [ [ -6, 1, 5, 1, 0, 2 ], [ -5, 1, 4, 2, 0, 2 ], [ -4, 2, 5, 1, 0, 2 ], [ -4, 1, 5, 1, 0, 2 ] ], 1 ], + [ [ [ -6, 1, 5, 1, 0, 2 ], [ -5, 2, 5, 1, 0, 2 ], [ -4, 2, 5, 1, 0, 2 ], [ -4, 1, 5, 1, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 1, 5, 1, 0, 2 ], [ -5, 2, 5, 1, 0, 2 ], [ -5, 1, 6, 1, 0, 2 ], [ -4, 1, 5, 1, 0, 2 ] ], 1 ], + [ [ [ -6, 1, 5, 1, 0, 2 ], [ -4, 1, 4, 1, 0, 2 ], [ -5, 1, 6, 1, 0, 2 ], [ -4, 1, 5, 1, 0, 2 ] ], 1 ], + [ [ [ -6, 1, 5, 1, 0, 2 ], [ -4, 1, 4, 1, 0, 2 ], [ -5, 1, 6, 1, 0, 2 ], [ -4, 2, 5, 1, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 1, 5, 1, 0, 2 ], [ -4, 1, 4, 1, 0, 2 ], [ -5, 2, 5, 1, 0, 2 ], [ -4, 2, 5, 1, 0, 2 ] ], 1 ], + [ [ [ -6, 1, 5, 1, 0, 2 ], [ -4, 2, 4, 1, 0, 2 ], [ -5, 2, 5, 1, 0, 2 ], [ -4, 2, 5, 1, 0, 2 ] ], 1 ], + [ [ [ -7, 2, 5, 1, 1, 2 ], [ -4, 2, 4, 1, 0, 2 ], [ -5, 2, 5, 1, 0, 2 ], [ -4, 2, 5, 1, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 2, 5, 1, 1, 2 ], [ -4, 2, 4, 1, 0, 2 ], [ -5, 2, 5, 1, 0, 2 ], [ -5, 1, 5, 1, 1, 2 ] ], 1 ], + [ [ [ -7, 2, 5, 1, 1, 2 ], [ -4, 2, 4, 1, 0, 2 ], [ -4, 1, 4, 1, 0, 2 ], [ -5, 1, 5, 1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 2, 5, 1, 1, 2 ], [ -4, 2, 4, 1, 0, 2 ], [ -4, 1, 4, 1, 0, 2 ], [ -3, 1, 4, 0, 0, 2 ] ], 1 ], + [ [ [ -6, 2, 5, 1, 0, 2 ], [ -4, 2, 4, 1, 0, 2 ], [ -4, 1, 4, 1, 0, 2 ], [ -3, 1, 4, 0, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 2, 4, 1, 1, 2 ], [ -4, 2, 4, 1, 0, 2 ], [ -4, 1, 4, 1, 0, 2 ], [ -3, 1, 4, 0, 0, 2 ] ], 1 ], + [ [ [ -6, 2, 4, 1, 1, 2 ], [ -4, 2, 4, 1, 0, 2 ], [ -4, 1, 4, 1, 0, 2 ], [ -3, 2, 4, 0, 0, 2 ] ], 1 ], + [ [ [ -6, 2, 4, 1, 1, 2 ], [ -4, 2, 4, 1, 0, 2 ], [ -5, 3, 4, 1, 0, 2 ], [ -3, 2, 4, 0, 0, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 2, 4, 1, 1, 2 ], [ -4, 2, 4, 1, 0, 2 ], [ -5, 3, 4, 1, 0, 2 ], [ -5, 2, 4, 2, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 2, 4, 1, 1, 2 ], [ -4, 2, 4, 1, 0, 2 ], [ -5, 3, 4, 1, 0, 2 ], [ -6, 2, 4, 2, 1, 2 ] ], 1 ], + [ [ [ -6, 2, 4, 1, 1, 2 ], [ -5, 3, 4, 1, 1, 2 ], [ -5, 3, 4, 1, 0, 2 ], [ -6, 2, 4, 2, 1, 2 ] ], 1 ], + [ [ [ -6, 2, 4, 1, 1, 2 ], [ -5, 3, 4, 1, 1, 2 ], [ -5, 2, 4, 1, 1, 3 ], [ -6, 2, 4, 2, 1, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 2, 4, 1, 1, 2 ], [ -5, 3, 4, 1, 1, 2 ], [ -5, 2, 4, 2, 1, 2 ], [ -6, 2, 4, 2, 1, 2 ] ], 1 ], + [ [ [ -6, 2, 4, 1, 1, 2 ], [ -5, 3, 4, 1, 1, 2 ], [ -5, 2, 4, 2, 1, 2 ], [ -6, 3, 4, 2, 1, 2 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -6, 2, 4, 1, 1, 2 ], [ -4, 2, 4, 1, 0, 2 ], [ -5, 3, 4, 1, 0, 2 ], [ -6, 2, 4, 2, 1, 2 ] ], + [ [ -6, 2, 4, 1, 1, 2 ], [ -5, 3, 4, 1, 1, 2 ], [ -5, 3, 4, 1, 0, 2 ], [ -6, 2, 4, 2, 1, 2 ] ], + [ [ -6, 2, 4, 1, 1, 2 ], [ -5, 3, 4, 1, 1, 2 ], [ -5, 2, 4, 1, 1, 3 ], [ -6, 2, 4, 2, 1, 2 ] ], + [ [ -6, 2, 4, 1, 1, 2 ], [ -5, 3, 4, 1, 1, 2 ], [ -5, 2, 4, 2, 1, 2 ], [ -6, 2, 4, 2, 1, 2 ] ], + [ [ -6, 2, 4, 1, 1, 2 ], [ -5, 3, 4, 1, 1, 2 ], [ -5, 2, 4, 2, 1, 2 ], [ -6, 3, 4, 2, 1, 2 ] ] +], +"cur_uid": "78a94ed1", +"ref_uid": "4e9f1dcc", +"order_seed": 418736, +"dur_seed": 167372, +"motifs_seed": 741164, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0061728395061728, 0.10227272727273, 0.074074074074074, 0.10227272727273, 0.2037037037037, 0.090909090909091, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 1, 0.47, 0.43, 1, 0.2 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 1, 2 ], [ 3, 0 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 10.091836734694, 10.091836734694 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/lilypond/part_I.ly new file mode 100644 index 0000000..cf060ff --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/lilypond/part_I.ly @@ -0,0 +1,26 @@ +{ + { c''1^\markup { \pad-markup #0.2 "-15"} } + \bar "|" + { f'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'2 c''2^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''2 ais2^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { ais2 dis'2^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } + \bar "|" + { dis'1 } + \bar "|" + { ais'1^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} } + \bar "|" + { b'2^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} b2^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b2 fis'2^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/lilypond/part_II.ly new file mode 100644 index 0000000..9712ce1 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/lilypond/part_II.ly @@ -0,0 +1,26 @@ +{ + { dis'2^\markup { \pad-markup #0.2 "-48"} ais'2^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { ais'2 c''2^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { c''2 a2^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { a1 } + \bar "|" + { c'1^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c'1 } + \bar "|" + { cis'1^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'2 dis'2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'2 ais'2^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/lilypond/part_III.ly new file mode 100644 index 0000000..4950731 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/lilypond/part_III.ly @@ -0,0 +1,26 @@ +{ + { b1^\markup { \pad-markup #0.2 "-34"} ~ } + \bar "|" + { b1 } + \bar "|" + { c'1^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + \bar "|" + { cis'1^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { cis'2 gis'2^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { a'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/lilypond/part_IV.ly new file mode 100644 index 0000000..f5a6564 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/78a94ed1/lilypond/part_IV.ly @@ -0,0 +1,26 @@ +{ + { f,1^\markup { \pad-markup #0.2 "-17"} ~ } + \bar "|" + { f,1 ~ } + \bar "|" + { f,1 ~ } + \bar "|" + { f,1 ~ } + \bar "|" + { f,1 } + \bar "|" + { f,1^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↑" }} ~ } + \bar "|" + { f,1 } + \bar "|" + { c2^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} d2^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/7c30c182_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/7c30c182_code.scd new file mode 100644 index 0000000..42b64ff --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/7c30c182_code.scd @@ -0,0 +1,981 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/7c30c182_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/7c30c182_mus_model.json new file mode 100644 index 0000000..f796261 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/7c30c182_mus_model.json @@ -0,0 +1,271 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -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 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 1 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 0, -1, -1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, -1, -1, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 0, -1, 0, -1, 0 ], [ 1, -1, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 0, -1, 0, -1, 0 ], [ 1, -1, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, -1, 0, -1, 0 ], [ 1, -1, -1, 0, 0, 0 ], [ 2, 0, -1, 0, -2, 0 ], [ 0, 0, -1, 1, 0, 0 ] ], 1 ], + [ [ [ 0, 0, -1, 0, -1, 0 ], [ 1, 0, -1, 0, -1, 0 ], [ 2, 0, -1, 0, -2, 0 ], [ 0, 0, -1, 1, 0, 0 ] ], 1 ], + [ [ [ 0, 0, -1, 0, -1, 0 ], [ 1, 0, -1, 0, -1, 0 ], [ 2, 0, -1, 0, -2, 0 ], [ 2, -1, -1, 0, -1, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, -1, 0, -1, 0 ], [ 1, 0, -1, 0, -1, 0 ], [ 2, 0, -2, 0, -1, 0 ], [ 2, -1, -1, 0, -1, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, -2, 0, 0, 0 ], [ 1, 0, -1, 0, -1, 0 ], [ 2, 0, -2, 0, -1, 0 ], [ 2, -1, -1, 0, -1, 0 ] ], 1 ], + [ [ [ 0, 0, -2, 0, 0, 0 ], [ 2, -1, -2, 0, -1, 0 ], [ 2, 0, -2, 0, -1, 0 ], [ 2, -1, -1, 0, -1, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, -2, 0, 0, 0 ], [ 2, -1, -2, 0, -1, 0 ], [ 3, -1, -3, 0, -1, 0 ], [ 2, -1, -1, 0, -1, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, -2, 0, 0, 0 ], [ 1, 0, -2, 0, 1, 0 ], [ 3, -1, -3, 0, -1, 0 ], [ 2, -1, -1, 0, -1, 0 ] ], 1 ], + [ [ [ 0, 0, -2, 0, 0, 0 ], [ 1, 0, -2, 0, 1, 0 ], [ 3, -1, -3, 0, -1, 0 ], [ 2, -1, -2, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 0, -2, 0, 0, 0 ], [ 1, 0, -2, 0, 1, 0 ], [ 0, 0, -2, 1, 0, 0 ], [ 2, -1, -2, 0, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, -2, 0, 0, 0 ], [ 1, 0, -2, 0, 1, 0 ], [ 0, 0, -2, 1, 0, 0 ], [ 1, 0, -3, 1, 0, 0 ] ], 1 ], + [ [ [ 0, 0, -3, 0, 1, 0 ], [ 1, 0, -2, 0, 1, 0 ], [ 0, 0, -2, 1, 0, 0 ], [ 1, 0, -3, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, -3, 0, 1, 0 ], [ 2, -1, -3, 0, 1, 0 ], [ 0, 0, -2, 1, 0, 0 ], [ 1, 0, -3, 1, 0, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, -3, 0, 1, 0 ], [ 2, -1, -3, 0, 1, 0 ], [ 0, 0, -3, 1, 1, 0 ], [ 1, 0, -3, 1, 0, 0 ] ], 1 ], + [ [ [ 0, 0, -3, 0, 1, 0 ], [ 2, -1, -3, 0, 1, 0 ], [ 0, 0, -3, 1, 1, 0 ], [ 1, 0, -3, 0, 2, 0 ] ], 1 ], + [ [ [ 0, 0, -3, 0, 1, 0 ], [ 0, 0, -2, 0, 1, 0 ], [ 0, 0, -3, 1, 1, 0 ], [ 1, 0, -3, 0, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, -3, 0, 1, 0 ], [ 0, 0, -2, 0, 1, 0 ], [ 0, 0, -3, 1, 1, 0 ], [ 1, 0, -3, 0, 1, 0 ] ], 1 ], + [ [ [ 0, 0, -3, 0, 1, 0 ], [ 0, 0, -2, 0, 1, 0 ], [ 1, 0, -3, 0, 2, 0 ], [ 1, 0, -3, 0, 1, 0 ] ], 1 ], + [ [ [ 0, 0, -3, 0, 1, 0 ], [ 1, -1, -3, 0, 1, 0 ], [ 1, 0, -3, 0, 2, 0 ], [ 1, 0, -3, 0, 1, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, -3, 0, 1, 0 ], [ 1, -1, -3, 0, 1, 0 ], [ 2, -1, -3, 0, 1, 0 ], [ 1, 0, -3, 0, 1, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, -3, 0, 1, 0 ], [ 1, -1, -3, 0, 1, 0 ], [ 2, -1, -3, 0, 1, 0 ], [ 2, -1, -4, 0, 1, 0 ] ], 1 ], + [ [ [ 0, 0, -3, 0, 1, 0 ], [ 1, -1, -3, 0, 1, 0 ], [ 1, -1, -3, 1, 1, 0 ], [ 2, -1, -4, 0, 1, 0 ] ], 1 ] + ], + [ + [ [ [ 0, 0, -3, 0, 1, 0 ], [ 2, -2, -4, 0, 1, 0 ], [ 1, -1, -3, 1, 1, 0 ], [ 2, -1, -4, 0, 1, 0 ] ], 1 ] + ], + [ + [ [ [ 1, -1, -4, 0, 1, 0 ], [ 2, -2, -4, 0, 1, 0 ], [ 1, -1, -3, 1, 1, 0 ], [ 2, -1, -4, 0, 1, 0 ] ], 1 ], + [ [ [ 1, -1, -4, 0, 1, 0 ], [ 1, -2, -3, 1, 1, 0 ], [ 1, -1, -3, 1, 1, 0 ], [ 2, -1, -4, 0, 1, 0 ] ], 1 ] + ], + [ + [ [ [ 1, -1, -4, 0, 1, 0 ], [ 2, -1, -5, 0, 1, 0 ], [ 1, -1, -3, 1, 1, 0 ], [ 2, -1, -4, 0, 1, 0 ] ], 1 ] + ], + [ + [ [ [ 1, -1, -4, 0, 1, 0 ], [ 2, -1, -5, 0, 1, 0 ], [ 1, -1, -3, 1, 1, 0 ], [ 2, -1, -5, 0, 2, 0 ] ], 1 ], + [ [ [ 1, -1, -4, 0, 1, 0 ], [ 2, -1, -5, 0, 1, 0 ], [ 3, -1, -5, 0, 0, 0 ], [ 2, -1, -5, 0, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 2, -2, -5, 0, 1, 0 ], [ 2, -1, -5, 0, 1, 0 ], [ 3, -1, -5, 0, 0, 0 ], [ 2, -1, -5, 0, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 2, -2, -5, 0, 1, 0 ], [ 2, -1, -5, 0, 1, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 2, -1, -5, 0, 2, 0 ] ], 1 ], + [ [ [ 2, -2, -5, 0, 1, 0 ], [ 2, -1, -6, 0, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 2, -1, -5, 0, 2, 0 ] ], 1 ], + [ [ [ -1, -1, -5, 0, 3, 0 ], [ 2, -1, -6, 0, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 2, -1, -5, 0, 2, 0 ] ], 1 ] + ], + [ + [ [ [ -1, -1, -5, 0, 3, 0 ], [ 2, -1, -6, 0, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 1, 0, -5, -1, 2, 0 ] ], 1 ], + [ [ [ 1, -2, -5, -1, 2, 0 ], [ 2, -1, -6, 0, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 1, 0, -5, -1, 2, 0 ] ], 1 ], + [ [ [ 1, -2, -5, -1, 2, 0 ], [ 2, 0, -5, -1, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 1, 0, -5, -1, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 1, -1, -5, -1, 1, 0 ], [ 2, 0, -5, -1, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 1, 0, -5, -1, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 1, -1, -5, -1, 1, 0 ], [ 2, 0, -5, -1, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 1, -1, -5, -1, 2, 1 ] ], 1 ] + ], + [ + [ [ [ 1, -1, -5, -1, 1, 0 ], [ 3, -1, -6, -1, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 1, -1, -5, -1, 2, 1 ] ], 1 ], + [ [ [ 1, -1, -6, -1, 2, 0 ], [ 3, -1, -6, -1, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 1, -1, -5, -1, 2, 1 ] ], 1 ] + ], + [ + [ [ [ 0, -1, -5, 0, 2, 0 ], [ 3, -1, -6, -1, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 1, -1, -5, -1, 2, 1 ] ], 1 ], + [ [ [ 0, -1, -5, 0, 2, 0 ], [ 2, -1, -5, 0, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 1, -1, -5, -1, 2, 1 ] ], 1 ] + ], + [ + [ [ [ 0, -1, -5, 0, 2, 0 ], [ 2, -1, -5, 0, 2, 0 ], [ 2, -2, -5, -1, 2, 1 ], [ 1, -1, -5, -1, 2, 1 ] ], 1 ], + [ [ [ 0, -1, -5, 0, 2, 0 ], [ 3, -1, -5, -2, 2, 1 ], [ 2, -2, -5, -1, 2, 1 ], [ 1, -1, -5, -1, 2, 1 ] ], 1 ] + ], + [ + [ [ [ 0, -1, -5, 0, 2, 0 ], [ 3, -1, -5, -2, 2, 1 ], [ 2, -1, -5, -1, 1, 1 ], [ 1, -1, -5, -1, 2, 1 ] ], 1 ], + [ [ [ 0, -1, -5, 0, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 2, -1, -5, -1, 1, 1 ], [ 1, -1, -5, -1, 2, 1 ] ], 1 ] + ], + [ + [ [ [ 0, -1, -5, 0, 2, 0 ], [ 2, -1, -5, 0, 1, 1 ], [ 2, -1, -5, -1, 1, 1 ], [ 1, -1, -5, -1, 2, 1 ] ], 1 ], + [ [ [ 0, -1, -5, 0, 2, 0 ], [ 2, -1, -5, 0, 1, 1 ], [ 2, -1, -5, -1, 1, 1 ], [ 2, -1, -5, -1, 0, 1 ] ], 1 ] + ], + [ + [ [ [ 0, -1, -5, 0, 2, 0 ], [ 3, -1, -6, -1, 1, 1 ], [ 2, -1, -5, -1, 1, 1 ], [ 2, -1, -5, -1, 0, 1 ] ], 1 ] + ], + [ + [ [ [ 0, -1, -5, 0, 2, 0 ], [ 3, -1, -6, -1, 1, 1 ], [ 2, -1, -5, -1, 1, 1 ], [ 2, -1, -6, -1, 1, 1 ] ], 1 ] + ], + [ + [ [ [ 0, -1, -5, 0, 2, 0 ], [ 3, -1, -6, -1, 1, 1 ], [ 3, -2, -6, -1, 1, 1 ], [ 2, -1, -6, -1, 1, 1 ] ], 1 ], + [ [ [ 0, -1, -5, 0, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 3, -2, -6, -1, 1, 1 ], [ 2, -1, -6, -1, 1, 1 ] ], 1 ] + ], + [ + [ [ [ 0, -1, -5, 0, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 3, -2, -6, -1, 1, 1 ], [ 2, -2, -6, -1, 1, 2 ] ], 1 ] + ], + [ + [ [ [ 1, 0, -5, -1, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 3, -2, -6, -1, 1, 1 ], [ 2, -2, -6, -1, 1, 2 ] ], 1 ], + [ [ [ 1, 0, -5, -1, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 3, -2, -6, -1, 1, 1 ], [ 3, -2, -5, -1, 2, 0 ] ], 1 ], + [ [ [ 1, 0, -5, -1, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 2, -1, -5, -1, 3, 0 ], [ 3, -2, -5, -1, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 1, 0, -5, -1, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 2, 0, -5, -1, 2, 0 ], [ 3, -2, -5, -1, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 2, -1, -6, -1, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 2, 0, -5, -1, 2, 0 ], [ 3, -2, -5, -1, 2, 0 ] ], 1 ], + [ [ [ 2, -1, -6, -1, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 2, 0, -5, -1, 2, 0 ], [ 3, -1, -5, -1, 1, 0 ] ], 1 ], + [ [ [ 2, -1, -6, -1, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 3, -1, -6, -1, 2, 0 ], [ 3, -1, -5, -1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ 2, -1, -6, -1, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 2, -1, -5, 0, 2, 0 ], [ 3, -1, -5, -1, 1, 0 ] ], 1 ], + [ [ [ 1, -1, -5, 0, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 2, -1, -5, 0, 2, 0 ], [ 3, -1, -5, -1, 1, 0 ] ], 1 ], + [ [ [ 1, -1, -5, 0, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 2, -1, -5, 0, 2, 0 ], [ 3, -1, -6, -1, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 3, -1, -6, -2, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 2, -1, -5, 0, 2, 0 ], [ 3, -1, -6, -1, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 3, -1, -6, -2, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 2, -1, -5, 0, 2, 0 ], [ 4, -1, -6, -2, 2, -1 ] ], 1 ], + [ [ [ 3, -1, -6, -2, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 4, -1, -6, -2, 2, -1 ] ], 1 ] + ], + [ + [ [ [ 3, -1, -6, -2, 2, 0 ], [ 3, -1, -5, -1, 2, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 4, -2, -6, -2, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 3, -1, -6, -2, 2, 0 ], [ 5, -1, -6, -3, 2, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 4, -2, -6, -2, 2, 0 ] ], 1 ], + [ [ [ 3, -1, -6, -2, 2, 0 ], [ 5, -1, -6, -3, 2, 0 ], [ 5, -2, -7, -2, 2, 0 ], [ 4, -2, -6, -2, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 4, -2, -7, -2, 2, 0 ], [ 5, -1, -6, -3, 2, 0 ], [ 5, -2, -7, -2, 2, 0 ], [ 4, -2, -6, -2, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 4, -2, -7, -2, 2, 0 ], [ 5, -1, -6, -3, 2, 0 ], [ 5, -2, -7, -2, 2, 0 ], [ 5, -3, -7, -2, 2, 0 ] ], 1 ], + [ [ [ 4, -1, -6, -3, 2, 0 ], [ 5, -1, -6, -3, 2, 0 ], [ 5, -2, -7, -2, 2, 0 ], [ 5, -3, -7, -2, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 4, -3, -7, -1, 2, 0 ], [ 5, -1, -6, -3, 2, 0 ], [ 5, -2, -7, -2, 2, 0 ], [ 5, -3, -7, -2, 2, 0 ] ], 1 ], + [ [ [ 4, -3, -7, -1, 2, 0 ], [ 5, -1, -6, -3, 2, 0 ], [ 5, -3, -7, -2, 2, 1 ], [ 5, -3, -7, -2, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 4, -3, -7, -1, 2, 0 ], [ 5, -1, -6, -3, 2, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 5, -3, -7, -2, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 4, -2, -6, -2, 2, 0 ], [ 5, -1, -6, -3, 2, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 5, -3, -7, -2, 2, 0 ] ], 1 ], + [ [ [ 4, -2, -6, -2, 2, 0 ], [ 5, -1, -6, -3, 2, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 3, 0, -6, -2, 2, 0 ] ], 1 ], + [ [ [ 4, -2, -6, -2, 2, 0 ], [ 3, -2, -6, -2, 2, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 3, 0, -6, -2, 2, 0 ] ], 1 ] + ], + [ + [ [ [ 4, -2, -6, -2, 2, 0 ], [ 3, -2, -6, -2, 2, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 3, -1, -6, -2, 2, 1 ] ], 1 ], + [ [ [ 4, -2, -6, -2, 2, 0 ], [ 3, -1, -6, -2, 1, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 3, -1, -6, -2, 2, 1 ] ], 1 ], + [ [ [ 4, -1, -6, -2, 1, 0 ], [ 3, -1, -6, -2, 1, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 3, -1, -6, -2, 2, 1 ] ], 1 ] + ], + [ + [ [ [ 4, -1, -7, -2, 2, 0 ], [ 3, -1, -6, -2, 1, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 3, -1, -6, -2, 2, 1 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ 4, -2, -6, -2, 2, 0 ], [ 3, -2, -6, -2, 2, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 3, 0, -6, -2, 2, 0 ] ], + [ [ 4, -2, -6, -2, 2, 0 ], [ 3, -2, -6, -2, 2, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 3, -1, -6, -2, 2, 1 ] ], + [ [ 4, -2, -6, -2, 2, 0 ], [ 3, -1, -6, -2, 1, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 3, -1, -6, -2, 2, 1 ] ], + [ [ 4, -1, -6, -2, 1, 0 ], [ 3, -1, -6, -2, 1, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 3, -1, -6, -2, 2, 1 ] ], + [ [ 4, -1, -7, -2, 2, 0 ], [ 3, -1, -6, -2, 1, 0 ], [ 4, -1, -6, -2, 2, 0 ], [ 3, -1, -6, -2, 2, 1 ] ] +], +"cur_uid": "7c30c182", +"ref_uid": "nil", +"order_seed": 993548, +"dur_seed": 828564, +"motifs_seed": 174746, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.037037037037037, 0, 0.18518518518519, 0, 0.45679012345679, 0, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58230452674897, 0, 0.61111111111111, 0, 0.7798353909465, 0, 1, 0 ], +"passages_weights": [ 1, 0.47, 0.43, 1, 1 ], +"hd_exp": 3.22, +"hd_invert": 0, +"order": +[ + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 0, 2, 3 ], [ 1 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 3, 0 ], [ 2, 1 ], [ ] ], + [ [ 3, 0 ], [ 2, 1 ], [ ] ], + [ [ 0, 2 ], [ 1, 3 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 0, 3 ], [ 2, 1 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 2, 1, 3 ], [ 0 ], [ ] ], + [ [ 0, 1 ], [ 3, 2 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ], + [ [ 3, 0 ], [ 1, 2 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 2, 3, 1 ], [ 0 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 48.479591836735, 48.479591836735 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/lilypond/part_I.ly new file mode 100644 index 0000000..533c6b9 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/lilypond/part_I.ly @@ -0,0 +1,92 @@ +{ + { c'1^\markup { \pad-markup #0.2 "+0"} } + \bar "|" + { e'1^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { e'2 f'2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'2 fis'2^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + \bar "|" + { fis'1 } + \bar "|" + { gis'1^\markup { \pad-markup #0.2 "-40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "+25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } + \bar "|" + { ais'1^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + \bar "|" + { ais'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "+44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} } + \bar "|" + { fis'1^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { fis'1 } + \bar "|" + { g'1^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1 } + \bar "|" + { fis1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + \bar "|" + { fis1 } + \bar "|" + { g1^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }} ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 } + \bar "|" + { gis1^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} } + \bar "|" + { ais1^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { ais2 b2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }} ~ } + \bar "|" + { b2 e'2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2 f'2^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'2 g'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + \bar "|" + { g'2 cis'2^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }} ~ } + \bar "|" + { cis'2 d'2^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'2 e'2^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2 e'2^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + \bar "|" + { e'2 fis'2^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }} ~ } + \bar "|" + { fis'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/lilypond/part_II.ly new file mode 100644 index 0000000..c4d9581 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/lilypond/part_II.ly @@ -0,0 +1,92 @@ +{ + { c'2^\markup { \pad-markup #0.2 "+0"} g'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { g'2 gis'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "+11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + \bar "|" + { a'2 b'2^\markup { \pad-markup #0.2 "-24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { b'1 } + \bar "|" + { c''1^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + \bar "|" + { c''2 d'2^\markup { \pad-markup #0.2 "-4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'2 e'2^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2 b'2^\markup { \pad-markup #0.2 "+44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + \bar "|" + { b'2 b'2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b'2 a'2^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'2 ais'2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } + \bar "|" + { ais'2 b'2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'2 c'2^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } + \bar "|" + { c'2 d'2^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'2 dis'2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 } + \bar "|" + { f'2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} fis'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { fis'1 } + \bar "|" + { g'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} a'2^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a'2 b'2^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 } + \bar "|" + { c''2^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} a'2^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/lilypond/part_III.ly new file mode 100644 index 0000000..2a0ff52 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/lilypond/part_III.ly @@ -0,0 +1,92 @@ +{ + { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { c'1 } + \bar "|" + { c''1^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c''2 cis'2^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'2 dis'2^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'2 e'2^\markup { \pad-markup #0.2 "-26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + \bar "|" + { e'2 ais'2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { b'2 ais2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { ais1 } + \bar "|" + { b1^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { b1 } + \bar "|" + { c'1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} } + \bar "|" + { d'2^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} dis'2^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'1 } + \bar "|" + { f'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} ~ } + \bar "|" + { f'1 } + \bar "|" + { fis'1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { fis'2 g'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + \bar "|" + { g'1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } + \bar "|" + { ais'1^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} } + \bar "|" + { b'2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} c''2^\markup { \pad-markup #0.2 "-42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + \bar "|" + { c''2 ais'2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + \bar "|" + { ais'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 } + \bar "|" + { c''1^\markup { \pad-markup #0.2 "-24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 } + \bar "|" + { d1^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } + \bar "|" + { e1^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/lilypond/part_IV.ly new file mode 100644 index 0000000..3a4f61a --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7c30c182/lilypond/part_IV.ly @@ -0,0 +1,92 @@ +{ + { c1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { c1 ~ } + \bar "|" + { c1 } + \bar "|" + { cis1^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} } + \bar "|" + { dis1^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } + \bar "|" + { dis1 ~ } + \bar "|" + { dis1 } + \bar "|" + { e1^\markup { \pad-markup #0.2 "+27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↑" }} ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e2 fis2^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis2 g2^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 } + \bar "|" + { gis1^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { gis2 d,2^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↑" }} ~ } + \bar "|" + { d,2 e,2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + \bar "|" + { e,2 f,2^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } + \bar "|" + { f,1 } + \bar "|" + { g,2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} a,2^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 } + \bar "|" + { fis1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { fis1 } + \bar "|" + { g1^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + \bar "|" + { g1 } + \bar "|" + { a1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + \bar "|" + { a1^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 } + \bar "|" + { b1^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + \bar "|" + { c'2^\markup { \pad-markup #0.2 "-24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} cis'2^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } + \bar "|" + { cis'1 } + \bar "|" + { d'1^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'2 e'2^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/7ede7adb_code.scd b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/7ede7adb_code.scd new file mode 100644 index 0000000..42b64ff --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/7ede7adb_code.scd @@ -0,0 +1,981 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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.01); + + + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/7ede7adb_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/7ede7adb_mus_model.json new file mode 100644 index 0000000..b5aa312 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/7ede7adb_mus_model.json @@ -0,0 +1,83 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -4, 2, 2, 3, 1, 0 ], [ -5, 3, 2, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -4, 2, 2, 3, 1, 0 ], [ -3, 1, 1, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 1, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 1, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 2, 2, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -2, 1, 1, 2, 1, 0 ], [ -3, 1, 1, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -5, 2, 1, 2, 1, 0 ], [ -3, 1, 1, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -4, 2, 1, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 2, 1, 2, 1, 0 ], [ -3, 1, 1, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -4, 3, 1, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 2, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -4, 3, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -5, 3, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -4, 3, 1, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 3, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -3, 1, 2, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 3, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -4, 3, 2, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 3, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ], [ -4, 2, 2, 2, 1, 0 ], [ -2, 2, 1, 1, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 3, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ], [ -4, 3, 2, 2, 1, 0 ], [ -2, 2, 1, 1, 1, 0 ] ], 1 ], + [ [ [ -5, 3, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ], [ -4, 3, 2, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ] ], 1 ] + ], + [ + [ [ [ -5, 3, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -5, 3, 1, 2, 1, 0 ], [ -3, 1, 1, 3, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ] ], 1 ], + [ [ [ -3, 0, 1, 2, 1, 0 ], [ -3, 1, 1, 3, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -5, 3, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ], [ -4, 3, 2, 2, 1, 0 ], [ -2, 2, 1, 1, 1, 0 ] ], + [ [ -5, 3, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ], [ -4, 3, 2, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ] ], + [ [ -5, 3, 1, 2, 1, 0 ], [ -3, 2, 1, 2, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ] ], + [ [ -5, 3, 1, 2, 1, 0 ], [ -3, 1, 1, 3, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ] ], + [ [ -3, 0, 1, 2, 1, 0 ], [ -3, 1, 1, 3, 1, 0 ], [ -2, 1, 0, 2, 1, 0 ], [ -2, 1, 1, 2, 1, 0 ] ] +], +"cur_uid": "7ede7adb", +"ref_uid": "6522664c", +"order_seed": 455950, +"dur_seed": 308053, +"motifs_seed": 206233, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0061728395061728, 0.10227272727273, 0.074074074074074, 0.10227272727273, 0.2037037037037, 0.090909090909091, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 1, 0.47, 0.43, 1, 0.7 ], +"hd_exp": 7, +"hd_invert": 0, +"order": +[ + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 1, 2 ], [ 0, 3 ], [ ] ], + [ [ 2, 1 ], [ 3, 0 ], [ ] ], + [ [ 0, 1, 2 ], [ 3 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ], + [ [ 1, 0, 2 ], [ 3 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 10.091836734694, 10.091836734694 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/lilypond/part_I.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/lilypond/part_I.ly new file mode 100644 index 0000000..41fe1e5 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/lilypond/part_I.ly @@ -0,0 +1,18 @@ +{ + { g'1^\markup { \pad-markup #0.2 "-21"} ~ } + \bar "|" + { g'2 b'2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + \bar "|" + { g1^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} } + \bar "|" + { d'1^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { d'2 e'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} } + \bar "|" + { fis'2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} a'2^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + \bar "|" + { a'2 c''2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { c''1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/lilypond/part_II.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/lilypond/part_II.ly new file mode 100644 index 0000000..ce1994b --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/lilypond/part_II.ly @@ -0,0 +1,18 @@ +{ + { b1^\markup { \pad-markup #0.2 "-34"} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 } + \bar "|" + { fis'1^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} } + \bar "|" + { gis'1^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/lilypond/part_III.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/lilypond/part_III.ly new file mode 100644 index 0000000..e5a072c --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/lilypond/part_III.ly @@ -0,0 +1,18 @@ +{ + { fis2^\markup { \pad-markup #0.2 "-33"} c'2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'2 g'2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'2 a'2^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/lilypond/part_IV.ly b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/lilypond/part_IV.ly new file mode 100644 index 0000000..bf1c7e0 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/7ede7adb/lilypond/part_IV.ly @@ -0,0 +1,18 @@ +{ + { gis'1^\markup { \pad-markup #0.2 "+34"} } + \bar "|" + { c''1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c''2 g,2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g,1 } + \bar "|" + { d1^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d1} +\bar "||" +} \ No newline at end of file diff --git a/resources/resources_bak_2024_01_03/string_quartet_3_rise/tmp/tmp_mus_model.json b/resources/resources_bak_2024_01_03/string_quartet_3_rise/tmp/tmp_mus_model.json new file mode 100644 index 0000000..1a3fb49 --- /dev/null +++ b/resources/resources_bak_2024_01_03/string_quartet_3_rise/tmp/tmp_mus_model.json @@ -0,0 +1,274 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 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, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, -1, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, -1, 0, 1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 0, -1, 0, 1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, 0, 0, -1, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 0, -1, 0, 1, 0, 0 ] ], 0.25 ], + [ [ [ 1, -2, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 0, -1, 0, 1, 0, 0 ] ], 0 ], + [ [ [ 1, -2, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -2, 0, -1, 0, 0 ], [ 2, -2, 0, -1, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, -2, 0, -1, 0, 0 ], [ 2, -2, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -2, 0, -1, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.5 ], + [ [ [ 0, 0, 0, -1, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 0, 0, -1, 0, 0 ], [ 1, -1, 1, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.5 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 1, -1, 1, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 1, -1, 1, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ] ], 0.5 ] + ], + [ + [ [ [ 2, -1, -1, -2, 0, 0 ], [ 1, -1, 1, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 2, -1, -1, -2, 0, 0 ], [ 1, -1, 1, -1, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 2, -1, -1, -2, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ] ], 0.5 ], + [ [ [ 0, -1, -1, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, -1, -1, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ], [ 2, -1, -1, -2, 0, 0 ] ], 0 ], + [ [ [ 0, -1, -1, 0, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ], [ 2, -1, -1, -2, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ], [ 2, -1, -1, -2, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, -1, -2, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ], [ 2, -1, -1, -2, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, -2, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ], [ 3, -1, -1, -3, 0, 0 ] ], 0.25 ], + [ [ [ 2, -1, -1, -3, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ], [ 3, -1, -1, -3, 0, 0 ] ], 0.25 ], + [ [ [ 2, -1, -1, -2, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ], [ 3, -1, -1, -3, 0, 0 ] ], 0.25 ], + [ [ [ 2, -1, -1, -2, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ], [ 2, -1, 0, -2, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 2, -1, -1, -2, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, -1, 0, 1 ], [ 2, -1, -1, -1, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, -1, 0, 1 ], [ 2, -1, -1, -1, 0, 0 ], [ 3, -1, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.5 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 3, -1, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 3, -1, -1, -1, 0, 0 ], [ 2, -1, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 3, -1, -2, -1, 0, 0 ], [ 3, -1, -1, -1, 0, 0 ], [ 2, -1, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 3, -1, -2, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 2, -1, -2, -1, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 2, -1, -2, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 1 ], [ 2, -1, -1, -1, 0, 0 ], [ 2, -1, -2, -1, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 1 ], [ 2, -1, -1, -1, 0, 0 ], [ 3, -2, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 1 ], [ 2, -1, -1, -2, 0, 0 ], [ 3, -2, -1, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 1 ], [ 1, -1, 0, -1, 0, 0 ], [ 3, -2, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 1 ], [ 1, -1, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ] ], 0.5 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ] ], 0.5 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 2, -2, -1, -1, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 2, -2, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 3, -1, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.5 ], + [ [ [ 0, 1, -1, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 3, -1, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -1, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ], [ 3, -1, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -1, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.5 ], + [ [ [ 0, 1, -1, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.25 ], + [ [ [ 0, 1, -1, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 0, -1, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.25 ], + [ [ [ 0, 0, -1, -1, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ], [ 0, 1, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.5 ] + ], + [ + [ [ [ 1, 0, -1, -2, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ], [ 0, 1, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.25 ], + [ [ [ 1, 0, -1, -2, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ], [ 2, 0, -1, -2, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 1, 0, -1, -2, 0, 0 ], [ 2, 0, -2, -1, 0, 0 ], [ 2, 0, -1, -2, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.25 ], + [ [ [ 1, 0, -1, -2, 0, 0 ], [ 2, 0, -2, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.5 ], + [ [ [ 1, 0, -1, -2, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.5 ], + [ [ [ 1, 0, -1, -2, 0, 0 ], [ 2, 0, -1, -2, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, -1, 0, 0 ], [ 2, 0, -1, -2, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 0, 0, -1, 0, 0 ], [ 2, 0, -1, -2, 0, 0 ], [ 3, 0, -1, -2, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, 0, -1, -2, 0, 0 ], [ 3, 0, -1, -2, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, -1, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 3, 0, -1, -2, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 0, -1, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 3, 0, -1, -2, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 0, -1, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 3, 0, -1, -2, 0, 0 ], [ 2, 0, -1, -2, 0, 0 ] ], 0 ], + [ [ [ 0, 0, -1, -1, 0, 0 ], [ 3, 0, -2, -2, 0, 0 ], [ 3, 0, -1, -2, 0, 0 ], [ 2, 0, -1, -2, 0, 0 ] ], 0.5 ], + [ [ [ 0, 0, -1, -1, 0, 0 ], [ 3, 0, -2, -2, 0, 0 ], [ 3, 0, -1, -2, 0, 0 ], [ 3, 0, -1, -3, 0, 0 ] ], 0 ], + [ [ [ 1, 0, -1, -2, 0, 0 ], [ 3, 0, -2, -2, 0, 0 ], [ 3, 0, -1, -2, 0, 0 ], [ 3, 0, -1, -3, 0, 0 ] ], 0.25 ], + [ [ [ 2, 0, -2, -2, 0, 0 ], [ 3, 0, -2, -2, 0, 0 ], [ 3, 0, -1, -2, 0, 0 ], [ 3, 0, -1, -3, 0, 0 ] ], 0 ], + [ [ [ 2, 0, -2, -2, 0, 0 ], [ 2, 1, -1, -2, 0, 0 ], [ 3, 0, -1, -2, 0, 0 ], [ 3, 0, -1, -3, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 2, 1, -1, -2, 0, 0 ], [ 3, 0, -1, -2, 0, 0 ], [ 3, 0, -1, -3, 0, 0 ] ], 0.25 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 2, 1, -1, -2, 0, 0 ], [ 3, 0, -1, -2, 0, 0 ], [ 2, 1, -2, -2, 0, 0 ] ], 0.25 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 2, 1, -1, -2, 0, 0 ], [ 2, 2, -1, -2, 0, 0 ], [ 2, 1, -2, -2, 0, 0 ] ], 0.5 ] + ], + [ + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 2, 1, -1, -2, 0, 0 ], [ 3, 1, -2, -2, 0, 0 ], [ 2, 1, -2, -2, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 2, 1, -1, -2, 0, 0 ], [ 3, 1, -2, -2, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 3, 1, -1, -3, 0, 0 ], [ 3, 1, -2, -2, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ] ], 0.25 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 3, 1, -1, -3, 0, 0 ], [ 3, 1, -2, -2, 0, 0 ], [ 2, 1, -1, -2, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 1, 2, -1, -2, 0, 0 ], [ 3, 1, -2, -2, 0, 0 ], [ 2, 1, -1, -2, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 2, 1, -2, -2, 0, 0 ], [ 3, 1, -2, -2, 0, 0 ], [ 2, 1, -1, -2, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 2, 1, -2, -2, 0, 0 ], [ 3, 1, -2, -2, 0, 0 ], [ 3, 1, -1, -3, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 2, 1, -2, -2, 0, 0 ], [ 2, 2, -1, -2, 0, 0 ], [ 3, 1, -1, -3, 0, 0 ] ], 0.5 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 2, 1, -2, -2, 0, 0 ], [ 2, 1, -1, -2, 1, 0 ], [ 3, 1, -1, -3, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 1, 1, -1, -1, 0, 0 ], [ 2, 1, -1, -2, 1, 0 ], [ 3, 1, -1, -3, 0, 0 ] ], 0.375 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 2, 1, -1, -2, 0, 0 ], [ 2, 1, -1, -2, 1, 0 ], [ 3, 1, -1, -3, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 2, 1, -1, -2, 0, 0 ], [ 2, 0, -1, -2, 0, 0 ], [ 3, 1, -1, -3, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 1, 1, -1, -2, -1, 0 ], [ 2, 0, -1, -2, 0, 0 ], [ 3, 1, -1, -3, 0, 0 ] ], 0.25 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 1, 1, -1, -2, -1, 0 ], [ 2, 0, -1, -2, 0, 0 ], [ 2, 1, 0, -2, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 1, 1, -1, -2, -1, 0 ], [ 1, 2, -1, -2, 0, 0 ], [ 2, 1, 0, -2, 0, 0 ] ], 0.5 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 1, 1, -1, -2, -1, 0 ], [ 2, 1, -1, -2, 0, 0 ], [ 2, 1, 0, -2, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 1, 1, -1, -2, -1, 0 ], [ 2, 1, -1, -2, 0, 0 ], [ 3, 0, -1, -2, 0, 0 ] ], 0.5 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 1, 1, -1, -2, -1, 0 ], [ 2, 1, -1, -2, 0, 0 ], [ 3, 1, -1, -2, -1, 0 ] ], 0.25 ], + [ [ [ 1, 1, -1, -2, 0, 0 ], [ 1, 1, -1, -2, -1, 0 ], [ 2, 1, -1, -2, -1, 0 ], [ 3, 1, -1, -2, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 2, -1, -2, -1, 0 ], [ 1, 1, -1, -2, -1, 0 ], [ 2, 1, -1, -2, -1, 0 ], [ 3, 1, -1, -2, -1, 0 ] ], 0.25 ], + [ [ [ 1, 2, -1, -2, -1, 0 ], [ 1, 1, -1, -2, -1, 0 ], [ 2, 1, -1, -2, -1, 0 ], [ 2, 2, -1, -2, -1, 0 ] ], 0.25 ], + [ [ [ 1, 2, -1, -2, -1, 0 ], [ 1, 1, -1, -2, -1, 0 ], [ 3, 1, -1, -3, -1, 0 ], [ 2, 2, -1, -2, -1, 0 ] ], 0.25 ], + [ [ [ 1, 1, -1, -2, -1, 1 ], [ 1, 1, -1, -2, -1, 0 ], [ 3, 1, -1, -3, -1, 0 ], [ 2, 2, -1, -2, -1, 0 ] ], 0 ], + [ [ [ 1, 1, -1, -2, -1, 1 ], [ 1, 1, -1, -2, -1, 0 ], [ 2, 1, 0, -2, -1, 0 ], [ 2, 2, -1, -2, -1, 0 ] ], 0.5 ], + [ [ [ 1, 1, -1, -1, -1, 0 ], [ 1, 1, -1, -2, -1, 0 ], [ 2, 1, 0, -2, -1, 0 ], [ 2, 2, -1, -2, -1, 0 ] ], 0.25 ], + [ [ [ 2, 1, -1, -2, -1, 0 ], [ 1, 1, -1, -2, -1, 0 ], [ 2, 1, 0, -2, -1, 0 ], [ 2, 2, -1, -2, -1, 0 ] ], 0.5 ], + [ [ [ 2, 1, -1, -2, -1, 0 ], [ 1, 1, -1, -2, -1, 0 ], [ 2, 1, 0, -2, -1, 0 ], [ 3, 1, -1, -2, -1, 0 ] ], 0.5 ] + ], + [ + [ [ [ 2, 1, -1, -2, -1, 0 ], [ 1, 1, 0, -2, -1, 0 ], [ 2, 1, 0, -2, -1, 0 ], [ 3, 1, -1, -2, -1, 0 ] ], 0.5 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 1, 1, 0, -2, -1, 0 ], [ 2, 1, 0, -2, -1, 0 ], [ 3, 1, -1, -2, -1, 0 ] ], 0.5 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 1, 1, 0, -2, -1, 0 ], [ 2, 1, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 1, 0, -2, -1, 0 ], [ 1, 1, 0, -2, -1, 0 ], [ 2, 1, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0 ], + [ [ [ 0, 1, 0, -2, -1, 0 ], [ 1, 1, 0, -2, -1, 0 ], [ 1, 3, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0.5 ], + [ [ [ 0, 1, 0, -2, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 1, 3, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0.25 ], + [ [ [ 0, 1, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 3, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0 ], + [ [ [ -1, 3, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 3, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0.625 ] + ], + [ + [ [ [ -1, 3, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0.25 ], + [ [ [ -1, 2, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0 ], + [ [ [ -1, 2, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 1, 3, 0, -2, -1, 0 ] ], 0.5 ], + [ [ [ 0, 3, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 1, 3, 0, -2, -1, 0 ] ], 0 ], + [ [ [ 0, 3, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 1, 0, -2, -1, 0 ], [ 1, 3, 0, -2, -1, 0 ] ], 0.25 ], + [ [ [ 0, 3, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 1, 0, -2, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ] ], 0.5 ], + [ [ [ 0, 3, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 1, 0, -2, -1, 0 ], [ 2, 1, 0, -2, -1, 0 ] ], 0.5 ] + ], + [ + [ [ [ 0, 3, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 1, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0.25 ], + [ [ [ 2, 1, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 1, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0 ], + [ [ [ 2, 1, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0.25 ], + [ [ [ 1, 3, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0 ], + [ [ [ 1, 3, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 1, 1, 0, -2, -1, 0 ] ], 0.5 ] + ], + [ + [ [ [ 1, 3, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 0, 3, 0, -2, -1, 0 ] ], 0.25 ], + [ [ [ 1, 3, 0, -2, -1, 0 ], [ 1, 2, 0, -3, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 0, 3, 0, -2, -1, 0 ] ], 0.25 ], + [ [ [ 2, 2, -1, -2, -1, 0 ], [ 1, 2, 0, -3, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 0, 3, 0, -2, -1, 0 ] ], 0.25 ], + [ [ [ 2, 2, -1, -2, -1, 0 ], [ 1, 2, 0, -3, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 1, 2, 1, -2, -1, 0 ] ], 0 ], + [ [ [ 2, 2, -1, -2, -1, 0 ], [ 0, 2, 1, -2, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 1, 2, 1, -2, -1, 0 ] ], 0.25 ], + [ [ [ 2, 2, -1, -2, -1, 0 ], [ 0, 2, 1, -2, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 1, 3, 0, -2, -1, 0 ] ], 0 ], + [ [ [ 2, 2, -1, -2, -1, 0 ], [ 1, 2, -1, -2, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 1, 3, 0, -2, -1, 0 ] ], 0.25 ], + [ [ [ 2, 2, -1, -2, -1, 0 ], [ 1, 2, -1, -2, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 3, 0, -2, -1, 0 ], [ 1, 2, -1, -2, -1, 0 ], [ 1, 2, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0 ], + [ [ [ 1, 3, 0, -2, -1, 0 ], [ 1, 2, -1, -2, -1, 0 ], [ 2, 2, 0, -3, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0.25 ], + [ [ [ 1, 3, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 2, 2, 0, -3, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0 ], + [ [ [ 1, 3, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 0, 3, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0.25 ], + [ [ [ 1, 3, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 1, 2, -1, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0 ], + [ [ [ 1, 3, 0, -2, -1, 0 ], [ 0, 3, 0, -2, -1, 0 ], [ 1, 2, -1, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0 ], + [ [ [ 2, 2, -1, -2, -1, 0 ], [ 0, 3, 0, -2, -1, 0 ], [ 1, 2, -1, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 0, 3, 0, -2, -1, 0 ], [ 1, 2, -1, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 0, 3, 0, -2, -1, 0 ], [ 1, 2, -1, -2, -1, 0 ], [ 1, 2, -1, -1, -1, 0 ] ], 0 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 1, 2, -1, -2, -1, -1 ], [ 1, 2, -1, -2, -1, 0 ], [ 1, 2, -1, -1, -1, 0 ] ], 0.25 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 1, 2, -1, -2, -1, -1 ], [ 1, 2, -1, -2, -1, 0 ], [ 2, 2, -1, -2, -1, 0 ] ], 0 ], + [ [ [ 2, 1, -1, -2, -1, 0 ], [ 1, 2, -1, -2, -1, -1 ], [ 1, 2, -1, -2, -1, 0 ], [ 2, 2, -1, -2, -1, 0 ] ], 0.5 ], + [ [ [ 2, 2, -1, -2, -1, -1 ], [ 1, 2, -1, -2, -1, -1 ], [ 1, 2, -1, -2, -1, 0 ], [ 2, 2, -1, -2, -1, 0 ] ], 0 ], + [ [ [ 2, 2, -1, -2, -1, -1 ], [ 1, 2, -1, -2, -1, -1 ], [ 1, 2, -1, -2, -1, 0 ], [ 2, 3, -1, -2, -1, 0 ] ], 0.5 ] + ], + [ + [ [ [ 2, 2, -1, -2, -1, -1 ], [ 1, 2, -1, -2, -1, -1 ], [ 1, 3, -1, -2, -1, -1 ], [ 2, 3, -1, -2, -1, 0 ] ], 0 ], + [ [ [ 2, 2, -1, -2, -1, -1 ], [ -1, 3, -1, -1, -1, 0 ], [ 1, 3, -1, -2, -1, -1 ], [ 2, 3, -1, -2, -1, 0 ] ], 0 ], + [ [ [ 0, 3, -1, -1, -1, 0 ], [ -1, 3, -1, -1, -1, 0 ], [ 1, 3, -1, -2, -1, -1 ], [ 2, 3, -1, -2, -1, 0 ] ], 0.25 ], + [ [ [ 1, 3, -1, -2, -1, 0 ], [ -1, 3, -1, -1, -1, 0 ], [ 1, 3, -1, -2, -1, -1 ], [ 2, 3, -1, -2, -1, 0 ] ], 0 ], + [ [ [ 1, 3, -1, -2, -1, 0 ], [ 0, 3, -1, -2, -1, 0 ], [ 1, 3, -1, -2, -1, -1 ], [ 2, 3, -1, -2, -1, 0 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ 2, 2, -1, -2, -1, -1 ], [ 1, 2, -1, -2, -1, -1 ], [ 1, 3, -1, -2, -1, -1 ], [ 2, 3, -1, -2, -1, 0 ] ], + [ [ 2, 2, -1, -2, -1, -1 ], [ -1, 3, -1, -1, -1, 0 ], [ 1, 3, -1, -2, -1, -1 ], [ 2, 3, -1, -2, -1, 0 ] ], + [ [ 0, 3, -1, -1, -1, 0 ], [ -1, 3, -1, -1, -1, 0 ], [ 1, 3, -1, -2, -1, -1 ], [ 2, 3, -1, -2, -1, 0 ] ], + [ [ 1, 3, -1, -2, -1, 0 ], [ -1, 3, -1, -1, -1, 0 ], [ 1, 3, -1, -2, -1, -1 ], [ 2, 3, -1, -2, -1, 0 ] ], + [ [ 1, 3, -1, -2, -1, 0 ], [ 0, 3, -1, -2, -1, 0 ], [ 1, 3, -1, -2, -1, -1 ], [ 2, 3, -1, -2, -1, 0 ] ] +], +"cur_uid": "tmp", +"ref_uid": "nil", +"order_seed": 482760, +"dur_seed": 662444, +"motifs_seed": 696864, +"entrances_probs_vals": [ 0.63, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.44771241830065, 0, 0.50653594771242, 0.41216216216216, 0.5359477124183, 0, 1, 0 ], +"passages_probs_vals": [ 0.63, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.44771241830065, 0, 0.50653594771242, 0.41216216216216, 0.5359477124183, 0, 1, 0 ], +"exits_probs_vals": [ 0.63, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.44771241830065, 0, 0.50653594771242, 0.41216216216216, 0.5359477124183, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0.0041152263374486, 0.0056818181818179, 0.080246913580247, 0.02840909090909, 0.20781893004115, 0.028409090909091, 0.41152263374486, 0, 0.44650205761317, 0.16477272727273, 0.47736625514403, 0, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 0.58, 1, 0.43, 1, 0.82 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 3 ], [ 0, 2, 1, 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 0, 0, 3 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 1 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 1 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 0 ], [ ] ], + [ [ 2 ], [ 3, 1, 0, 0, 3, 0, 0, 3 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 0 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1, 1, 3, 2, 3, 2 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 2, 2, 2, 0, 2 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 2, 1, 1, 0 ], [ ] ], + [ [ 3 ], [ 2, 0, 1 ], [ ] ], + [ [ 2 ], [ 0, 3, 1, 3, 0, 0, 1 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1, 3, 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 2, 1, 1, 2 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 2, 3, 3, 2 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 0, 2, 0, 0, 3 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 1, 0 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 0, 2, 3, 3 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 0, 3 ], [ ] ], + [ [ 2 ], [ 3, 1, 0, 3, 1, 3, 1, 3 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 2, 2, 1, 0 ], [ ] ], + [ [ 2 ], [ 0, 3, 1, 3, 0, 0, 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 0, 1 ], [ ] ] +], +"sus_weights": [ 0.69, 0, 0 ], +"order_size": [ 28, 28.275510204082 ], +"passages_size": [ 0, 6 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_1/490b1e6e/490b1e6e_mus_model.json b/resources/string_quartet_1/490b1e6e/490b1e6e_mus_model.json index 64ab1de..67e50c3 100644 --- a/resources/string_quartet_1/490b1e6e/490b1e6e_mus_model.json +++ b/resources/string_quartet_1/490b1e6e/490b1e6e_mus_model.json @@ -24,9 +24,7 @@ [ [ [ -1, 0, 0, 0, 1, 0 ], [ -1, -1, 1, 0, 1, 0 ], [ 0, -1, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 1.5 ], [ [ [ -1, 0, 0, 0, 1, 0 ], [ 0, -2, 0, 0, 1, 0 ], [ 0, -1, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 1.25 ], [ [ [ -1, 0, 0, 0, 1, 0 ], [ 0, -2, 0, 0, 1, 0 ], [ 0, -1, 0, 0, 1, 0 ], [ "Rest" ] ], 0.875 ], - [ [ [ "Rest" ], [ 0, -2, 0, 0, 1, 0 ], [ 0, -1, 0, 0, 1, 0 ], [ "Rest" ] ], 0 ], - [ [ [ "Rest" ], [ 0, -2, 0, 0, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], - [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.375 ] + [ [ [ "Rest" ], [ 0, -2, 0, 0, 1, 0 ], [ 0, -1, 0, 0, 1, 0 ], [ "Rest" ] ], 1.375 ] ] ] ], diff --git a/resources/string_quartet_1/490b1e6e/lilypond/part_II.ly b/resources/string_quartet_1/490b1e6e/lilypond/part_II.ly index 72acd78..212ca16 100644 --- a/resources/string_quartet_1/490b1e6e/lilypond/part_II.ly +++ b/resources/string_quartet_1/490b1e6e/lilypond/part_II.ly @@ -21,6 +21,6 @@ \bar "|" { ais1 ~ } \bar "|" - { ais4 ~ ais16[ r8.] r2 } + { ais1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_1/490b1e6e/lilypond/part_III.ly b/resources/string_quartet_1/490b1e6e/lilypond/part_III.ly index c698c38..d2fdd62 100644 --- a/resources/string_quartet_1/490b1e6e/lilypond/part_III.ly +++ b/resources/string_quartet_1/490b1e6e/lilypond/part_III.ly @@ -21,6 +21,6 @@ \bar "|" { d4 dis2.^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } \bar "|" - { dis4 ~ dis16[ r8.] r2 } + { dis1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_1/4a8a6e53/4a8a6e53_mus_model.json b/resources/string_quartet_1/4a8a6e53/4a8a6e53_mus_model.json index 150baf5..4e54975 100644 --- a/resources/string_quartet_1/4a8a6e53/4a8a6e53_mus_model.json +++ b/resources/string_quartet_1/4a8a6e53/4a8a6e53_mus_model.json @@ -56,9 +56,9 @@ [ [ [ 1, -1, 0, 0, -2, 0 ], [ "Rest" ], [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 1.375 ], [ [ [ 1, -1, 0, 0, -2, 0 ], [ "Rest" ], [ 2, -2, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 0.875 ], [ [ [ 0, -1, 0, 0, -1, 1 ], [ "Rest" ], [ 2, -2, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 3.375 ], - [ [ [ 0, -1, 0, 0, -1, 1 ], [ "Rest" ], [ 2, -2, 0, 0, -1, 0 ], [ "Rest" ] ], 1.5 ], - [ [ [ 0, -1, 0, 0, -1, 1 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.375 ], - [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 2 ] + [ [ [ 0, -1, 0, 0, -1, 1 ], [ "Rest" ], [ 2, -2, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ] ], 1.5 ], + [ [ [ 0, -1, 0, 0, -1, 1 ], [ "Rest" ], [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ] ], 1.375 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ] ], 6 ] ] ] ], diff --git a/resources/string_quartet_1/4a8a6e53/lilypond/part_I.ly b/resources/string_quartet_1/4a8a6e53/lilypond/part_I.ly index e9e6601..35e6ebb 100644 --- a/resources/string_quartet_1/4a8a6e53/lilypond/part_I.ly +++ b/resources/string_quartet_1/4a8a6e53/lilypond/part_I.ly @@ -47,10 +47,14 @@ \bar "|" { b1 ~ } \bar "|" - { b2 ~ b16[ r8.] r4 } + { b1 ~ } \bar "|" - { r1 } + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } \bar "|" - { r1 } + { b1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_1/4a8a6e53/lilypond/part_II.ly b/resources/string_quartet_1/4a8a6e53/lilypond/part_II.ly index 3c00ff8..7ce04eb 100644 --- a/resources/string_quartet_1/4a8a6e53/lilypond/part_II.ly +++ b/resources/string_quartet_1/4a8a6e53/lilypond/part_II.ly @@ -51,6 +51,10 @@ \bar "|" { e'4 ~ e'16[ r8.] r2 } \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" { r1 } \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_1/4a8a6e53/lilypond/part_III.ly b/resources/string_quartet_1/4a8a6e53/lilypond/part_III.ly index 75dcb1c..158131f 100644 --- a/resources/string_quartet_1/4a8a6e53/lilypond/part_III.ly +++ b/resources/string_quartet_1/4a8a6e53/lilypond/part_III.ly @@ -51,6 +51,10 @@ \bar "|" { r1 } \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" { r1 } \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_1/4a8a6e53/lilypond/part_IV.ly b/resources/string_quartet_1/4a8a6e53/lilypond/part_IV.ly index 41471e8..a80f515 100644 --- a/resources/string_quartet_1/4a8a6e53/lilypond/part_IV.ly +++ b/resources/string_quartet_1/4a8a6e53/lilypond/part_IV.ly @@ -51,6 +51,10 @@ \bar "|" { gis1 } \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" { r1 } \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_1/66f6a618/66f6a618_mus_model.json b/resources/string_quartet_1/66f6a618/66f6a618_mus_model.json index fe45ed4..579cc75 100644 --- a/resources/string_quartet_1/66f6a618/66f6a618_mus_model.json +++ b/resources/string_quartet_1/66f6a618/66f6a618_mus_model.json @@ -44,17 +44,17 @@ [ [ [ -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 ] ], 3.75 ] + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, -1 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 5.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" ], [ 0, 0, 0, 0, 0, -1 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 1 ], + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, -1 ], [ "Rest" ], [ 0, 0, 0, 0, 1, 0 ] ], 3.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 ] ], 2.625 ], + [ [ [ "Rest" ], [ -2, 0, 0, 1, 1, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 1, 0 ] ], 3.625 ], [ [ [ "Rest" ], [ -2, 0, 0, 1, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 0.25 ], - [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0.375 ] + [ [ [ "Rest" ], [ -2, 0, 0, 1, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 1.5 ] ] ] ], diff --git a/resources/string_quartet_1/66f6a618/lilypond/part_I.ly b/resources/string_quartet_1/66f6a618/lilypond/part_I.ly index d05522a..a684605 100644 --- a/resources/string_quartet_1/66f6a618/lilypond/part_I.ly +++ b/resources/string_quartet_1/66f6a618/lilypond/part_I.ly @@ -65,6 +65,12 @@ \bar "|" { fis'1 ~ } \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" { fis'2 ~ fis'8.[ r16] r4} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_1/66f6a618/lilypond/part_II.ly b/resources/string_quartet_1/66f6a618/lilypond/part_II.ly index 602b0d6..82d5004 100644 --- a/resources/string_quartet_1/66f6a618/lilypond/part_II.ly +++ b/resources/string_quartet_1/66f6a618/lilypond/part_II.ly @@ -57,7 +57,13 @@ \bar "|" { b1 ~ } \bar "|" - { b8.[ r16] r2. } + { b1 ~ } + \bar "|" + { b2 ~ b8.[ r16] r4 } + \bar "|" + { r1 } + \bar "|" + { r1 } \bar "|" { r1 } \bar "|" diff --git a/resources/string_quartet_1/66f6a618/lilypond/part_III.ly b/resources/string_quartet_1/66f6a618/lilypond/part_III.ly index 6d06a75..d1f7beb 100644 --- a/resources/string_quartet_1/66f6a618/lilypond/part_III.ly +++ b/resources/string_quartet_1/66f6a618/lilypond/part_III.ly @@ -57,14 +57,20 @@ \bar "|" { e1 ~ } \bar "|" - { e2. ~ e16[ d8.^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }}] ~ } + { e1 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e4 ~ e16[ d8.^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }}] ~ d2 ~ } \bar "|" - { d2. cis4^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } + { d4 cis2^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ cis8[ d8^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}] ~ } \bar "|" - { cis4 ~ cis8[ d8^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}] ~ d2 ~ } + { d2. ~ d8[ dis8^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}] ~ } \bar "|" - { d4 ~ d8[ dis8^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}] ~ dis2 ~ } + { dis1 ~ } \bar "|" - { dis2. ~ dis16[ r8.]} + { dis1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_1/66f6a618/lilypond/part_IV.ly b/resources/string_quartet_1/66f6a618/lilypond/part_IV.ly index bc81ade..ebec60a 100644 --- a/resources/string_quartet_1/66f6a618/lilypond/part_IV.ly +++ b/resources/string_quartet_1/66f6a618/lilypond/part_IV.ly @@ -57,6 +57,8 @@ \bar "|" { c1 ~ } \bar "|" + { c1 ~ } + \bar "|" { c8.[ r16] r2. } \bar "|" { r1 } @@ -65,6 +67,10 @@ \bar "|" { r1 } \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" { r1 } \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_1/774ed940/774ed940_mus_model.json b/resources/string_quartet_1/774ed940/774ed940_mus_model.json index beff01e..ea7ab7d 100644 --- a/resources/string_quartet_1/774ed940/774ed940_mus_model.json +++ b/resources/string_quartet_1/774ed940/774ed940_mus_model.json @@ -3,15 +3,15 @@ [ [ [ - [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 2, -1, 1, -2, 1, 0 ] ], 0.25 ], - [ [ [ 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 ] + [ [ [ "Rest" ], [ 1, -1, 1, -2, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 0.25 ], + [ [ [ 0, -1, 1, -2, 1, 1 ], [ 1, -1, 1, -2, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 0.5 ], + [ [ [ 0, 0, 1, -2, 1, 0 ], [ 1, -1, 1, -2, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 1.25 ], + [ [ [ 0, -1, 1, -2, 1, 1 ], [ 1, -1, 1, -2, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 0.75 ], + [ [ [ 0, -1, 1, -1, 1, 0 ], [ 1, -1, 1, -2, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 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 ], [ 1, -1, 1, -2, 1, 0 ], [ "Rest" ], [ 0, 0, 1, -1, 1, 0 ] ], 0 ], + [ [ [ 0, -1, 1, -1, 1, 0 ], [ 1, -1, 1, -2, 1, 0 ], [ 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 ], diff --git a/resources/string_quartet_1/774ed940/lilypond/part_I.ly b/resources/string_quartet_1/774ed940/lilypond/part_I.ly index 2b16ea6..2083359 100644 --- a/resources/string_quartet_1/774ed940/lilypond/part_I.ly +++ b/resources/string_quartet_1/774ed940/lilypond/part_I.ly @@ -1,9 +1,9 @@ { - { g'1^\markup { \pad-markup #0.2 "-2"} ~ } + { r1 } \bar "|" - { g'1 ~ } + { r1 } \bar "|" - { g'2. ~ g'16[ c'8.^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } + { r2. r16[ c'8.^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } \bar "|" { c'1 ~ } \bar "|" diff --git a/resources/string_quartet_1/774ed940/lilypond/part_III.ly b/resources/string_quartet_1/774ed940/lilypond/part_III.ly index 9d65346..66c71ad 100644 --- a/resources/string_quartet_1/774ed940/lilypond/part_III.ly +++ b/resources/string_quartet_1/774ed940/lilypond/part_III.ly @@ -1,9 +1,9 @@ { - { r1 } + { g1^\markup { \pad-markup #0.2 "-2"} ~ } \bar "|" - { r1 } + { g1 ~ } \bar "|" - { r2. r16[ a8.^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ } + { g2. ~ g16[ a8.^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ } \bar "|" { a2 ~ a16[ gis8.^\markup { \pad-markup #0.2 "+26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ gis4 ~ } \bar "|" diff --git a/resources/string_quartet_1/774ed940/lilypond/part_IV.ly b/resources/string_quartet_1/774ed940/lilypond/part_IV.ly index c7d9483..9b37d19 100644 --- a/resources/string_quartet_1/774ed940/lilypond/part_IV.ly +++ b/resources/string_quartet_1/774ed940/lilypond/part_IV.ly @@ -1,7 +1,7 @@ { - { r8[ dis8^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }}] ~ dis8[ d8^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}] ~ d2 } + { r8[ dis8^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}] ~ dis8[ d8^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ d2 } \bar "|" - { dis4^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} ~ dis8[ f8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}] ~ f2 ~ } + { dis4^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }} ~ dis8[ f8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}] ~ f2 ~ } \bar "|" { f1 ~ } \bar "|" diff --git a/resources/string_quartet_1/tmp/tmp_mus_model.json b/resources/string_quartet_1/tmp/tmp_mus_model.json index 1beabb8..474023f 100644 --- a/resources/string_quartet_1/tmp/tmp_mus_model.json +++ b/resources/string_quartet_1/tmp/tmp_mus_model.json @@ -3,76 +3,88 @@ [ [ [ - [ [ [ "Rest" ], [ "Rest" ], [ 2, -1, 1, -2, 1, 0 ], [ "Rest" ] ], 2.75 ], - [ [ [ 2, -1, 1, -2, 0, 0 ], [ "Rest" ], [ 2, -1, 1, -2, 1, 0 ], [ "Rest" ] ], 0.375 ], - [ [ [ 1, -1, 2, -2, 1, 0 ], [ "Rest" ], [ 2, -1, 1, -2, 1, 0 ], [ "Rest" ] ], 3.75 ] + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.375 ], + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.25 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.125 ] ], [ - [ [ [ 1, -1, 2, -2, 1, 0 ], [ "Rest" ], [ 2, -1, 1, -2, 1, 0 ], [ 2, -2, 1, -1, 1, 0 ] ], 0 ], - [ [ [ 1, -1, 2, -2, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 2, -1, 1, -2, 1, 0 ], [ 2, -2, 1, -1, 1, 0 ] ], 3.375 ], - [ [ [ 1, -1, 2, -2, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 3, -3, 1, -2, 0, 0 ], [ 2, -2, 1, -1, 1, 0 ] ], 1 ], - [ [ [ 1, -1, 2, -2, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 2, -2, 1, -1, 1, 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, 0 ] ], 0 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ] ], [ - [ [ [ 0, 1, 2, -2, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 2, -2, 1, -1, 1, 0 ] ], 1.125 ], - [ [ [ 2, -3, 1, -1, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 2, -2, 1, -1, 1, 0 ] ], 3 ] + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.125 ], + [ [ [ -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.25 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ -2, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ -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.25 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ -1, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.375 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ -2, 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 ], [ -2, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ -1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ -2, 0, 0, 1, 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, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.5 ] ], [ - [ [ [ 2, -3, 1, -1, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 2, -3, 0, -1, 1, 0 ] ], 0.875 ], - [ [ [ 2, -3, 1, -1, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 1, -3, 1, 0, 1, 0 ] ], 1.375 ] + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, -1, 0 ] ], 0.125 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, -1, 0, 0, 0 ] ], 0.375 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, -1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -2, 0, 1, 0, 0, 0 ] ], 0.125 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -2, 0, 0, 0, 1, 0 ] ], 0.375 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, -1, 0 ] ], 0.375 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, -1, -1, 0 ] ], 0.5 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.125 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 0.25 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -2, 1, 0, 0, 0, 0 ] ], 0.125 ] ], [ - [ [ [ 1, -3, 1, 0, 0, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 1, -3, 1, 0, 1, 0 ] ], 1.125 ], - [ [ [ 3, -3, 1, -2, 1, -1 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 1, -3, 1, 0, 1, 0 ] ], 1.875 ] - ], - [ - [ [ [ 3, -3, 1, -2, 1, -1 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 1, 0, 1, -2, 1, 0 ] ], 0.875 ], - [ [ [ 3, -3, 1, -2, 1, -1 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 0, 0, 2, -2, 2, 0 ] ], 2.125 ] - ], - [ - [ [ [ 3, -4, 1, -2, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 0, 0, 2, -2, 2, 0 ] ], 0.875 ], - [ [ [ 3, -3, 1, -2, 0, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 0, 0, 2, -2, 2, 0 ] ], 1.625 ], - [ [ [ 3, -3, 1, -2, 0, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ "Rest" ], [ 0, 0, 2, -2, 2, 0 ] ], 0.75 ], - [ [ [ "Rest" ], [ 3, -3, 1, -2, 1, 0 ], [ "Rest" ], [ 0, 0, 2, -2, 2, 0 ] ], 1.125 ], - [ [ [ "Rest" ], [ 3, -3, 1, -2, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 1.25 ], - [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 4.75 ] + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ -1, 0, 1, 0, 0, 0 ], [ -2, 1, 0, 0, 0, 0 ] ], 0.5 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, 0, -1, 0, -1, 0 ], [ -2, 1, 0, 0, 0, 0 ] ], 0.125 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, -1, -1, 0 ], [ -2, 1, 0, 0, 0, 0 ] ], 0.375 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ -2, 1, -1, 0, 0, 0 ], [ -2, 1, 0, 0, 0, 0 ] ], 0.125 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ -1, 0, 0, 0, -1, 0 ], [ -2, 1, 0, 0, 0, 0 ] ], 0.375 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, -1 ], [ -2, 1, 0, 0, 0, 0 ] ], 0.375 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ -1, 0, 0, 0, 0, -1 ], [ -2, 1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ -2, 1, 0, 0, 1, 0 ], [ -2, 1, 0, 0, 0, 0 ] ], 0.125 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ -1, 0, 1, 0, 0, 0 ], [ -2, 1, 0, 0, 0, 0 ] ], 0.125 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ -1, -1, 0, 0, 0, 0 ], [ -2, 1, 0, 0, 0, 0 ] ], 0.375 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ "Rest" ], [ -1, -1, 0, 0, 0, 0 ], [ -2, 1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ -1, -1, 0, 0, 0, 0 ], [ -2, 1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ -1, -1, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 5.375 ] ] ] ], "last_changes": [ - [ [ 3, -3, 1, -2, 1, -1 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 1, -3, 1, 0, 1, 0 ] ], - [ [ 3, -3, 1, -2, 1, -1 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 1, 0, 1, -2, 1, 0 ] ], - [ [ 3, -3, 1, -2, 1, -1 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 0, 0, 2, -2, 2, 0 ] ], - [ [ 3, -4, 1, -2, 1, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 0, 0, 2, -2, 2, 0 ] ], - [ [ 3, -3, 1, -2, 0, 0 ], [ 3, -3, 1, -2, 1, 0 ], [ 0, 0, 2, -2, 1, 0 ], [ 0, 0, 2, -2, 2, 0 ] ] + [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, -1 ], [ -2, 1, 0, 0, 0, 0 ] ], + [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ -1, 0, 0, 0, 0, -1 ], [ -2, 1, 0, 0, 0, 0 ] ], + [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ -2, 1, 0, 0, 1, 0 ], [ -2, 1, 0, 0, 0, 0 ] ], + [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ -1, 0, 1, 0, 0, 0 ], [ -2, 1, 0, 0, 0, 0 ] ], + [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ -1, -1, 0, 0, 0, 0 ], [ -2, 1, 0, 0, 0, 0 ] ] ], "cur_uid": "tmp", -"ref_uid": "6ed95c4c", -"order_seed": 290117, -"dur_seed": 200959, -"motifs_seed": 970117, -"entrances_probs_vals": [ 0.75, 0, 5.0793650793651, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], -"passages_probs_vals": [ 0.27, 0, 2.7380952380952, 0.24725274725275, 1.48, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], -"exits_probs_vals": [ 0.27, 0, 2.7380952380952, 0.24725274725275, 1.48, 0.20725388601036, 0.68581081081081, 0.24093264248705, 0.34121621621622, 0.5, 0.5, 0.67616580310881, 0.81081081081081, 1, 0.5 ], -"ranges": [ [ -1482.3529411765, 542 ], [ -1129.4117647059, 1378 ], [ -256.34674922601, 1601 ], [ -238, 1712.693498452 ] ], -"step_probs_vals": [ -1200, 1200, 0, 0, 0.19135802469136, 0.27272727272727, 0.2962962962963, 0, 0.33539094650206, 0, 0.34362139917695, 0, 0.38271604938272, 0.15340909090909, 0.39711934156379, 0.56818181818182, 0.43415637860082, 0, 0.51028806584362, 0, 0.56172839506173, 0.84090909090909, 0.61316872427984, 0, 0.69135802469136, 0.28977272727273, 0.73662551440329, 0, 0.97736625514403, 0 ], +"ref_uid": "nil", +"order_seed": 199504, +"dur_seed": 236250, +"motifs_seed": 783592, +"entrances_probs_vals": [ 0.75, 0, 0, 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, 0, 0, 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, 0, 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 ], [ 0, 0 ], [ 3, 1 ] ], - [ [ 0, 3, 1 ], [ 2, 2 ], [ ] ], - [ [ 1, 3, 2 ], [ 0, 0 ], [ ] ], - [ [ 2, 0, 1 ], [ 3, 3 ], [ ] ], - [ [ 3, 1, 2 ], [ 0, 0 ], [ ] ], - [ [ 0, 2, 1 ], [ 3, 3 ], [ ] ], - [ [ 2, 3, 1 ], [ 0, 0 ], [ ] ] + [ [ 1, 2 ], [ 0 ], [ 3 ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 0, 3, 2 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], [ ] ], + [ [ 0, 2, 1 ], [ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ], [ ] ] ], -"sus_weights": [ 0.45, 0.3, 0.38 ], -"order_size": [ 6.0510204081633, 15.142857142857 ], -"passages_size": [ 1, 1 ], +"sus_weights": [ 0.75, 0.69, 0.75 ], +"order_size": [ 2.0102040816327, 6.0510204081633 ], +"passages_size": [ 0, 10 ], "motif_edited": "false", "order_edited": "false" } \ No newline at end of file diff --git a/resources/string_quartet_2/4c059f33/4c059f33_mus_model.json b/resources/string_quartet_2/4c059f33/4c059f33_mus_model.json index fd5c9df..772a988 100644 --- a/resources/string_quartet_2/4c059f33/4c059f33_mus_model.json +++ b/resources/string_quartet_2/4c059f33/4c059f33_mus_model.json @@ -4,22 +4,22 @@ [ [ [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 3, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ] ], 4.875 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ "Rest" ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 0, 0 ] ], 4.875 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -2, 3, -1, -1, 1, 0 ] ], 4.75 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ 0, 3, -2, -1, 0, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 4, -2, -1, 1, 0 ] ], 4.75 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 4.125 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], - [ [ [ "Rest" ], [ -1, 3, -3, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], - [ [ [ "Rest" ], [ -1, 3, -3, -1, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ 0, 3, -3, -1, 1, 0 ] ], 4.125 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ "Rest" ], [ 0, 3, -3, -1, 1, 0 ] ], 0 ], + [ [ [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ], [ "Rest" ], [ 0, 3, -3, -1, 1, 0 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 3, -3, -1, 1, 0 ] ], 0 ] ] ] ], diff --git a/resources/string_quartet_2/4c059f33/lilypond/part_I.ly b/resources/string_quartet_2/4c059f33/lilypond/part_I.ly index e46bd01..9587605 100644 --- a/resources/string_quartet_2/4c059f33/lilypond/part_I.ly +++ b/resources/string_quartet_2/4c059f33/lilypond/part_I.ly @@ -1,16 +1,16 @@ { - { r2 a2^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { r2 e'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } \bar "|" - { a1 ~ } + { e'1 ~ } \bar "|" - { a2. ~ a8.[ cis16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ } + { e'2. ~ e'8.[ e'16^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } \bar "|" - { cis1 ~ } + { e'1 ~ } \bar "|" - { cis1 ~ } + { e'1 ~ } \bar "|" - { cis4 ~ cis16[ cis8.^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ cis2 ~ } + { e'4 ~ e'16[ f'8.^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ f'2 ~ } \bar "|" - { cis1} + { f'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_2/4c059f33/lilypond/part_II.ly b/resources/string_quartet_2/4c059f33/lilypond/part_II.ly index c17645f..3515b71 100644 --- a/resources/string_quartet_2/4c059f33/lilypond/part_II.ly +++ b/resources/string_quartet_2/4c059f33/lilypond/part_II.ly @@ -1,16 +1,16 @@ { - { r2 cis2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + { r2 cis'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } \bar "|" - { cis1 ~ } + { cis'1 ~ } \bar "|" - { cis2. ~ cis8.[ cis16^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ } + { cis'2. ~ cis'8.[ cis'16^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ } \bar "|" - { cis1 ~ } + { cis'1 ~ } \bar "|" - { cis1 ~ } + { cis'1 ~ } \bar "|" - { cis4 ~ cis16[ d8.^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ d2 ~ } + { cis'4 ~ cis'16[ d'8.^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ d'2 ~ } \bar "|" - { d1} + { d'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_2/4c059f33/lilypond/part_III.ly b/resources/string_quartet_2/4c059f33/lilypond/part_III.ly index f07edd8..e46bd01 100644 --- a/resources/string_quartet_2/4c059f33/lilypond/part_III.ly +++ b/resources/string_quartet_2/4c059f33/lilypond/part_III.ly @@ -1,16 +1,16 @@ { - { r2 e2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + { r2 a2^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { e1 ~ } + { a1 ~ } \bar "|" - { e2. ~ e8.[ e16^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } + { a2. ~ a8.[ cis16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ } \bar "|" - { e1 ~ } + { cis1 ~ } \bar "|" - { e1 ~ } + { cis1 ~ } \bar "|" - { e4 ~ e16[ f8.^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ f2 ~ } + { cis4 ~ cis16[ cis8.^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ cis2 ~ } \bar "|" - { f1} + { cis1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_2/60adbbef/60adbbef_mus_model.json b/resources/string_quartet_2/60adbbef/60adbbef_mus_model.json index 748c135..494aac6 100644 --- a/resources/string_quartet_2/60adbbef/60adbbef_mus_model.json +++ b/resources/string_quartet_2/60adbbef/60adbbef_mus_model.json @@ -4,27 +4,27 @@ [ [ [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.75 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 4.75 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ "Rest" ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 1, 0 ] ], 4.75 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 2, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ] ], 7.125 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 1 ] ], 7.125 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -2, 3, -2, -1, 2, 0 ], [ -1, 3, -3, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -2, 3, -2, -1, 2, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -2, 3, -2, -1, 2, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], 4.5 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -1, 3, -2, -1, 1, 1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 3, -2, -1, 2, 0 ], [ -1, 3, -2, -1, 1, 1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 3, -2, -1, 2, 0 ], [ -1, 3, -2, 0, 1, 0 ] ], 4.5 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 6.875 ], - [ [ [ "Rest" ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], - [ [ [ "Rest" ], [ -1, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], - [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ 0, 3, -2, -1, 0, 0 ], [ -1, 3, -2, 0, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 0, 0 ], [ -1, 3, -2, 0, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 0, 0 ], [ 0, 3, -2, -1, 1, 0 ] ], 6.875 ], + [ [ [ "Rest" ], [ -1, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 0, 0 ], [ 0, 3, -2, -1, 1, 0 ] ], 0 ], + [ [ [ "Rest" ], [ -1, 3, -1, -1, 1, 0 ], [ "Rest" ], [ 0, 3, -2, -1, 1, 0 ] ], 0 ], + [ [ [ "Rest" ], [ -1, 3, -1, -1, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 10.75 ] ] ] diff --git a/resources/string_quartet_2/60adbbef/lilypond/part_I.ly b/resources/string_quartet_2/60adbbef/lilypond/part_I.ly index 708ce11..eafa3f1 100644 --- a/resources/string_quartet_2/60adbbef/lilypond/part_I.ly +++ b/resources/string_quartet_2/60adbbef/lilypond/part_I.ly @@ -1,31 +1,31 @@ { { r1 } \bar "|" - { r2. r8[ e8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } + { r2. r8[ a'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ } \bar "|" - { e1 ~ } + { a'1 ~ } \bar "|" - { e1 ~ } + { a'1 ~ } \bar "|" - { e4 f2.^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + { a'4 fis'2.^\markup { \pad-markup #0.2 "-44"} ~ } \bar "|" - { f1 ~ } + { fis'1 ~ } \bar "|" - { f1 ~ } + { fis'1 ~ } \bar "|" - { f2. ~ f16[ cis'8.^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ } + { fis'2. ~ fis'16[ g'8.^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ } \bar "|" - { cis'1 ~ } + { g'1 ~ } \bar "|" - { cis'1 ~ } + { g'1 ~ } \bar "|" - { cis'16[ cis'8.^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ cis'2. ~ } + { g'16[ a'8.^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ a'2. ~ } \bar "|" - { cis'1 ~ } + { a'1 ~ } \bar "|" - { cis'1 ~ } + { a'1 ~ } \bar "|" - { cis'2 r2 } + { a'2 r2 } \bar "|" { r1 } \bar "|" diff --git a/resources/string_quartet_2/60adbbef/lilypond/part_II.ly b/resources/string_quartet_2/60adbbef/lilypond/part_II.ly index 7fea40e..3f5836d 100644 --- a/resources/string_quartet_2/60adbbef/lilypond/part_II.ly +++ b/resources/string_quartet_2/60adbbef/lilypond/part_II.ly @@ -1,31 +1,31 @@ { { r1 } \bar "|" - { r2. r8[ cis8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ } + { r2. r8[ cis'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ } \bar "|" - { cis1 ~ } + { cis'1 ~ } \bar "|" - { cis1 ~ } + { cis'1 ~ } \bar "|" - { cis4 d2.^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + { cis'4 d'2.^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } \bar "|" - { d1 ~ } + { d'1 ~ } \bar "|" - { d1 ~ } + { d'1 ~ } \bar "|" - { d2. ~ d16[ dis8.^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ } + { d'2. ~ d'16[ dis'8.^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ } \bar "|" - { dis1 ~ } + { dis'1 ~ } \bar "|" - { dis1 ~ } + { dis'1 ~ } \bar "|" - { dis16[ e8.^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] ~ e2. ~ } + { dis'16[ e'8.^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] ~ e'2. ~ } \bar "|" - { e1 ~ } + { e'1 ~ } \bar "|" - { e1 ~ } + { e'1 ~ } \bar "|" - { e2 r2 } + { e'2 r2 } \bar "|" { r1 } \bar "|" diff --git a/resources/string_quartet_2/60adbbef/lilypond/part_III.ly b/resources/string_quartet_2/60adbbef/lilypond/part_III.ly index dde5fb8..708ce11 100644 --- a/resources/string_quartet_2/60adbbef/lilypond/part_III.ly +++ b/resources/string_quartet_2/60adbbef/lilypond/part_III.ly @@ -1,31 +1,31 @@ { { r1 } \bar "|" - { r2. r8[ a8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ } + { r2. r8[ e8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } \bar "|" - { a1 ~ } + { e1 ~ } \bar "|" - { a1 ~ } + { e1 ~ } \bar "|" - { a4 fis2.^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ } + { e4 f2.^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } \bar "|" - { fis1 ~ } + { f1 ~ } \bar "|" - { fis1 ~ } + { f1 ~ } \bar "|" - { fis2. ~ fis16[ g8.^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ } + { f2. ~ f16[ cis'8.^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ } \bar "|" - { g1 ~ } + { cis'1 ~ } \bar "|" - { g1 ~ } + { cis'1 ~ } \bar "|" - { g16[ a8.^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ a2. ~ } + { cis'16[ cis'8.^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ cis'2. ~ } \bar "|" - { a1 ~ } + { cis'1 ~ } \bar "|" - { a1 ~ } + { cis'1 ~ } \bar "|" - { a2 r2 } + { cis'2 r2 } \bar "|" { r1 } \bar "|" diff --git a/resources/string_quartet_2/62300302/62300302_mus_model.json b/resources/string_quartet_2/62300302/62300302_mus_model.json index dfaef7d..da50172 100644 --- a/resources/string_quartet_2/62300302/62300302_mus_model.json +++ b/resources/string_quartet_2/62300302/62300302_mus_model.json @@ -4,36 +4,36 @@ [ [ [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 2.25 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 3, -2, 0, 1, 0 ] ], 1.5 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ 0, 2, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ] ], 1.875 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 2, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ] ], 2.625 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 1.5 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ "Rest" ] ], 1.875 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ] ], 2.625 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 2, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 3, -2, 0, 1, 0 ] ], 1.25 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 3, -2, 0, 1, 0 ] ], 1.5 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -1, 3, -2, -2, 1, 0 ] ], 2.25 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -1, 3, -2, -1, 2, 0 ] ], 1.25 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ 0, 3, -2, -1, 0, 0 ] ], 1.5 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ 0, 3, -2, -1, 0, 0 ] ], 2.25 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ 0, 3, -2, -1, 0, 0 ], [ -1, 3, -2, -2, 1, 0 ] ], 1.5 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ 0, 3, -2, -1, 0, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 2 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 0, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 1.75 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 0, 0 ], [ 0, 3, -2, -1, 0, 0 ] ], 1.5 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 3, -2, -1, 0, 0 ], [ 0, 3, -2, -1, 0, 0 ] ], 2 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 3, -2, -1, 0, 0 ], [ -1, 4, -2, -1, 1, 0 ] ], 1.75 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 1.375 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 2.125 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -2, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 1.125 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 3, -2, -2, 1, 0 ], [ -1, 4, -2, -1, 1, 0 ] ], 1.375 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -1, 4, -2, -1, 1, 0 ] ], 2.125 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -1, 3, -2, -1, 1, 1 ] ], 1.125 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 2, -2, -1, 1, 0 ] ], 2.125 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 2, -2, -1, 1, 0 ] ], 1.75 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -2, 3, -2, -1, 2, 0 ] ], 2 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 3, -2, -1, 1, 1 ] ], 2.125 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 3, -2, 0, 1, 0 ] ], 1.75 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 2, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 3, -2, 0, 1, 0 ] ], 2 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 3, -2, -1, 0, 0 ] ], 1 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 1 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 1.5 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 0, 0 ] ], 1 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 1.375 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 3, -2, 0, 1, 0 ] ], 1 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, 0, 1, 0 ] ], 1 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, 0 ] ], 1.5 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ "Rest" ], [ 0, 3, -2, -1, 1, 0 ] ], 1 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 3, -2, -1, 1, 0 ] ], 1.375 ], [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ] ] diff --git a/resources/string_quartet_2/62300302/lilypond/part_I.ly b/resources/string_quartet_2/62300302/lilypond/part_I.ly index f4f96ba..0afcad2 100644 --- a/resources/string_quartet_2/62300302/lilypond/part_I.ly +++ b/resources/string_quartet_2/62300302/lilypond/part_I.ly @@ -1,36 +1,36 @@ { { r1 } \bar "|" - { r8[ g8^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ g2. ~ } + { r1 } \bar "|" - { g1 ~ } + { r2. r16[ dis'8.^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ } \bar "|" - { g1 ~ } + { dis'1 ~ } \bar "|" - { g1 ~ } + { dis'2. e'4^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } \bar "|" - { g2 b,2^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + { e'1 ~ } \bar "|" - { b,1 ~ } + { e'1 ~ } \bar "|" - { b,4 ~ b,8[ cis8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ cis2 ~ } + { e'1 ~ } \bar "|" - { cis1 ~ } + { e'4 ~ e'8[ e'8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ e'2 ~ } \bar "|" - { cis2. ~ cis8.[ d16^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ } + { e'1 ~ } \bar "|" - { d1 ~ } + { e'1 } \bar "|" - { d1 ~ } + { fis'1^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ } \bar "|" - { d1 ~ } + { fis'2 ~ fis'8[ g'8^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ g'4 ~ } \bar "|" - { d2 dis2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + { g'1 ~ } \bar "|" - { dis2 e2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + { g'1 ~ } \bar "|" - { e1 ~ } + { g'2 a'2^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { e2. r4} + { a'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_2/62300302/lilypond/part_II.ly b/resources/string_quartet_2/62300302/lilypond/part_II.ly index 158f676..8af6926 100644 --- a/resources/string_quartet_2/62300302/lilypond/part_II.ly +++ b/resources/string_quartet_2/62300302/lilypond/part_II.ly @@ -7,11 +7,11 @@ \bar "|" { d'1 ~ } \bar "|" - { d'8[ dis'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ dis'2. ~ } + { d'8[ dis'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ dis'2. ~ } \bar "|" { dis'1 ~ } \bar "|" - { dis'2 ~ dis'8[ e'8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ e'4 ~ } + { dis'2 ~ dis'8[ e'8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ e'4 ~ } \bar "|" { e'1 ~ } \bar "|" diff --git a/resources/string_quartet_2/62300302/lilypond/part_III.ly b/resources/string_quartet_2/62300302/lilypond/part_III.ly index cebac3f..a6fa808 100644 --- a/resources/string_quartet_2/62300302/lilypond/part_III.ly +++ b/resources/string_quartet_2/62300302/lilypond/part_III.ly @@ -1,36 +1,36 @@ { { r1 } \bar "|" - { r1 } + { r8[ g8^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ g2. ~ } \bar "|" - { r2. r16[ dis8.^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ } + { g1 ~ } \bar "|" - { dis1 ~ } + { g1 ~ } \bar "|" - { dis2. e4^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + { g1 ~ } \bar "|" - { e1 ~ } + { g2 cis2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } \bar "|" - { e1 ~ } + { cis1 ~ } \bar "|" - { e1 ~ } + { cis4 ~ cis8[ cis8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ cis2 ~ } \bar "|" - { e4 ~ e8[ e8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ e2 ~ } + { cis1 ~ } \bar "|" - { e1 ~ } + { cis2. ~ cis8.[ d16^\markup { \pad-markup #0.2 "+14"}] ~ } \bar "|" - { e1 } + { d1 ~ } \bar "|" - { fis1^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ } + { d1 ~ } \bar "|" - { fis2 ~ fis8[ g8^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ g4 ~ } + { d1 ~ } \bar "|" - { g1 ~ } + { d2 dis2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } \bar "|" - { g1 ~ } + { dis2 e2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } \bar "|" - { g2 a2^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { e1 ~ } \bar "|" - { a1} + { e2. r4} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_2/628706ec/628706ec_mus_model.json b/resources/string_quartet_2/628706ec/628706ec_mus_model.json index 7226160..8b61d7a 100644 --- a/resources/string_quartet_2/628706ec/628706ec_mus_model.json +++ b/resources/string_quartet_2/628706ec/628706ec_mus_model.json @@ -4,10 +4,10 @@ [ [ [ [ [ "Rest" ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 1.5 ], - [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 1.25 ], - [ [ [ -1, 2, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 2, -1, 0, 0, 0 ] ], 0.5 ], - [ [ [ 1, 2, -1, -1, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 2, -1, 0, 0, 0 ] ], 0.875 ], - [ [ [ 1, 2, -1, -1, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 2, -1, 0, 0, 1 ] ], 1.25 ], + [ [ [ "Rest" ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 1.25 ], + [ [ [ "Rest" ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 2, -1, 0, 0, 0 ] ], 0.5 ], + [ [ [ "Rest" ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 2, -1, 0, 0, 0 ] ], 0.875 ], + [ [ [ "Rest" ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 2, -1, 0, 0, 1 ] ], 1.25 ], [ [ [ -1, 3, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 2, -1, 0, 0, 1 ] ], 0 ] ], [ @@ -38,8 +38,8 @@ ], [ [ [ [ 0, 1, -1, -1, 1, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ "Rest" ], [ 1, 2, 0, -1, 0, 0 ] ], 1.125 ], - [ [ [ -1, 2, -1, 0, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ "Rest" ], [ 1, 2, 0, -1, 0, 0 ] ], 1.375 ], - [ [ [ -1, 2, -1, 0, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ 0, 2, -1, -1, 0, 1 ], [ 1, 2, 0, -1, 0, 0 ] ], 0.25 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ "Rest" ], [ 1, 2, 0, -1, 0, 0 ] ], 0.375 ], + [ [ [ -1, 2, -1, 0, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ 0, 2, -1, -1, 0, 1 ], [ 1, 2, 0, -1, 0, 0 ] ], 1.25 ], [ [ [ -1, 2, -1, 0, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 1, 2, 0, -1, 0, 0 ] ], 0.625 ], [ [ [ -1, 2, -1, 0, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 1, 2, -1, 0, 0, 0 ] ], 0.375 ], [ [ [ -1, 2, -1, 0, 0, 0 ], [ 1, 2, -1, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 1, 2, -1, -1, 0, 1 ] ], 0.125 ], diff --git a/resources/string_quartet_2/628706ec/lilypond/part_I.ly b/resources/string_quartet_2/628706ec/lilypond/part_I.ly index 5057e30..b1f09ad 100644 --- a/resources/string_quartet_2/628706ec/lilypond/part_I.ly +++ b/resources/string_quartet_2/628706ec/lilypond/part_I.ly @@ -1,7 +1,7 @@ { { r1 } \bar "|" - { r4 r8[ ais''8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ ais''2 ~ } + { r4 r8[ ais''8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ ais''2 ~ } \bar "|" { ais''16[ g''8.^\markup { \pad-markup #0.2 "-42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}] ~ g''4 ~ g''8.[ r16] r4 } \bar "|" diff --git a/resources/string_quartet_2/628706ec/lilypond/part_II.ly b/resources/string_quartet_2/628706ec/lilypond/part_II.ly index 488d911..683f9b3 100644 --- a/resources/string_quartet_2/628706ec/lilypond/part_II.ly +++ b/resources/string_quartet_2/628706ec/lilypond/part_II.ly @@ -19,9 +19,9 @@ \bar "|" { r1 } \bar "|" - { r1 } + { r2 r16[ a'8.^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}] ~ a'4 ~ } \bar "|" - { r16[ a'8^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }} a'16^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] ~ a'2. ~ } + { a'8.[ a'16^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] ~ a'2. ~ } \bar "|" { a'2 gis'2^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" diff --git a/resources/string_quartet_2/628706ec/lilypond/part_IV.ly b/resources/string_quartet_2/628706ec/lilypond/part_IV.ly index ce23b81..82a09f8 100644 --- a/resources/string_quartet_2/628706ec/lilypond/part_IV.ly +++ b/resources/string_quartet_2/628706ec/lilypond/part_IV.ly @@ -1,9 +1,9 @@ { - { r2. ais4^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { r1 } \bar "|" - { ais2 ~ ais8[ c''8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }}] ~ c''4 ~ } + { r1 } \bar "|" - { c''2 ~ c''8.[ f'16^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ f'4 ~ } + { r2 r8.[ f'16^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ f'4 ~ } \bar "|" { f'2. f'4^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } \bar "|" diff --git a/resources/string_quartet_2/72dc057f/72dc057f_mus_model.json b/resources/string_quartet_2/72dc057f/72dc057f_mus_model.json index 5541d17..161771f 100644 --- a/resources/string_quartet_2/72dc057f/72dc057f_mus_model.json +++ b/resources/string_quartet_2/72dc057f/72dc057f_mus_model.json @@ -4,21 +4,21 @@ [ [ [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 5 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 6.875 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ 0, 3, -2, -1, 2, 0 ], [ -1, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 2, 0 ], [ -1, 4, -2, -1, 1, 0 ] ], 6.875 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 3.875 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ 0, 3, -1, -1, 1, 0 ], [ -1, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ 0, 3, -1, -1, 1, 0 ], [ -1, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ 0, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 0, 0 ] ], 3.875 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 6.125 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ 1, 2, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 0, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ 1, 2, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -3, -1, 1, 0 ], [ 1, 2, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ] ], 6.125 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ 1, 2, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 2, -2, -1, 1, 0 ] ], 0 ], [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 6.125 ] ] diff --git a/resources/string_quartet_2/72dc057f/lilypond/part_I.ly b/resources/string_quartet_2/72dc057f/lilypond/part_I.ly index 91049e5..5c2e756 100644 --- a/resources/string_quartet_2/72dc057f/lilypond/part_I.ly +++ b/resources/string_quartet_2/72dc057f/lilypond/part_I.ly @@ -3,23 +3,23 @@ \bar "|" { r1 } \bar "|" - { r2 e2^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { r2 e'2^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { e1 ~ } + { e'1 ~ } \bar "|" - { e1 ~ } + { e'1 ~ } \bar "|" - { e2. ~ e8.[ e16^\markup { \pad-markup #0.2 "-36"}] ~ } + { e'2. ~ e'8.[ e'16^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] ~ } \bar "|" - { e1 ~ } + { e'1 ~ } \bar "|" - { e2. ~ e8[ d8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ } + { e'2. ~ e'8[ d'8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ } \bar "|" - { d1 ~ } + { d'1 ~ } \bar "|" - { d1 ~ } + { d'1 ~ } \bar "|" - { d2. ~ d8.[ r16] } + { d'2. ~ d'8.[ r16] } \bar "|" { r1 } \bar "|" diff --git a/resources/string_quartet_2/72dc057f/lilypond/part_II.ly b/resources/string_quartet_2/72dc057f/lilypond/part_II.ly index 80a76d1..101d6df 100644 --- a/resources/string_quartet_2/72dc057f/lilypond/part_II.ly +++ b/resources/string_quartet_2/72dc057f/lilypond/part_II.ly @@ -3,23 +3,23 @@ \bar "|" { r1 } \bar "|" - { r2 dis'2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + { r2 dis''2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } \bar "|" - { dis'1 ~ } + { dis''1 ~ } \bar "|" - { dis'1 ~ } + { dis''1 ~ } \bar "|" - { dis'2. ~ dis'8.[ cis'16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ } + { dis''2. ~ dis''8.[ cis''16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ } \bar "|" - { cis'1 ~ } + { cis''1 ~ } \bar "|" - { cis'2. ~ cis'8[ d'8^\markup { \pad-markup #0.2 "+14"}] ~ } + { cis''2. ~ cis''8[ d''8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ } \bar "|" - { d'1 ~ } + { d''1 ~ } \bar "|" - { d'1 ~ } + { d''1 ~ } \bar "|" - { d'2. ~ d'8.[ r16] } + { d''2. ~ d''8.[ r16] } \bar "|" { r1 } \bar "|" diff --git a/resources/string_quartet_2/72dc057f/lilypond/part_III.ly b/resources/string_quartet_2/72dc057f/lilypond/part_III.ly index 0b76537..e774c53 100644 --- a/resources/string_quartet_2/72dc057f/lilypond/part_III.ly +++ b/resources/string_quartet_2/72dc057f/lilypond/part_III.ly @@ -3,23 +3,23 @@ \bar "|" { r1 } \bar "|" - { r2 cis2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + { r2 cis'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } \bar "|" - { cis1 ~ } + { cis'1 ~ } \bar "|" - { cis1 ~ } + { cis'1 ~ } \bar "|" - { cis2. ~ cis8.[ cis16^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ } + { cis'2. ~ cis'8.[ cis'16^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ } \bar "|" - { cis1 ~ } + { cis'1 ~ } \bar "|" - { cis2. ~ cis8[ f8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ } + { cis'2. ~ cis'8[ f'8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ } \bar "|" - { f1 ~ } + { f'1 ~ } \bar "|" - { f1 ~ } + { f'1 ~ } \bar "|" - { f2. ~ f8.[ r16] } + { f'2. ~ f'8.[ r16] } \bar "|" { r1 } \bar "|" diff --git a/resources/string_quartet_2/74b8f8d9/74b8f8d9_mus_model.json b/resources/string_quartet_2/74b8f8d9/74b8f8d9_mus_model.json index c472d47..239177d 100644 --- a/resources/string_quartet_2/74b8f8d9/74b8f8d9_mus_model.json +++ b/resources/string_quartet_2/74b8f8d9/74b8f8d9_mus_model.json @@ -4,37 +4,37 @@ [ [ [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.75 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 4.75 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ "Rest" ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 1, 0 ] ], 4.75 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 2, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ] ], 7.125 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 1 ] ], 7.125 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -2, 3, -2, -1, 2, 0 ], [ -1, 3, -3, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -2, 3, -2, -1, 2, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -2, 3, -2, -1, 2, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], 4.5 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -1, 3, -2, -1, 1, 1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 3, -2, -1, 2, 0 ], [ -1, 3, -2, -1, 1, 1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ -1, 3, -2, -1, 2, 0 ], [ -1, 3, -2, 0, 1, 0 ] ], 4.5 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 6.875 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ 0, 3, -2, -1, 0, 0 ], [ -1, 3, -2, 0, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 0, 0 ], [ -1, 3, -2, 0, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 0, 0 ], [ 0, 3, -2, -1, 1, 0 ] ], 6.875 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ] ], 5.25 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ -1, 4, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ -1, 4, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 4, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 5.25 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -3, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -3, -1, 1, 0 ] ], 6.125 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ "Rest" ] ], 0 ], - [ [ [ "Rest" ], [ -1, 2, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ "Rest" ] ], 0 ], - [ [ [ "Rest" ], [ -1, 2, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ -1, 4, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 1 ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 1 ], [ 0, 2, -2, -1, 1, 0 ] ], 6.125 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 1, 1 ], [ 0, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ -1, 3, -2, -1, 1, 1 ], [ 0, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 2, -2, -1, 1, 0 ] ], 0 ], [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 10.125 ] ] ] diff --git a/resources/string_quartet_2/74b8f8d9/lilypond/part_I.ly b/resources/string_quartet_2/74b8f8d9/lilypond/part_I.ly index 2d48723..1e8996c 100644 --- a/resources/string_quartet_2/74b8f8d9/lilypond/part_I.ly +++ b/resources/string_quartet_2/74b8f8d9/lilypond/part_I.ly @@ -1,43 +1,43 @@ { { r1 } \bar "|" - { r2. r8[ e8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } + { r2. r8[ a'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ } \bar "|" - { e1 ~ } + { a'1 ~ } \bar "|" - { e1 ~ } + { a'1 ~ } \bar "|" - { e4 f2.^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + { a'4 fis'2.^\markup { \pad-markup #0.2 "-44"} ~ } \bar "|" - { f1 ~ } + { fis'1 ~ } \bar "|" - { f1 ~ } + { fis'1 ~ } \bar "|" - { f2. ~ f16[ cis'8.^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ } + { fis'2. ~ fis'16[ g'8.^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ } \bar "|" - { cis'1 ~ } + { g'1 ~ } \bar "|" - { cis'1 ~ } + { g'1 ~ } + \bar "|" + { g'16[ a'8.^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ a'2. ~ } + \bar "|" + { a'1 ~ } \bar "|" - { cis'16[ cis'8.^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ cis'2. ~ } + { a'1 ~ } + \bar "|" + { a'2 cis'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" { cis'1 ~ } \bar "|" { cis'1 ~ } \bar "|" - { cis'2 d'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + { cis'8[ d'8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ d'2. ~ } \bar "|" { d'1 ~ } \bar "|" { d'1 ~ } \bar "|" - { d'8[ f8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ f2. ~ } - \bar "|" - { f1 ~ } - \bar "|" - { f1 ~ } - \bar "|" - { f8.[ r16] r2. } + { d'8.[ r16] r2. } \bar "|" { r1 } \bar "|" diff --git a/resources/string_quartet_2/74b8f8d9/lilypond/part_II.ly b/resources/string_quartet_2/74b8f8d9/lilypond/part_II.ly index 1c284cd..afb9df3 100644 --- a/resources/string_quartet_2/74b8f8d9/lilypond/part_II.ly +++ b/resources/string_quartet_2/74b8f8d9/lilypond/part_II.ly @@ -1,43 +1,43 @@ { { r1 } \bar "|" - { r2. r8[ cis8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ } + { r2. r8[ cis'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ } \bar "|" - { cis1 ~ } + { cis'1 ~ } \bar "|" - { cis1 ~ } + { cis'1 ~ } \bar "|" - { cis4 d2.^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + { cis'4 d'2.^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } \bar "|" - { d1 ~ } + { d'1 ~ } \bar "|" - { d1 ~ } + { d'1 ~ } \bar "|" - { d2. ~ d16[ dis8.^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ } + { d'2. ~ d'16[ dis'8.^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ } \bar "|" - { dis1 ~ } + { dis'1 ~ } \bar "|" - { dis1 ~ } + { dis'1 ~ } \bar "|" - { dis16[ e8.^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] ~ e2. ~ } + { dis'16[ e'8.^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] ~ e'2. ~ } \bar "|" - { e1 ~ } + { e'1 ~ } \bar "|" - { e1 ~ } + { e'1 ~ } \bar "|" - { e2 e2^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { e'2 e'2^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { e1 ~ } + { e'1 ~ } \bar "|" - { e1 ~ } + { e'1 ~ } \bar "|" - { e8[ fis8^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}] ~ fis2. ~ } + { e'8[ fis'8^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}] ~ fis'2. ~ } \bar "|" - { fis1 ~ } + { fis'1 ~ } \bar "|" - { fis1 ~ } + { fis'1 ~ } \bar "|" - { fis8.[ r16] r2. } + { fis'8.[ r16] r2. } \bar "|" { r1 } \bar "|" diff --git a/resources/string_quartet_2/74b8f8d9/lilypond/part_III.ly b/resources/string_quartet_2/74b8f8d9/lilypond/part_III.ly index ecf1ce2..2d48723 100644 --- a/resources/string_quartet_2/74b8f8d9/lilypond/part_III.ly +++ b/resources/string_quartet_2/74b8f8d9/lilypond/part_III.ly @@ -1,43 +1,43 @@ { { r1 } \bar "|" - { r2. r8[ a8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ } + { r2. r8[ e8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } \bar "|" - { a1 ~ } + { e1 ~ } \bar "|" - { a1 ~ } + { e1 ~ } \bar "|" - { a4 fis2.^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ } + { e4 f2.^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } \bar "|" - { fis1 ~ } + { f1 ~ } \bar "|" - { fis1 ~ } + { f1 ~ } \bar "|" - { fis2. ~ fis16[ g8.^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ } + { f2. ~ f16[ cis'8.^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ } \bar "|" - { g1 ~ } + { cis'1 ~ } \bar "|" - { g1 ~ } + { cis'1 ~ } \bar "|" - { g16[ a8.^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ a2. ~ } + { cis'16[ cis'8.^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ cis'2. ~ } \bar "|" - { a1 ~ } + { cis'1 ~ } \bar "|" - { a1 ~ } + { cis'1 ~ } \bar "|" - { a2 cis2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { cis'2 d'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } \bar "|" - { cis1 ~ } + { d'1 ~ } \bar "|" - { cis1 ~ } + { d'1 ~ } \bar "|" - { cis8[ d8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ d2. ~ } + { d'8[ f8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ f2. ~ } \bar "|" - { d1 ~ } + { f1 ~ } \bar "|" - { d1 ~ } + { f1 ~ } \bar "|" - { d8.[ r16] r2. } + { f8.[ r16] r2. } \bar "|" { r1 } \bar "|" diff --git a/resources/string_quartet_2/76e45e56/76e45e56_mus_model.json b/resources/string_quartet_2/76e45e56/76e45e56_mus_model.json index e1d66b2..646e00f 100644 --- a/resources/string_quartet_2/76e45e56/76e45e56_mus_model.json +++ b/resources/string_quartet_2/76e45e56/76e45e56_mus_model.json @@ -4,32 +4,32 @@ [ [ [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 7 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -1, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ 0, 3, -2, -1, 2, 0 ], [ -1, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 2, 0 ], [ -1, 4, -2, -1, 1, 0 ] ], 7 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 5.5 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ 0, 3, -1, -1, 1, 0 ], [ -1, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ 0, 3, -1, -1, 1, 0 ], [ -1, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ 0, 3, -1, -1, 1, 0 ], [ 0, 3, -2, -1, 0, 0 ] ], 5.5 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 4 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ 1, 2, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 0, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ], [ 1, 2, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -3, -1, 1, 0 ], [ 1, 2, -2, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ] ], 4 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -2, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 5.625 ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -3, -1, 1, 0 ], [ 1, 3, -2, -2, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ 0, 3, -3, -1, 1, 0 ], [ 1, 3, -2, -2, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 1 ], [ 1, 3, -2, -2, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 5.625 ] ], [ - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 6.5 ], - [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], - [ [ [ "Rest" ], [ -2, 3, -2, 0, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], - [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, 0, 1, 0 ], [ 0, 3, -2, -1, 1, 0 ], [ 0, 3, -2, -1, 1, -1 ] ], 6.5 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, 0, 1, 0 ], [ "Rest" ], [ 0, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ "Rest" ], [ -1, 3, -2, 0, 1, 0 ], [ "Rest" ], [ 0, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 3, -2, -1, 1, -1 ] ], 0 ], [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 6.375 ] ] ] diff --git a/resources/string_quartet_2/76e45e56/lilypond/part_I.ly b/resources/string_quartet_2/76e45e56/lilypond/part_I.ly new file mode 100644 index 0000000..3279f32 --- /dev/null +++ b/resources/string_quartet_2/76e45e56/lilypond/part_I.ly @@ -0,0 +1,38 @@ +{ + { r2 e'2^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 } + \bar "|" + { e'1^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2. d'4^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'2. cis'4^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'2 ~ cis'16[ cis'8.^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ cis'4 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'2. ~ cis'16[ r8.] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_2/76e45e56/lilypond/part_II.ly b/resources/string_quartet_2/76e45e56/lilypond/part_II.ly new file mode 100644 index 0000000..20c6582 --- /dev/null +++ b/resources/string_quartet_2/76e45e56/lilypond/part_II.ly @@ -0,0 +1,38 @@ +{ + { r2 dis''2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + \bar "|" + { dis''1 ~ } + \bar "|" + { dis''1 ~ } + \bar "|" + { dis''1 } + \bar "|" + { cis''1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''2. d''4^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { d''1 ~ } + \bar "|" + { d''2. b'4^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'2 ~ b'16[ a'8.^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ a'4 ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'2. ~ a'16[ r8.] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_2/76e45e56/lilypond/part_III.ly b/resources/string_quartet_2/76e45e56/lilypond/part_III.ly new file mode 100644 index 0000000..2edf028 --- /dev/null +++ b/resources/string_quartet_2/76e45e56/lilypond/part_III.ly @@ -0,0 +1,38 @@ +{ + { r2 cis'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 } + \bar "|" + { cis'1^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }} ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'2. f'4^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'2. fis'4^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'2 ~ fis'16[ g'8.^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ g'4 ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'2. ~ g'16[ r8.] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_2/76e45e56/lilypond/part_IV.ly b/resources/string_quartet_2/76e45e56/lilypond/part_IV.ly new file mode 100644 index 0000000..c9189fc --- /dev/null +++ b/resources/string_quartet_2/76e45e56/lilypond/part_IV.ly @@ -0,0 +1,38 @@ +{ + { a,1^\markup { \pad-markup #0.2 "+16"} ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,2. ~ a,16[ r8.] } + \bar "|" + { r1 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise.json b/resources/string_quartet_3_rise.json index 8607c63..f66928b 100644 --- a/resources/string_quartet_3_rise.json +++ b/resources/string_quartet_3_rise.json @@ -13,7 +13,11 @@ "78a94ed1", "531df78c", "7276dc78", - "43214be8", - "7c30c182" + "47bdba0e", + "5f3f1c84", + "4f53a446", + "731cf7ae", + "4da80bfb", + "624f7439" ] } \ No newline at end of file diff --git a/resources/string_quartet_3_rise.json_bak b/resources/string_quartet_3_rise.json_bak index d09baa2..a1aae83 100644 --- a/resources/string_quartet_3_rise.json_bak +++ b/resources/string_quartet_3_rise.json_bak @@ -13,6 +13,10 @@ "78a94ed1", "531df78c", "7276dc78", - "43214be8" + "47bdba0e", + "5f3f1c84", + "4f53a446", + "731cf7ae", + "4da80bfb" ] } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/43214be8/lilypond/part_I.ly b/resources/string_quartet_3_rise/43214be8/lilypond/part_I.ly index e9eae1a..3cb7b6a 100644 --- a/resources/string_quartet_3_rise/43214be8/lilypond/part_I.ly +++ b/resources/string_quartet_3_rise/43214be8/lilypond/part_I.ly @@ -1,48 +1,48 @@ { - { gis'1^\markup { \pad-markup #0.2 "-11"} } + { ais'1^\markup { \pad-markup #0.2 "-11"} } \bar "|" - { fis1^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} } + { gis1^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} } \bar "|" - { c'1^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + { d'1^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } \bar "|" - { c'2 fis'2^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { d'2 gis'2^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { fis'1 ~ } + { gis'1 ~ } \bar "|" - { fis'1 } + { gis'1 } \bar "|" - { b'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + { cis''1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } \bar "|" - { b'2 g2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + { cis''2 a2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g2 cis'2^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } + { a2 dis'2^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } \bar "|" - { a'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { b'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { a'2 ais'2^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { b'2 c''2^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { ais'1 ~ } + { c''1 ~ } \bar "|" - { ais'1 } + { c''1 } \bar "|" - { ais1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { c'1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { ais1 ~ } + { c'1 ~ } \bar "|" - { ais1 ~ } + { c'1 ~ } \bar "|" - { ais1 ~ } + { c'1 ~ } \bar "|" - { ais2 d'2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + { c'2 e'2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" - { d'2 g'2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { e'2 a'2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { g'2 b'2^\markup { \pad-markup #0.2 "+50"}} + { a'2 cis''2^\markup { \pad-markup #0.2 "+50"}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/43214be8/lilypond/part_II.ly b/resources/string_quartet_3_rise/43214be8/lilypond/part_II.ly index bd2901a..ca6cf66 100644 --- a/resources/string_quartet_3_rise/43214be8/lilypond/part_II.ly +++ b/resources/string_quartet_3_rise/43214be8/lilypond/part_II.ly @@ -1,48 +1,48 @@ { - { d'1^\markup { \pad-markup #0.2 "+38"} ~ } + { e'1^\markup { \pad-markup #0.2 "+38"} ~ } \bar "|" - { d'1 ~ } + { e'1 ~ } \bar "|" - { d'1 } + { e'1 } \bar "|" - { g'1^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + { a'1^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } \bar "|" - { g'1 } + { a'1 } \bar "|" - { b'1^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { cis''1^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { b'2 d'2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }} } + { cis''2 e'2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }} } \bar "|" - { a'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} } + { b'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} } \bar "|" - { f'1^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } + { g'1^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } \bar "|" - { f'1 } + { g'1 } \bar "|" - { f'1^\markup { \pad-markup #0.2 "-35"} ~ } + { g'1^\markup { \pad-markup #0.2 "-35"} ~ } \bar "|" - { f'1 ~ } + { g'1 ~ } \bar "|" - { f'1 } + { g'1 } \bar "|" - { b'1^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} } + { cis''1^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} } \bar "|" - { d'1^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} } + { e'1^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} } \bar "|" - { g1^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { a1^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g2 c'2^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + { a2 d'2^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } \bar "|" - { c'1 ~ } + { d'1 ~ } \bar "|" - { c'2 f'2^\markup { \pad-markup #0.2 "-35"} ~ } + { d'2 g'2^\markup { \pad-markup #0.2 "-35"} ~ } \bar "|" - { f'1 ~ } + { g'1 ~ } \bar "|" - { f'1 ~ } + { g'1 ~ } \bar "|" - { f'1} + { g'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/43214be8/lilypond/part_III.ly b/resources/string_quartet_3_rise/43214be8/lilypond/part_III.ly index 192a5db..e7f6e42 100644 --- a/resources/string_quartet_3_rise/43214be8/lilypond/part_III.ly +++ b/resources/string_quartet_3_rise/43214be8/lilypond/part_III.ly @@ -1,48 +1,48 @@ { - { g'1^\markup { \pad-markup #0.2 "+36"} ~ } + { a'1^\markup { \pad-markup #0.2 "+36"} ~ } \bar "|" - { g'2 b'2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + { a'2 cis''2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } \bar "|" - { b'1 ~ } + { cis''1 ~ } \bar "|" - { b'1 } + { cis''1 } \bar "|" - { a1^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } + { b1^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } \bar "|" - { a2 d'2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + { b2 e'2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } \bar "|" - { d'1 ~ } + { e'1 ~ } \bar "|" - { d'1 ~ } + { e'1 ~ } \bar "|" - { d'1 } + { e'1 } \bar "|" - { cis1^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }} ~ } + { dis1^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }} ~ } \bar "|" - { cis2 dis'2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} } + { dis2 f'2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} } \bar "|" - { ais'1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + { c''1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } \bar "|" - { ais'1 ~ } + { c''1 ~ } \bar "|" - { ais'1 ~ } + { c''1 ~ } \bar "|" - { ais'1 ~ } + { c''1 ~ } \bar "|" - { ais'1 ~ } + { c''1 ~ } \bar "|" - { ais'2 d2^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + { c''2 e2^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } \bar "|" - { d1 ~ } + { e1 ~ } \bar "|" - { d2 g2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } + { e2 a2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g1} + { a1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/43214be8/lilypond/part_IV.ly b/resources/string_quartet_3_rise/43214be8/lilypond/part_IV.ly index 534e787..00a5907 100644 --- a/resources/string_quartet_3_rise/43214be8/lilypond/part_IV.ly +++ b/resources/string_quartet_3_rise/43214be8/lilypond/part_IV.ly @@ -1,48 +1,48 @@ { - { ais,2^\markup { \pad-markup #0.2 "+21"} f2^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } + { c2^\markup { \pad-markup #0.2 "+21"} g2^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } \bar "|" - { f1 ~ } + { g1 ~ } \bar "|" - { f2 b2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { g2 cis'2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b2 e'2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + { cis'2 fis'2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } \bar "|" - { e'1 ~ } + { fis'1 ~ } \bar "|" - { e'1 ~ } + { fis'1 ~ } \bar "|" - { e'1 ~ } + { fis'1 ~ } \bar "|" - { e'2 d2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { fis'2 e2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { d2 a2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + { e2 b2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" - { a1 ~ } + { b1 ~ } \bar "|" - { a1 ~ } + { b1 ~ } \bar "|" - { a2 dis'2^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } + { b2 f'2^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } \bar "|" - { dis'1 ~ } + { f'1 ~ } \bar "|" - { dis'2 g'2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + { f'2 a'2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } \bar "|" - { g'2 e,2^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } + { a'2 fis,2^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } \bar "|" - { e,1 } + { fis,1 } \bar "|" - { ais,1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} } + { c1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} } \bar "|" - { e1^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} } + { fis1^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} } \bar "|" - { dis,1^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} } + { f,1^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} } \bar "|" - { b,1^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} } + { cis1^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} } \bar "|" - { c,1^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} } + { d,1^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} } \bar "|" - { f,1^\markup { \pad-markup #0.2 "+1"}} + { g,1^\markup { \pad-markup #0.2 "+1"}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/44490863/lilypond/part_I.ly b/resources/string_quartet_3_rise/44490863/lilypond/part_I.ly index a351af0..7554f1b 100644 --- a/resources/string_quartet_3_rise/44490863/lilypond/part_I.ly +++ b/resources/string_quartet_3_rise/44490863/lilypond/part_I.ly @@ -1,48 +1,48 @@ { - { b1^\markup { \pad-markup #0.2 "-12"} ~ } + { cis'1^\markup { \pad-markup #0.2 "-12"} ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b2 fis'2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } + { cis'2 gis'2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } \bar "|" - { fis'2^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} gis'2^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } + { gis'2^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ais'2^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } \bar "|" - { gis'2 b'2^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + { ais'2 cis''2^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } \bar "|" - { b'1 } + { cis''1 } \bar "|" - { fis1^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { gis1^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { fis2 ais2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } + { gis2 c'2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } \bar "|" - { ais1 } + { c'1 } \bar "|" - { cis'1^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { dis'1^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { cis'2 c''2^\markup { \pad-markup #0.2 "-20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + { dis'2 d''2^\markup { \pad-markup #0.2 "-20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } \bar "|" - { c''1 ~ } + { d''1 ~ } \bar "|" - { c''2 fis2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { d''2 gis2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { fis1 ~ } + { gis1 ~ } \bar "|" - { fis2 cis'2^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} } + { gis2 dis'2^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} } \bar "|" - { b'1^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + { cis''1^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } \bar "|" - { b'1 } + { cis''1 } \bar "|" - { a1^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { b1^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { a1 ~ } + { b1 ~ } \bar "|" - { a2 e'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} ~ } + { b2 fis'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} ~ } \bar "|" - { e'1 ~ } + { fis'1 ~ } \bar "|" - { e'1} + { fis'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/44490863/lilypond/part_II.ly b/resources/string_quartet_3_rise/44490863/lilypond/part_II.ly index 93d3bf8..38f577f 100644 --- a/resources/string_quartet_3_rise/44490863/lilypond/part_II.ly +++ b/resources/string_quartet_3_rise/44490863/lilypond/part_II.ly @@ -1,48 +1,48 @@ { - { g'1^\markup { \pad-markup #0.2 "+2"} ~ } + { a'1^\markup { \pad-markup #0.2 "+2"} ~ } \bar "|" - { g'1 ~ } + { a'1 ~ } \bar "|" - { g'2 b'2^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { a'2 cis''2^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } \bar "|" - { b'1 ~ } + { cis''1 ~ } \bar "|" - { b'1 } + { cis''1 } \bar "|" - { b1^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + { cis'1^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b2 cis'2^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + { cis'2 dis'2^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" - { cis'1 } + { dis'1 } \bar "|" - { d'1^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { e'1^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { d'1 } + { e'1 } \bar "|" - { f'1^\markup { \pad-markup #0.2 "-22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} ~ } + { g'1^\markup { \pad-markup #0.2 "-22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} ~ } \bar "|" - { f'2 b'2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } + { g'2 cis''2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } \bar "|" - { b'1 ~ } + { cis''1 ~ } \bar "|" - { b'2 fis'2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { cis''2 gis'2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } \bar "|" - { fis'1 ~ } + { gis'1 ~ } \bar "|" - { fis'1 } + { gis'1 } \bar "|" - { gis'1^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + { ais'1^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } \bar "|" - { gis'1 } + { ais'1 } \bar "|" - { a'1^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} } + { b'1^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} } \bar "|" - { c''1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + { d''1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } \bar "|" - { c''2 b'2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } + { d''2 cis''2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } \bar "|" - { b'1} + { cis''1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/44490863/lilypond/part_III.ly b/resources/string_quartet_3_rise/44490863/lilypond/part_III.ly index 606adf0..791ea32 100644 --- a/resources/string_quartet_3_rise/44490863/lilypond/part_III.ly +++ b/resources/string_quartet_3_rise/44490863/lilypond/part_III.ly @@ -1,48 +1,48 @@ { - { fis'1^\markup { \pad-markup #0.2 "-10"} } + { gis'1^\markup { \pad-markup #0.2 "-10"} } \bar "|" - { g2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} e'2^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + { a2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} fis'2^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } \bar "|" - { e'1 ~ } + { fis'1 ~ } \bar "|" - { e'1 ~ } + { fis'1 ~ } \bar "|" - { e'1 ~ } + { fis'1 ~ } \bar "|" - { e'1 ~ } + { fis'1 ~ } \bar "|" - { e'2 fis'2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { fis'2 gis'2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { fis'1 ~ } + { gis'1 ~ } \bar "|" - { fis'1 ~ } + { gis'1 ~ } \bar "|" - { fis'1 ~ } + { gis'1 ~ } \bar "|" - { fis'1 ~ } + { gis'1 ~ } \bar "|" - { fis'1 ~ } + { gis'1 ~ } \bar "|" - { fis'1 ~ } + { gis'1 ~ } \bar "|" - { fis'1 } + { gis'1 } \bar "|" - { fis'1^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + { gis'1^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } \bar "|" - { fis'1 ~ } + { gis'1 ~ } \bar "|" - { fis'1 ~ } + { gis'1 ~ } \bar "|" - { fis'2 a'2^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + { gis'2 b'2^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } \bar "|" - { a'2 b'2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { b'2 cis''2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { b'1 ~ } + { cis''1 ~ } \bar "|" - { b'1 } + { cis''1 } \bar "|" - { g1^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + { a1^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } \bar "|" - { g1} + { a1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/44490863/lilypond/part_IV.ly b/resources/string_quartet_3_rise/44490863/lilypond/part_IV.ly index b3eb4c8..24d5f90 100644 --- a/resources/string_quartet_3_rise/44490863/lilypond/part_IV.ly +++ b/resources/string_quartet_3_rise/44490863/lilypond/part_IV.ly @@ -1,48 +1,48 @@ { - { gis'2^\markup { \pad-markup #0.2 "-45"} b'2^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { ais'2^\markup { \pad-markup #0.2 "-45"} cis''2^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } \bar "|" - { b'1 } + { cis''1 } \bar "|" - { e1^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} } + { fis1^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} } \bar "|" - { fis1^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + { gis1^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } \bar "|" - { fis1 ~ } + { gis1 ~ } \bar "|" - { fis1 } + { gis1 } \bar "|" - { b,1^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + { cis1^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } \bar "|" - { b,1 } + { cis1 } \bar "|" - { d1^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + { e1^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } \bar "|" - { d2 fis2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { e2 gis2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { fis2 gis2^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } + { gis2 ais2^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } \bar "|" - { gis1 } + { ais1 } \bar "|" - { ais1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} } + { c'1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} } \bar "|" - { cis'1^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + { dis'1^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" - { cis'1 } + { dis'1 } \bar "|" - { ais'1^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } + { c''1^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } \bar "|" - { ais'2 b2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { c''2 cis'2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b2 d'2^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + { cis'2 e'2^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } \bar "|" - { d'1 ~ } + { e'1 ~ } \bar "|" - { d'1 } + { e'1 } \bar "|" - { a'2^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} e,2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}} + { b'2^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} fis,2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/47957a9d/47957a9d_code.scd b/resources/string_quartet_3_rise/47957a9d/47957a9d_code.scd new file mode 100644 index 0000000..070e09d --- /dev/null +++ b/resources/string_quartet_3_rise/47957a9d/47957a9d_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/47957a9d/47957a9d_mus_model.json b/resources/string_quartet_3_rise/47957a9d/47957a9d_mus_model.json new file mode 100644 index 0000000..67771a0 --- /dev/null +++ b/resources/string_quartet_3_rise/47957a9d/47957a9d_mus_model.json @@ -0,0 +1,465 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 3 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 3 ], [ -7, 5, 1, 4, -1, 3 ], [ -6, 5, 1, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 3 ], [ -7, 5, 1, 4, -1, 3 ], [ -7, 5, 1, 4, -1, 2 ] ], 0.25 ], + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 3 ], [ -7, 5, 1, 5, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 3 ], [ -7, 5, 1, 5, -1, 2 ], [ -7, 4, 1, 4, -1, 2 ] ], 0.25 ], + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 3 ], [ -7, 5, 1, 5, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 3 ], [ -6, 5, 0, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 5, 2, 5, -1, 2 ], [ -8, 5, 1, 4, -1, 3 ], [ -6, 5, 0, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -10, 5, 2, 5, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -6, 5, 0, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -10, 5, 2, 5, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -7, 5, 2, 4, 0, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -10, 5, 2, 5, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -10, 5, 2, 5, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -9, 5, 2, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 6, 2, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -9, 6, 2, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -9, 6, 2, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -9, 6, 2, 4, -1, 2 ], [ -8, 5, 2, 5, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 5, 2, 5, -1, 2 ], [ -8, 5, 2, 5, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -10, 5, 2, 5, -1, 2 ], [ -7, 4, 2, 4, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -10, 5, 2, 5, -1, 2 ], [ -7, 4, 2, 4, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -10, 5, 2, 5, -1, 2 ], [ -7, 4, 2, 4, -1, 2 ], [ -8, 5, 2, 5, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -9, 5, 2, 4, -1, 2 ], [ -7, 4, 2, 4, -1, 2 ], [ -8, 5, 2, 5, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 5, 2, 4, -1, 2 ], [ -7, 4, 2, 4, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -8, 4, 2, 4, -1, 2 ], [ -7, 4, 2, 4, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -8, 4, 2, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -8, 4, 2, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 4, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -9, 6, 2, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 4, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -8, 5, 1, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 4, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 5, 2, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 4, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -7, 5, 2, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -7, 5, 2, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ], [ -9, 7, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -7, 5, 2, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -7, 5, 2, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 6, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 2, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 6, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 2, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 6, 1, 4, -1, 2 ], [ -8, 6, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 2, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -8, 6, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 6, 1, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -8, 6, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 6, 1, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -7, 6, 1, 4, -1, 2 ] ], 0.25 ], + [ [ [ -8, 6, 1, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -8, 6, 1, 4, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 6, 2, 3, -1, 2 ], [ -8, 6, 2, 4, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 6, 2, 3, -1, 2 ], [ -8, 6, 2, 3, -1, 3 ], [ -7, 5, 2, 4, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 6, 2, 3, -1, 2 ], [ -8, 6, 2, 3, -1, 3 ], [ -7, 5, 2, 4, -1, 2 ], [ -6, 6, 2, 2, -1, 2 ] ], 0 ], + [ [ [ -8, 6, 2, 3, -1, 2 ], [ -8, 6, 2, 3, -1, 3 ], [ -6, 5, 2, 3, -1, 2 ], [ -6, 6, 2, 2, -1, 2 ] ], 0.25 ], + [ [ [ -8, 6, 2, 3, -1, 2 ], [ -8, 7, 2, 3, -1, 2 ], [ -6, 5, 2, 3, -1, 2 ], [ -6, 6, 2, 2, -1, 2 ] ], 0 ], + [ [ [ -8, 6, 2, 3, -1, 2 ], [ -8, 7, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ], [ -6, 6, 2, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 2, 3, -1, 2 ], [ -8, 7, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ], [ -6, 6, 2, 2, -1, 2 ] ], 0 ], + [ [ [ -9, 8, 2, 3, -1, 2 ], [ -8, 7, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ] ], 0 ], + [ [ [ -9, 8, 2, 3, -1, 2 ], [ -7, 7, 2, 2, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 2, 3, -1, 2 ], [ -8, 7, 3, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ] ], 0 ], + [ [ [ -9, 8, 2, 3, -1, 2 ], [ -8, 7, 3, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ], [ -8, 8, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 2, 3, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ], [ -8, 8, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 1, 3, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ], [ -8, 8, 2, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 5, 2, 3, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ], [ -8, 8, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -7, 5, 2, 3, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ], [ -7, 6, 3, 3, -1, 2 ] ], 0 ], + [ [ [ -7, 5, 2, 3, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -6, 5, 2, 3, -1, 2 ], [ -7, 6, 3, 3, -1, 2 ] ], 0.25 ], + [ [ [ -7, 5, 2, 3, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -6, 6, 2, 3, -2, 2 ], [ -7, 6, 3, 3, -1, 2 ] ], 0 ], + [ [ [ -7, 5, 2, 3, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -6, 6, 2, 3, -2, 2 ], [ -6, 5, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -7, 6, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -6, 6, 2, 3, -2, 2 ], [ -6, 5, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -7, 6, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -7, 6, 2, 3, -1, 3 ], [ -6, 5, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -7, 6, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -7, 6, 2, 3, -1, 3 ], [ -7, 7, 2, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 6, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -7, 6, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ], [ -6, 6, 1, 3, -1, 2 ] ], 0 ], + [ [ [ -7, 6, 1, 3, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ], [ -6, 6, 1, 3, -1, 2 ] ], 0.25 ], + [ [ [ -7, 6, 1, 3, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ], [ -6, 6, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -7, 6, 1, 3, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -6, 6, 1, 3, -1, 2 ], [ -6, 6, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -7, 6, 1, 3, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ], [ -6, 6, 2, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 6, 1, 3, -1, 2 ], [ -9, 8, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ], [ -6, 6, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 2, 3, -1, 2 ], [ -9, 8, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ], [ -6, 6, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 2, 3, -1, 2 ], [ -9, 8, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ], [ -8, 8, 2, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 2, 3, -1, 2 ], [ -9, 8, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ], [ -8, 9, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 2, 3, -1, 2 ], [ -9, 8, 2, 3, -1, 2 ], [ -8, 8, 2, 3, -1, 2 ], [ -8, 9, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -9, 9, 2, 3, -1, 2 ], [ -9, 8, 2, 3, -1, 2 ], [ -8, 8, 2, 3, -1, 2 ], [ -8, 9, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 8, 1, 3, -1, 2 ], [ -9, 8, 2, 3, -1, 2 ], [ -8, 8, 2, 3, -1, 2 ], [ -8, 9, 2, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 2, 4, -1, 2 ], [ -9, 8, 2, 3, -1, 2 ], [ -8, 8, 2, 3, -1, 2 ], [ -8, 9, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -9, 8, 2, 4, -1, 2 ], [ -9, 8, 2, 3, -1, 2 ], [ -8, 8, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 2, 4, -1, 2 ], [ -9, 9, 2, 3, -1, 2 ], [ -8, 8, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 2, 4, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ], [ -8, 8, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 2, 4, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 2, 4, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 7, 2, 3, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 2, 3, -1, 2 ], [ -7, 6, 2, 3, -1, 2 ], [ -8, 6, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 2, 3, -1, 2 ], [ -8, 8, 2, 3, -1, 2 ], [ -8, 6, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 7, 2, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -8, 6, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 2, 3, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ], [ -8, 6, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 2, 3, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ], [ -9, 8, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -7, 7, 2, 2, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ], [ -9, 8, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 7, 3, 3, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ], [ -9, 8, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 2, 4, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ], [ -9, 8, 2, 3, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 2, 4, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -7, 7, 2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 2, 4, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -8, 7, 3, 4, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 1, 4, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -8, 7, 3, 4, -1, 2 ] ], 0.25 ], + [ [ [ -8, 7, 1, 4, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 1, 4, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 1, 4, -1, 2 ], [ -7, 6, 1, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -7, 5, 2, 4, -1, 2 ], [ -7, 6, 1, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -8, 7, 2, 4, -1, 2 ], [ -7, 6, 1, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -8, 6, 2, 4, -1, 2 ], [ -7, 6, 1, 4, -1, 2 ], [ -8, 5, 2, 4, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 6, 2, 4, -1, 2 ], [ -7, 6, 1, 4, -1, 2 ], [ -9, 7, 2, 4, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -8, 6, 2, 4, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ], [ -9, 7, 2, 4, -1, 2 ], [ -7, 6, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -8, 6, 2, 4, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ], [ -9, 7, 2, 4, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -8, 6, 2, 4, -1, 2 ], [ -9, 6, 2, 4, -1, 2 ], [ -9, 7, 2, 4, -1, 2 ], [ -7, 5, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -8, 6, 2, 4, -1, 2 ], [ -9, 6, 2, 4, -1, 2 ], [ -9, 7, 2, 4, -1, 2 ], [ -8, 7, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -8, 6, 2, 4, -1, 2 ], [ -9, 6, 2, 4, -1, 2 ], [ -9, 7, 2, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 6, 2, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 2 ], [ -9, 7, 2, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 0.25 ], + [ [ [ -8, 6, 2, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 0.25 ], + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -7, 6, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -7, 6, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -10, 8, 1, 4, -1, 2 ], [ -7, 6, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0.25 ], + [ [ [ -10, 8, 1, 4, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -10, 8, 1, 4, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 8, 1, 4, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ] ], 0.25 ], + [ [ [ -10, 8, 1, 4, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ], [ -10, 9, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -10, 8, 1, 4, -1, 2 ], [ -9, 9, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ], [ -10, 9, 1, 4, -1, 2 ] ], 0.25 ], + [ [ [ -10, 8, 1, 4, -1, 2 ], [ -9, 9, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ], [ -9, 8, 0, 4, -1, 2 ] ], 0 ], + [ [ [ -10, 8, 1, 4, -1, 2 ], [ -9, 9, 1, 4, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ], [ -9, 8, 0, 4, -1, 2 ] ], 0.25 ], + [ [ [ -10, 8, 1, 4, -1, 2 ], [ -9, 9, 1, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -9, 8, 0, 4, -1, 2 ] ], 0 ], + [ [ [ -10, 8, 1, 4, -1, 2 ], [ -9, 9, 1, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 8, 1, 4, -1, 2 ], [ -9, 9, 1, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -10, 8, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -11, 9, 2, 4, -1, 2 ], [ -9, 9, 1, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -10, 8, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -11, 9, 2, 4, -1, 2 ], [ -10, 9, 2, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -10, 8, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -11, 9, 2, 4, -1, 2 ], [ -10, 9, 2, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -9, 9, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -11, 9, 2, 4, -1, 2 ], [ -10, 9, 2, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -8, 8, 2, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -11, 9, 2, 4, -1, 2 ], [ -10, 9, 2, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -10, 10, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -11, 9, 2, 4, -1, 2 ], [ -10, 9, 2, 4, -1, 2 ], [ -9, 9, 2, 4, -1, 2 ], [ -10, 10, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -11, 10, 2, 4, -1, 2 ], [ -10, 9, 2, 4, -1, 2 ], [ -9, 9, 2, 4, -1, 2 ], [ -10, 10, 2, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -11, 10, 2, 4, -1, 2 ], [ -9, 9, 2, 3, -1, 2 ], [ -9, 9, 2, 4, -1, 2 ], [ -10, 10, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -10, 9, 1, 4, -1, 2 ], [ -9, 9, 2, 3, -1, 2 ], [ -9, 9, 2, 4, -1, 2 ], [ -10, 10, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -10, 9, 1, 4, -1, 2 ], [ -9, 9, 2, 3, -1, 2 ], [ -9, 9, 2, 4, -1, 2 ], [ -9, 9, 1, 4, -1, 2 ] ], 0.25 ], + [ [ [ -10, 9, 1, 4, -1, 2 ], [ -9, 9, 2, 3, -1, 2 ], [ -9, 9, 2, 4, -1, 2 ], [ -10, 9, 2, 4, -1, 2 ] ], 0 ], + [ [ [ -10, 9, 1, 4, -1, 2 ], [ -10, 9, 3, 4, -1, 2 ], [ -9, 9, 2, 4, -1, 2 ], [ -10, 9, 2, 4, -1, 2 ] ], 0.25 ], + [ [ [ -10, 9, 1, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -9, 9, 2, 4, -1, 2 ], [ -10, 9, 2, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 9, 1, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -9, 9, 2, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -10, 9, 1, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -9, 7, 2, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0.25 ], + [ [ [ -10, 8, 2, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0.25 ], + [ [ [ -10, 8, 1, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -10, 8, 1, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -9, 8, 2, 5, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 1, 4, -1, 2 ], [ -9, 8, 2, 4, -1, 2 ], [ -9, 8, 2, 5, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -9, 7, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -9, 8, 2, 5, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -9, 7, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0.25 ], + [ [ [ -9, 7, 1, 4, -1, 2 ], [ -9, 9, 1, 4, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0.25 ], + [ [ [ -9, 7, 1, 4, -1, 2 ], [ -8, 8, 0, 4, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0.25 ], + [ [ [ -9, 7, 1, 4, -1, 2 ], [ -10, 8, 1, 4, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -9, 7, 1, 4, -1, 2 ], [ -10, 8, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0.25 ], + [ [ [ -9, 7, 1, 4, -1, 2 ], [ -9, 8, 1, 3, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 1, 4, -1, 2 ], [ -9, 8, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 1, 3, -1, 2 ], [ -9, 8, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -9, 8, 1, 4, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 1, 3, -1, 2 ], [ -9, 8, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 9, 1, 3, -1, 2 ], [ -9, 8, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 1, 3, -1, 3 ], [ -9, 8, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 3, -1, 3 ], [ -8, 8, 1, 2, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 3, -1, 3 ], [ -8, 8, 1, 2, -1, 2 ], [ -8, 9, 1, 3, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 3, -1, 3 ], [ -9, 8, 2, 3, -1, 2 ], [ -8, 9, 1, 3, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 3, -1, 3 ], [ -9, 8, 2, 3, -1, 2 ], [ -8, 8, 1, 3, -1, 3 ], [ -8, 8, 1, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 1, 3, -1, 3 ], [ -9, 8, 2, 3, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ] ], 0 ], + [ [ [ -9, 9, 1, 3, -1, 2 ], [ -9, 8, 2, 3, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 9, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ], [ -8, 8, 1, 4, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ], [ -7, 8, 1, 3, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 3, -1, 2 ], [ -9, 9, 1, 3, -1, 2 ], [ -7, 8, 1, 3, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 3, -1, 2 ], [ -8, 8, 0, 3, -1, 2 ], [ -7, 8, 1, 3, -1, 2 ], [ -8, 8, 1, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 1, 3, -1, 2 ], [ -8, 8, 0, 3, -1, 2 ], [ -7, 8, 1, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 3, -1, 2 ], [ -8, 8, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -1, 2 ], [ -8, 8, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -1, 2 ], [ -8, 8, 0, 3, -1, 2 ], [ -8, 9, 0, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 9, 0, 3, -1, 2 ], [ -8, 8, 0, 3, -1, 2 ], [ -8, 9, 0, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 9, 0, 3, -1, 2 ], [ -8, 8, 0, 3, -1, 2 ], [ -8, 9, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 9, 0, 3, -1, 2 ], [ -7, 8, 0, 2, -1, 2 ], [ -8, 9, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -9, 9, 0, 3, -1, 2 ], [ -7, 8, 0, 2, -1, 2 ], [ -8, 8, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 8, -1, 3, -1, 2 ], [ -7, 8, 0, 2, -1, 2 ], [ -8, 8, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 8, -1, 3, -1, 2 ], [ -7, 8, 0, 2, -1, 2 ], [ -9, 9, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 4, -1, 2 ], [ -7, 8, 0, 2, -1, 2 ], [ -9, 9, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 8, 0, 3, -1, 2 ], [ -7, 8, 0, 2, -1, 2 ], [ -9, 9, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 8, 0, 3, -1, 2 ], [ -8, 9, 0, 3, -1, 2 ], [ -9, 9, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -7, 8, 0, 2, -1, 2 ], [ -8, 9, 0, 3, -1, 2 ], [ -9, 9, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 8, 1, 3, -1, 2 ], [ -8, 9, 0, 3, -1, 2 ], [ -9, 9, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 8, 1, 3, -1, 2 ], [ -8, 9, 0, 3, -1, 2 ], [ -8, 8, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 8, 1, 3, -1, 2 ], [ -8, 8, 0, 3, -1, 3 ], [ -8, 8, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 8, 0, 3, 0, 2 ], [ -8, 8, 0, 3, -1, 3 ], [ -8, 8, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 9, 0, 3, -1, 2 ], [ -8, 8, 0, 3, -1, 3 ], [ -8, 8, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 9, 0, 3, -1, 2 ], [ -9, 8, 0, 3, -1, 2 ], [ -8, 8, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 9, 0, 3, -1, 2 ], [ -9, 8, 0, 3, -1, 2 ], [ -9, 9, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 9, 0, 3, -1, 2 ], [ -9, 8, 0, 3, -1, 2 ], [ -9, 9, 0, 3, -1, 2 ], [ -7, 9, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -7, 8, -1, 3, -1, 2 ], [ -9, 8, 0, 3, -1, 2 ], [ -9, 9, 0, 3, -1, 2 ], [ -7, 9, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -7, 8, -1, 3, -1, 2 ], [ -9, 8, 0, 3, -1, 2 ], [ -8, 8, -1, 3, -1, 2 ], [ -7, 9, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 8, 0, 3, -1, 2 ], [ -9, 8, 0, 3, -1, 2 ], [ -8, 8, -1, 3, -1, 2 ], [ -7, 9, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 8, 0, 3, -1, 2 ], [ -9, 8, 0, 3, -1, 2 ], [ -8, 8, -1, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 8, 0, 3, -1, 2 ], [ -9, 8, 0, 3, -1, 2 ], [ -8, 7, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 8, 0, 3, -1, 2 ], [ -9, 8, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 8, 0, 3, -1, 2 ], [ -8, 7, -1, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 8, 0, 3, -1, 2 ], [ -8, 7, -1, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -7, 7, -1, 3, -1, 2 ], [ -8, 7, -1, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 3, -1, 2 ], [ -8, 7, -1, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -6, 6, 0, 3, -1, 2 ], [ -8, 7, 0, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, 0, 3, -1, 2 ], [ -7, 7, 0, 2, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 3, -1, 2 ], [ -7, 7, 0, 2, -1, 2 ], [ -7, 7, 0, 4, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -6, 7, 0, 3, -1, 1 ], [ -7, 7, 0, 2, -1, 2 ], [ -7, 7, 0, 4, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -6, 7, 0, 2, -1, 2 ], [ -7, 7, 0, 2, -1, 2 ], [ -7, 7, 0, 4, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -7, 7, 1, 3, -1, 2 ], [ -7, 7, 0, 2, -1, 2 ], [ -7, 7, 0, 4, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 8, 0, 3, -1, 2 ], [ -7, 7, 0, 2, -1, 2 ], [ -7, 7, 0, 4, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 8, 0, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -7, 7, 0, 4, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 0, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -7, 7, 0, 4, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -1, 2 ], [ -8, 8, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 6, 0, 3, -1, 2 ], [ -8, 8, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 6, 0, 3, -1, 2 ], [ -7, 6, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 3, -1, 2 ], [ -7, 6, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 3, -1, 2 ], [ -8, 7, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -7, 6, 0, 3, -1, 2 ], [ -8, 7, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 6, 0, 3, -1, 2 ], [ -8, 7, 0, 3, -1, 2 ], [ -7, 8, 0, 3, -1, 2 ], [ -6, 6, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -7, 6, 0, 3, -1, 2 ], [ -8, 7, 0, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 6, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -7, 6, 0, 3, -1, 2 ], [ -7, 6, -1, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 6, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -7, 6, 0, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 6, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -7, 6, 0, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -5, 6, 0, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 6, 0, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ], + [ [ [ -7, 7, 0, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ], + [ [ [ -7, 7, 0, 3, -2, 2 ], [ -7, 7, -1, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -1, 3 ], [ -7, 7, -1, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ], + [ [ [ -8, 8, 0, 3, -1, 2 ], [ -7, 7, -1, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -8, 8, 0, 3, -1, 2 ], [ -8, 7, 0, 4, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ], + [ [ [ -8, 8, 0, 3, -1, 2 ], [ -8, 7, 0, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 7, -1, 3, -1, 2 ], [ -8, 7, 0, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -7, 7, -1, 3, -1, 2 ], [ -7, 7, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -7, 7, -1, 3, -1, 2 ], [ -7, 7, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 7, -1, 3, -1, 2 ], [ -8, 7, -1, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0 ], + [ [ [ -7, 6, -1, 3, -1, 2 ], [ -8, 7, -1, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0 ], + [ [ [ -7, 6, -1, 3, -1, 2 ], [ -8, 7, -1, 3, -1, 2 ], [ -6, 6, -1, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0.25 ], + [ [ [ -7, 6, -1, 3, -1, 2 ], [ -8, 7, -1, 3, -1, 2 ], [ -7, 7, -1, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 8, -1, 3, -1, 2 ], [ -8, 7, -1, 3, -1, 2 ], [ -7, 7, -1, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 8, -1, 3, -1, 2 ], [ -7, 7, -1, 2, -1, 2 ], [ -7, 7, -1, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0.25 ], + [ [ [ -8, 8, -1, 3, -1, 2 ], [ -8, 7, 0, 3, -1, 2 ], [ -7, 7, -1, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0 ], + [ [ [ -8, 8, -1, 3, -1, 2 ], [ -8, 7, 0, 3, -1, 2 ], [ -7, 8, -1, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 7, -1, 3, -1, 2 ], [ -8, 7, 0, 3, -1, 2 ], [ -7, 8, -1, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0 ], + [ [ [ -7, 7, -1, 3, -1, 2 ], [ -8, 7, 0, 3, -1, 2 ], [ -6, 6, -1, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0 ], + [ [ [ -7, 7, -1, 3, -1, 2 ], [ -7, 6, -1, 3, -1, 2 ], [ -6, 6, -1, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0.25 ], + [ [ [ -7, 7, -1, 3, -1, 2 ], [ -7, 6, -1, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0 ], + [ [ [ -6, 6, -1, 3, -1, 2 ], [ -7, 6, -1, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, -1, 3, -1, 2 ], [ -7, 7, -1, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, -1, 3, -1, 2 ], [ -7, 7, -1, 3, -1, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -5, 6, -2, 3, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, -1, 3, -1, 2 ], [ -7, 7, -1, 3, -1, 2 ], [ -7, 6, -1, 3, -1, 2 ], [ -5, 6, -2, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, -1, 3, -1, 2 ], [ -7, 7, -1, 3, -1, 2 ], [ -7, 6, -1, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0 ], + [ [ [ -6, 6, -1, 3, -1, 2 ], [ -7, 7, -1, 3, -1, 2 ], [ -6, 6, -1, 2, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0 ], + [ [ [ -6, 6, -1, 3, -1, 2 ], [ -6, 6, -2, 3, -1, 2 ], [ -6, 6, -1, 2, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, -1, 3, -1, 2 ], [ -6, 6, -2, 3, -1, 2 ], [ -6, 6, -1, 2, -1, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0.25 ], + [ [ [ -6, 6, -1, 3, -1, 2 ], [ -6, 6, -2, 3, -1, 2 ], [ -7, 6, 0, 3, -1, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0 ], + [ [ [ -6, 6, -1, 3, -1, 2 ], [ -6, 7, -1, 3, -1, 2 ], [ -7, 6, 0, 3, -1, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0.25 ], + [ [ [ -6, 6, -1, 3, -1, 2 ], [ -5, 5, -1, 3, -1, 2 ], [ -7, 6, 0, 3, -1, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, -1, 3, -1, 2 ], [ -7, 6, -1, 3, 1, 2 ], [ -7, 6, 0, 3, -1, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0 ], + [ [ [ -6, 5, -1, 3, 0, 2 ], [ -7, 6, -1, 3, 1, 2 ], [ -7, 6, 0, 3, -1, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0 ], + [ [ [ -6, 5, -1, 3, 0, 2 ], [ -7, 6, -1, 3, 1, 2 ], [ -7, 6, -1, 3, 0, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0.25 ], + [ [ [ -7, 7, -1, 3, 0, 2 ], [ -7, 6, -1, 3, 1, 2 ], [ -7, 6, -1, 3, 0, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0 ], + [ [ [ -7, 7, -1, 3, 0, 2 ], [ -7, 6, -1, 3, 1, 2 ], [ -6, 6, -1, 2, 0, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 7, -1, 3, 0, 2 ], [ -7, 6, -1, 3, 1, 2 ], [ -6, 6, -1, 3, 0, 1 ], [ -6, 6, -1, 3, 0, 2 ] ], 0 ], + [ [ [ -7, 6, -1, 3, 0, 2 ], [ -7, 6, -1, 3, 1, 2 ], [ -6, 6, -1, 3, 0, 1 ], [ -6, 6, -1, 3, 0, 2 ] ], 0.25 ], + [ [ [ -7, 6, -1, 3, 0, 2 ], [ -7, 7, -1, 3, 0, 2 ], [ -6, 6, -1, 3, 0, 1 ], [ -6, 6, -1, 3, 0, 2 ] ], 0.25 ], + [ [ [ -7, 6, -1, 3, 0, 2 ], [ -6, 6, -2, 3, 0, 2 ], [ -6, 6, -1, 3, 0, 1 ], [ -6, 6, -1, 3, 0, 2 ] ], 0 ], + [ [ [ -6, 6, -1, 2, 0, 2 ], [ -6, 6, -2, 3, 0, 2 ], [ -6, 6, -1, 3, 0, 1 ], [ -6, 6, -1, 3, 0, 2 ] ], 0.25 ], + [ [ [ -6, 6, -1, 2, 0, 2 ], [ -7, 6, -1, 4, 0, 2 ], [ -6, 6, -1, 3, 0, 1 ], [ -6, 6, -1, 3, 0, 2 ] ], 0 ], + [ [ [ -6, 6, -1, 2, 0, 2 ], [ -7, 6, -1, 4, 0, 2 ], [ -8, 6, -1, 4, 0, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 6, 0, 3, 0, 2 ], [ -7, 6, -1, 4, 0, 2 ], [ -8, 6, -1, 4, 0, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0 ], + [ [ [ -7, 6, 0, 3, 0, 2 ], [ -7, 6, -1, 4, 0, 2 ], [ -7, 6, -1, 3, 0, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0 ], + [ [ [ -7, 6, 0, 3, 0, 2 ], [ -8, 7, -1, 3, 0, 2 ], [ -7, 6, -1, 3, 0, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0.25 ], + [ [ [ -7, 6, 0, 3, 0, 2 ], [ -8, 6, -1, 3, 0, 2 ], [ -7, 6, -1, 3, 0, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0.25 ], + [ [ [ -7, 6, 0, 3, 0, 2 ], [ -7, 6, -1, 2, 0, 2 ], [ -7, 6, -1, 3, 0, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0 ], + [ [ [ -7, 6, 0, 3, 0, 2 ], [ -7, 6, -1, 2, 0, 2 ], [ -6, 6, -1, 2, 0, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 6, 0, 3, 0, 2 ], [ -7, 6, -1, 2, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -6, 6, -1, 3, 0, 2 ] ], 0 ], + [ [ [ -7, 6, 0, 3, 0, 2 ], [ -7, 6, -1, 2, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 0, 4, 0, 2 ] ], 0 ], + [ [ [ -7, 6, 0, 3, 0, 2 ], [ -9, 6, 0, 4, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 0, 4, 0, 2 ] ], 0.25 ], + [ [ [ -7, 6, 0, 3, 0, 2 ], [ -8, 6, 0, 3, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 0, 4, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 6, 1, 4, 0, 2 ], [ -8, 6, 0, 3, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 0, 4, 0, 2 ] ], 0 ], + [ [ [ -8, 6, 1, 4, 0, 2 ], [ -9, 6, 1, 4, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 0, 4, 0, 2 ] ], 0 ], + [ [ [ -8, 6, 1, 4, 0, 2 ], [ -9, 6, 1, 4, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 1, 4, 0, 2 ] ], 0.25 ], + [ [ [ -8, 6, 1, 4, 0, 2 ], [ -8, 5, 0, 4, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 1, 4, 0, 2 ] ], 0 ], + [ [ [ -7, 5, 0, 4, 0, 2 ], [ -8, 5, 0, 4, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 1, 4, 0, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 4, 0, 2 ], [ -8, 5, 0, 4, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 1, 4, 0, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 4, 0, 2 ], [ -9, 7, 0, 4, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 1, 4, 0, 2 ] ], 0.25 ], + [ [ [ -8, 6, 0, 4, 0, 3 ], [ -9, 7, 0, 4, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 1, 4, 0, 2 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ -8, 6, 1, 4, 0, 2 ], [ -8, 5, 0, 4, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 1, 4, 0, 2 ] ], + [ [ -7, 5, 0, 4, 0, 2 ], [ -8, 5, 0, 4, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 1, 4, 0, 2 ] ], + [ [ -8, 7, 0, 4, 0, 2 ], [ -8, 5, 0, 4, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 1, 4, 0, 2 ] ], + [ [ -8, 7, 0, 4, 0, 2 ], [ -9, 7, 0, 4, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 1, 4, 0, 2 ] ], + [ [ -8, 6, 0, 4, 0, 3 ], [ -9, 7, 0, 4, 0, 2 ], [ -8, 6, 0, 4, 0, 2 ], [ -7, 6, 1, 4, 0, 2 ] ] +], +"cur_uid": "47957a9d", +"ref_uid": "7276dc78", +"order_seed": 386659, +"dur_seed": 801009, +"motifs_seed": 846784, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0.0041152263374486, 0.0056818181818179, 0.080246913580247, 0.02840909090909, 0.20781893004115, 0.028409090909091, 0.41152263374486, 0, 0.44855967078189, 0.34659090909091, 0.47736625514403, 0, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58847736625514, 0.93181818181818, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 1, 2, 3, 2, 3, 3, 2 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 2, 1, 0 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 1 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 2, 0 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 2, 0, 0 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 3, 2, 0 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 3, 3, 3, 0 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 1, 2 ], [ ] ], + [ [ 2 ], [ 0, 3, 1, 1, 3, 1, 0 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 2, 3, 0, 2, 3 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 3, 2, 2 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 0 ], [ ] ], + [ [ 2 ], [ 0, 3, 1, 1 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 2, 1, 1 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 0 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 0, 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 0, 0 ], [ ] ], + [ [ 0 ], [ 2, 1, 3, 1, 3, 3 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 0, 1, 2 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 1, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1, 3, 2, 2, 3 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 3, 3 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 3, 1, 1 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 0, 0, 2 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 1, 1, 1, 2, 1 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 0 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 1, 2 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 0, 2, 1, 1 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 2, 0, 3 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 2, 0, 0, 1, 0 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 0, 0, 1 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 2, 0, 3, 2, 2 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 0, 1 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 0, 0, 0, 1 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 0, 1, 0, 1, 0 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 1, 3 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 0, 0, 1, 1 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 3 ], [ 1, 0, 2, 2, 0, 1, 1, 2 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 2, 0 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 3, 2, 1, 1 ], [ ] ], + [ [ 3 ], [ 1, 0, 2, 0, 2 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 1, 0, 1, 2 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 1, 1, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1, 1 ], [ ] ], + [ [ 2 ], [ 0, 1, 3, 1, 0, 0, 1, 0 ], [ ] ] +], +"sus_weights": [ 0.69, 0, 0 ], +"order_size": [ 49.489795918367, 49.489795918367 ], +"passages_size": [ 0, 6 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/47bdba0e/47bdba0e_code.scd b/resources/string_quartet_3_rise/47bdba0e/47bdba0e_code.scd new file mode 100644 index 0000000..070e09d --- /dev/null +++ b/resources/string_quartet_3_rise/47bdba0e/47bdba0e_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/47bdba0e/47bdba0e_mus_model.json b/resources/string_quartet_3_rise/47bdba0e/47bdba0e_mus_model.json new file mode 100644 index 0000000..d9ac111 --- /dev/null +++ b/resources/string_quartet_3_rise/47bdba0e/47bdba0e_mus_model.json @@ -0,0 +1,161 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -2, 2 ], [ -7, 5, 1, 4, 0, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 1 ], + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, 0, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 1 ], + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, 0, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, 0, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -8, 5, 1, 4, 0, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -8, 6, 1, 5, -1, 2 ], [ -8, 5, 1, 4, 0, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -8, 6, 1, 5, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -8, 6, 1, 5, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -8, 5, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -8, 5, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -7, 6, 0, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 6, 1, 3, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -8, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -8, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 5, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 7, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 7, 1, 3, -1, 2 ], [ -8, 6, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 1, 2, -1, 2 ], [ -8, 6, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ], + [ [ [ -7, 6, 1, 2, -1, 2 ], [ -7, 6, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ], + [ [ [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 8, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -6, 6, 1, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -6, 6, 1, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ], + [ [ [ -7, 6, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -8, 8, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -7, 7, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -8, 8, 2, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 7, 1, 3, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -8, 8, 2, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 7, 1, 3, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -8, 8, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -7, 7, 1, 3, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ], [ -6, 7, 1, 2, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 7, 1, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ], [ -6, 7, 1, 2, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -9, 7, 1, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -6, 7, 1, 2, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -9, 7, 1, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 7, 1, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -8, 8, 2, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -8, 8, 2, 2, -2, 2 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -9, 7, 1, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], + [ [ -9, 7, 1, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], + [ [ -8, 7, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], + [ [ -8, 7, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -8, 8, 2, 2, -2, 2 ] ], + [ [ -7, 6, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -8, 8, 2, 2, -2, 2 ] ] +], +"cur_uid": "47bdba0e", +"ref_uid": "7276dc78", +"order_seed": 343288, +"dur_seed": 721067, +"motifs_seed": 895119, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0, 0, 0.069958847736626, 0, 0.31481481481481, 0, 0.38271604938272, 0.13068181818182, 0.45884773662551, 0.14772727272727, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.79218106995885, 0, 1, 0 ], +"passages_weights": [ 1, 0.47, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 1, 3 ], [ 0, 2 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 1, 3, 0 ], [ 2 ], [ ] ], + [ [ 0 ], [ 1, 2, 3 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 3, 2, 1 ], [ 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 2, 1 ], [ 0, 3 ], [ ] ], + [ [ 3, 2 ], [ 0, 1 ], [ ] ], + [ [ 0, 3 ], [ 1, 2 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 3, 0 ], [ 1, 2 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 25, 25.244897959184 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/47bdba0e/lilypond/part_I.ly b/resources/string_quartet_3_rise/47bdba0e/lilypond/part_I.ly new file mode 100644 index 0000000..8aeb6a9 --- /dev/null +++ b/resources/string_quartet_3_rise/47bdba0e/lilypond/part_I.ly @@ -0,0 +1,52 @@ +{ + { cis''1^\markup { \pad-markup #0.2 "+50"} } + \bar "|" + { g1^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g1 ~ } + \bar "|" + { g2 d'2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'2 b2^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 } + \bar "|" + { fis'1^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'2 f'2^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'2 c''2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 } + \bar "|" + { ais'1^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 } + \bar "|" + { g1^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/47bdba0e/lilypond/part_II.ly b/resources/string_quartet_3_rise/47bdba0e/lilypond/part_II.ly new file mode 100644 index 0000000..b7d26c3 --- /dev/null +++ b/resources/string_quartet_3_rise/47bdba0e/lilypond/part_II.ly @@ -0,0 +1,52 @@ +{ + { cis''1^\markup { \pad-markup #0.2 "-48"} ~ } + \bar "|" + { cis''1 } + \bar "|" + { d'2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} a'2^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} } + \bar "|" + { cis'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} } + \bar "|" + { a1^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { a1 } + \bar "|" + { e'1^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } + \bar "|" + { dis'1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { dis'1 } + \bar "|" + { ais'1^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { ais'1 } + \bar "|" + { ais2^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} dis'2^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + \bar "|" + { dis'1 } + \bar "|" + { gis'1^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { gis'2 d''2^\markup { \pad-markup #0.2 "-42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} } + \bar "|" + { ais1^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { ais1} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/47bdba0e/lilypond/part_III.ly b/resources/string_quartet_3_rise/47bdba0e/lilypond/part_III.ly new file mode 100644 index 0000000..eba99ed --- /dev/null +++ b/resources/string_quartet_3_rise/47bdba0e/lilypond/part_III.ly @@ -0,0 +1,52 @@ +{ + { cis'2^\markup { \pad-markup #0.2 "+50"} g'2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'2 c''2^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { c''1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a'2 g'2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { b'1 } + \bar "|" + { e1^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + \bar "|" + { b1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } + \bar "|" + { b1 } + \bar "|" + { cis''2^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ais'2^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'2 ais2^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais2 f'2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'2 fis'2^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { fis'1 } + \bar "|" + { c''1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/47bdba0e/lilypond/part_IV.ly b/resources/string_quartet_3_rise/47bdba0e/lilypond/part_IV.ly new file mode 100644 index 0000000..b468bd1 --- /dev/null +++ b/resources/string_quartet_3_rise/47bdba0e/lilypond/part_IV.ly @@ -0,0 +1,52 @@ +{ + { g,1^\markup { \pad-markup #0.2 "+1"} ~ } + \bar "|" + { g,2 d2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d2 g2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } + \bar "|" + { g1 } + \bar "|" + { ais'2^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} e2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { e1 } + \bar "|" + { a2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} b,2^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b,2 g2^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + \bar "|" + { g2 b'2^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b'2 fis2^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis2 b2^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b1 } + \bar "|" + { fis'1^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + \bar "|" + { fis'1 } + \bar "|" + { fis1^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis2 fis,2^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { fis,1 ~ } + \bar "|" + { fis,2 c2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c2 f2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/47de143a/47de143a_code.scd b/resources/string_quartet_3_rise/47de143a/47de143a_code.scd new file mode 100644 index 0000000..e1a9d92 --- /dev/null +++ b/resources/string_quartet_3_rise/47de143a/47de143a_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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"], {(62.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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/47de143a/47de143a_mus_model.json b/resources/string_quartet_3_rise/47de143a/47de143a_mus_model.json new file mode 100644 index 0000000..fbd1366 --- /dev/null +++ b/resources/string_quartet_3_rise/47de143a/47de143a_mus_model.json @@ -0,0 +1,80 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -5, 6, 0, 2, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 1.125 ], + [ [ [ -3, 4, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 1.875 ], + [ [ [ -4, 6, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 2 ], + [ [ [ -4, 5, 0, 1, -2, 3 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 1.5 ], + [ [ [ -3, 5, 0, 1, -3, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 1.5 ] + ], + [ + [ [ [ -2, 4, 0, 1, -2, 1 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 1.875 ], + [ [ [ -4, 4, 0, 2, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 1.75 ] + ], + [ + [ [ [ -4, 4, 0, 2, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 4, 0, 2, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 5, -1, 2, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -2, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 5, -1, 2, -2, 2 ] ], 1.125 ], + [ [ [ -3, 5, -2, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 5, -2, 1, -2, 2 ] ], 0.75 ], + [ [ [ -3, 5, -2, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -2, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 6, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 6.25 ] + ] + ] +], +"last_changes": +[ + [ [ -5, 10, -3, 0, -3, 1 ], [ -5, 10, -3, 0, -3, 2 ], [ -4, 10, -3, 0, -3, 1 ], [ -5, 11, -3, 0, -3, 2 ] ], + [ [ -5, 10, -3, 0, -3, 1 ], [ -5, 11, -3, 0, -3, 1 ], [ -4, 10, -3, 0, -3, 1 ], [ -5, 11, -3, 0, -3, 2 ] ], + [ [ -5, 10, -3, 0, -3, 1 ], [ -5, 11, -3, 0, -3, 1 ], [ -4, 10, -3, 0, -3, 1 ], [ -3, 10, -3, 0, -3, 1 ] ], + [ [ -5, 10, -3, 0, -3, 1 ], [ -5, 11, -3, 0, -3, 1 ], [ -4, 11, -3, 0, -3, 1 ], [ -3, 10, -3, 0, -3, 1 ] ], + [ [ -5, 10, -3, 0, -3, 1 ], [ -5, 11, -3, 0, -3, 1 ], [ -4, 11, -3, 0, -3, 1 ], [ -4, 10, -3, 0, -3, 1 ] ] +], +"cur_uid": "47de143a", +"ref_uid": "731cf7ae", +"order_seed": 992132, +"dur_seed": 301127, +"motifs_seed": 698626, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 1.0164835164835, 0.0098039215686275, 0, 0.20915032679739, 0, 0.24183006535948, 0.82432432432432, 0.28758169934641, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 1.0164835164835, 0.0098039215686275, 0, 0.20915032679739, 0, 0.24183006535948, 0.82432432432432, 0.28758169934641, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 1.0164835164835, 0.0098039215686275, 0, 0.20915032679739, 0, 0.24183006535948, 0.82432432432432, 0.28758169934641, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 2, 1, 3, 1, 1, 3 ], [ ] ], + [ [ 2 ], [ 0, 1, 3, 0, 3 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 3, 3, 1 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 2, 0, 2 ], [ ] ], + [ [ 2 ], [ 0, 3, 1, 1, 3 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 3, 2, 0 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 3, 3, 0, 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 1, 3, 1 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 1, 1, 2 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 2, 0 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 3, 3, 1, 1 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 1 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 0 ], [ 2, 1, 3, 3, 1 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 2, 0 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 3, 3 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 2, 0, 3 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 3 ], [ ] ] +], +"sus_weights": [ 0.7, 0, 0 ], +"order_size": [ 20, 20.19387755102 ], +"passages_size": [ 0, 5 ], +"motif_edited": "true", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4874dd07/lilypond/part_I.ly b/resources/string_quartet_3_rise/4874dd07/lilypond/part_I.ly index 63f4a0e..521c9ce 100644 --- a/resources/string_quartet_3_rise/4874dd07/lilypond/part_I.ly +++ b/resources/string_quartet_3_rise/4874dd07/lilypond/part_I.ly @@ -1,38 +1,38 @@ { - { r2 c'2^\markup { \pad-markup #0.2 "+0"} ~ } + { r2 d'2^\markup { \pad-markup #0.2 "+0"} ~ } \bar "|" - { c'1 ~ } + { d'1 ~ } \bar "|" - { c'2 g2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + { d'2 a2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } \bar "|" - { a1^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} } + { b1^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} } \bar "|" - { ais1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + { c'1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } \bar "|" - { ais1 } + { c'1 } \bar "|" - { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + { d'1^\markup { \pad-markup #0.2 "+0"} ~ } \bar "|" - { c'2 f'2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } - \bar "|" - { f'1 ~ } - \bar "|" - { f'1 } - \bar "|" - { g'1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { d'2 g'2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } \bar "|" { g'1 ~ } \bar "|" { g'1 } \bar "|" - { ais'1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + { a'1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { ais'1 } + { a'1 ~ } \bar "|" - { c''1^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { a'1 } + \bar "|" + { c''1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } \bar "|" { c''1 } \bar "|" - { b1^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}} + { d''1^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { d''1 } + \bar "|" + { cis'1^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4874dd07/lilypond/part_II.ly b/resources/string_quartet_3_rise/4874dd07/lilypond/part_II.ly index 8b4aa3d..5f32320 100644 --- a/resources/string_quartet_3_rise/4874dd07/lilypond/part_II.ly +++ b/resources/string_quartet_3_rise/4874dd07/lilypond/part_II.ly @@ -1,38 +1,38 @@ { { r1 } \bar "|" - { r2 g'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { r2 a'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { g'1 ~ } + { a'1 ~ } \bar "|" - { g'2 a'2^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { a'2 b'2^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } \bar "|" - { a'2 c''2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { b'2 d''2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { c''1 ~ } + { d''1 ~ } \bar "|" - { c''2 g'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { d''2 a'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { g'1 ~ } + { a'1 ~ } \bar "|" - { g'2 c''2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { a'2 d''2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { c''1 ~ } + { d''1 ~ } \bar "|" - { c''1 } + { d''1 } \bar "|" - { f1^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } + { g1^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } \bar "|" - { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + { d'1^\markup { \pad-markup #0.2 "+0"} ~ } \bar "|" - { c'2 g'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { d'2 a'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { g'1 ~ } + { a'1 ~ } \bar "|" - { g'1 ~ } + { a'1 ~ } \bar "|" - { g'1 ~ } + { a'1 ~ } \bar "|" - { g'1} + { a'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4874dd07/lilypond/part_III.ly b/resources/string_quartet_3_rise/4874dd07/lilypond/part_III.ly index f3dc391..34b4e69 100644 --- a/resources/string_quartet_3_rise/4874dd07/lilypond/part_III.ly +++ b/resources/string_quartet_3_rise/4874dd07/lilypond/part_III.ly @@ -1,38 +1,38 @@ { { r1 } \bar "|" - { c1^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { d1^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { c1 ~ } + { d1 ~ } \bar "|" - { c1 ~ } + { d1 ~ } \bar "|" - { c1 } + { d1 } \bar "|" - { g1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + { a1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } \bar "|" - { g1 } + { a1 } \bar "|" - { gis1^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + { ais1^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } \bar "|" - { gis1 } + { ais1 } \bar "|" - { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + { d'1^\markup { \pad-markup #0.2 "+0"} ~ } \bar "|" - { c'1 ~ } + { d'1 ~ } \bar "|" - { c'2 c2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { d'2 d2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { c1 ~ } + { d1 ~ } \bar "|" - { c1 ~ } + { d1 ~ } \bar "|" - { c2 g2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + { d2 a2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } \bar "|" - { g1 } + { a1 } \bar "|" - { d'1^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + { e'1^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } \bar "|" - { d'1} + { e'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4874dd07/lilypond/part_IV.ly b/resources/string_quartet_3_rise/4874dd07/lilypond/part_IV.ly index c4f4ab6..aa3b55a 100644 --- a/resources/string_quartet_3_rise/4874dd07/lilypond/part_IV.ly +++ b/resources/string_quartet_3_rise/4874dd07/lilypond/part_IV.ly @@ -1,38 +1,38 @@ { - { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + { d'1^\markup { \pad-markup #0.2 "+0"} ~ } \bar "|" - { c'1 } + { d'1 } \bar "|" - { d'1^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + { e'1^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } \bar "|" - { d'1 ~ } + { e'1 ~ } \bar "|" - { d'1 ~ } + { e'1 ~ } \bar "|" - { d'2 c2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + { e'2 d2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } \bar "|" - { c1 ~ } + { d1 ~ } \bar "|" - { c1 } + { d1 } \bar "|" - { f1^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { g1^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } \bar "|" - { f2 g2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + { g2 a2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" - { g2 f'2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + { a2 g'2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } \bar "|" - { f'1 ~ } + { g'1 ~ } \bar "|" - { f'2 c''2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { g'2 d''2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { c''1 } + { d''1 } \bar "|" - { c'1^\markup { \pad-markup #0.2 "+0"} ~ } + { d'1^\markup { \pad-markup #0.2 "+0"} ~ } \bar "|" - { c'2 f2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } + { d'2 g2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } \bar "|" - { f2 g2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + { g2 a2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } \bar "|" - { g2 fis'2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}} + { a2 gis'2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4b40ed47/lilypond/part_I.ly b/resources/string_quartet_3_rise/4b40ed47/lilypond/part_I.ly index 669e421..f6077e0 100644 --- a/resources/string_quartet_3_rise/4b40ed47/lilypond/part_I.ly +++ b/resources/string_quartet_3_rise/4b40ed47/lilypond/part_I.ly @@ -1,22 +1,22 @@ { - { a'1^\markup { \pad-markup #0.2 "+1"} } + { b'1^\markup { \pad-markup #0.2 "+1"} } \bar "|" - { c''1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } + { d''1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } \bar "|" - { c''2 gis2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { d''2 ais2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { gis2 a2^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + { ais2 b2^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } \bar "|" - { a1 ~ } + { b1 ~ } \bar "|" - { a2 b2^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }} ~ } + { b2 cis'2^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }} ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b1} + { cis'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4b40ed47/lilypond/part_II.ly b/resources/string_quartet_3_rise/4b40ed47/lilypond/part_II.ly index 1c18623..f2264a1 100644 --- a/resources/string_quartet_3_rise/4b40ed47/lilypond/part_II.ly +++ b/resources/string_quartet_3_rise/4b40ed47/lilypond/part_II.ly @@ -1,22 +1,22 @@ { - { dis'2^\markup { \pad-markup #0.2 "-48"} dis'2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ } + { f'2^\markup { \pad-markup #0.2 "-48"} f'2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ } \bar "|" - { dis'1 ~ } + { f'1 ~ } \bar "|" - { dis'1 } + { f'1 } \bar "|" - { b'1^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }} } + { cis''1^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }} } \bar "|" - { c''1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } + { d''1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } \bar "|" - { f1^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + { g1^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } \bar "|" - { f1 ~ } + { g1 ~ } \bar "|" - { f1 ~ } + { g1 ~ } \bar "|" - { f2 gis2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} ~ } + { g2 ais2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} ~ } \bar "|" - { gis1} + { ais1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4b40ed47/lilypond/part_III.ly b/resources/string_quartet_3_rise/4b40ed47/lilypond/part_III.ly index 370f202..2b5bf61 100644 --- a/resources/string_quartet_3_rise/4b40ed47/lilypond/part_III.ly +++ b/resources/string_quartet_3_rise/4b40ed47/lilypond/part_III.ly @@ -1,22 +1,22 @@ { - { fis'1^\markup { \pad-markup #0.2 "+11"} ~ } + { gis'1^\markup { \pad-markup #0.2 "+11"} ~ } \bar "|" - { fis'2 gis'2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + { gis'2 ais'2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } \bar "|" - { gis'1 ~ } + { ais'1 ~ } \bar "|" - { gis'1 ~ } + { ais'1 ~ } \bar "|" - { gis'1 ~ } + { ais'1 ~ } \bar "|" - { gis'1 ~ } + { ais'1 ~ } \bar "|" - { gis'2 a'2^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }} ~ } + { ais'2 b'2^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }} ~ } \bar "|" - { a'1 } + { b'1 } \bar "|" - { c''1^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} } + { d''1^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} } \bar "|" - { d'1^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}} + { e'1^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4b40ed47/lilypond/part_IV.ly b/resources/string_quartet_3_rise/4b40ed47/lilypond/part_IV.ly index 34d5f50..d6a93f5 100644 --- a/resources/string_quartet_3_rise/4b40ed47/lilypond/part_IV.ly +++ b/resources/string_quartet_3_rise/4b40ed47/lilypond/part_IV.ly @@ -1,22 +1,22 @@ { - { fis'1^\markup { \pad-markup #0.2 "+38"} ~ } + { gis'1^\markup { \pad-markup #0.2 "+38"} ~ } \bar "|" - { fis'1 } + { gis'1 } \bar "|" - { g'1^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} ~ } + { a'1^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} ~ } \bar "|" - { g'1 ~ } + { a'1 ~ } \bar "|" - { g'2 g'2^\markup { \pad-markup #0.2 "-26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } + { a'2 a'2^\markup { \pad-markup #0.2 "-26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } \bar "|" - { g'1 } + { a'1 } \bar "|" - { dis'1^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} } + { f'1^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} } \bar "|" - { dis'2^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} ais'2^\markup { \pad-markup #0.2 "+44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + { f'2^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} c''2^\markup { \pad-markup #0.2 "+44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } \bar "|" - { ais'1 ~ } + { c''1 ~ } \bar "|" - { ais'2 b'2^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}} + { c''2 cis''2^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4bf1af12/lilypond/part_I.ly b/resources/string_quartet_3_rise/4bf1af12/lilypond/part_I.ly index 28e0f1c..81901d2 100644 --- a/resources/string_quartet_3_rise/4bf1af12/lilypond/part_I.ly +++ b/resources/string_quartet_3_rise/4bf1af12/lilypond/part_I.ly @@ -1,22 +1,22 @@ { - { g'1^\markup { \pad-markup #0.2 "-21"} ~ } + { a'1^\markup { \pad-markup #0.2 "-21"} ~ } \bar "|" - { g'2 a'2^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { a'2 b'2^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { a'2 e'2^\markup { \pad-markup #0.2 "-36"} ~ } + { b'2 fis'2^\markup { \pad-markup #0.2 "-36"} ~ } \bar "|" - { e'1 ~ } + { fis'1 ~ } \bar "|" - { e'1 } + { fis'1 } \bar "|" - { g'1^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + { a'1^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } \bar "|" - { g'1 } + { a'1 } \bar "|" - { a'1^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + { b'1^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } \bar "|" - { a'1 } + { b'1 } \bar "|" - { e'1^\markup { \pad-markup #0.2 "-36"}} + { fis'1^\markup { \pad-markup #0.2 "-36"}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4bf1af12/lilypond/part_II.ly b/resources/string_quartet_3_rise/4bf1af12/lilypond/part_II.ly index e6c2955..a98c260 100644 --- a/resources/string_quartet_3_rise/4bf1af12/lilypond/part_II.ly +++ b/resources/string_quartet_3_rise/4bf1af12/lilypond/part_II.ly @@ -1,22 +1,22 @@ { - { b'1^\markup { \pad-markup #0.2 "-34"} } + { cis''1^\markup { \pad-markup #0.2 "-34"} } \bar "|" - { c''1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + { d''1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } \bar "|" - { c''1 } + { d''1 } \bar "|" - { a'1^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { b'1^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { a'2 b'2^\markup { \pad-markup #0.2 "-34"} ~ } + { b'2 cis''2^\markup { \pad-markup #0.2 "-34"} ~ } \bar "|" - { b'2 e'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { cis''2 fis'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { e'2 b'2^\markup { \pad-markup #0.2 "-34"} ~ } + { fis'2 cis''2^\markup { \pad-markup #0.2 "-34"} ~ } \bar "|" - { b'1 ~ } + { cis''1 ~ } \bar "|" - { b'1 ~ } + { cis''1 ~ } \bar "|" - { b'2 c''2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}} + { cis''2 d''2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4bf1af12/lilypond/part_III.ly b/resources/string_quartet_3_rise/4bf1af12/lilypond/part_III.ly index 9111a1e..09bfdcb 100644 --- a/resources/string_quartet_3_rise/4bf1af12/lilypond/part_III.ly +++ b/resources/string_quartet_3_rise/4bf1af12/lilypond/part_III.ly @@ -1,22 +1,22 @@ { - { g2^\markup { \pad-markup #0.2 "-21"} a2^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + { a2^\markup { \pad-markup #0.2 "-21"} b2^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } \bar "|" - { a1 ~ } + { b1 ~ } \bar "|" - { a1 ~ } + { b1 ~ } \bar "|" - { a1 } + { b1 } \bar "|" - { b1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { cis'1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { b1 } + { cis'1 } \bar "|" - { cis'1^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + { dis'1^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } \bar "|" - { cis'2 e'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { dis'2 fis'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { e'2 e2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + { fis'2 fis2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } \bar "|" - { e1} + { fis1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4bf1af12/lilypond/part_IV.ly b/resources/string_quartet_3_rise/4bf1af12/lilypond/part_IV.ly index 5c0d977..3c23e1f 100644 --- a/resources/string_quartet_3_rise/4bf1af12/lilypond/part_IV.ly +++ b/resources/string_quartet_3_rise/4bf1af12/lilypond/part_IV.ly @@ -1,22 +1,22 @@ { - { e,1^\markup { \pad-markup #0.2 "-36"} ~ } + { fis,1^\markup { \pad-markup #0.2 "-36"} ~ } \bar "|" - { e,1 } + { fis,1 } \bar "|" - { a,1^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { b,1^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { a,2 e2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { b,2 fis2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } \bar "|" - { e1 ~ } + { fis1 ~ } \bar "|" - { e1 ~ } + { fis1 ~ } \bar "|" - { e1 ~ } + { fis1 ~ } \bar "|" - { e1 } + { fis1 } \bar "|" - { b1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + { cis'1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } \bar "|" - { b1} + { cis'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4c8a188f/4c8a188f_code.scd b/resources/string_quartet_3_rise/4c8a188f/4c8a188f_code.scd new file mode 100644 index 0000000..070e09d --- /dev/null +++ b/resources/string_quartet_3_rise/4c8a188f/4c8a188f_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/4c8a188f/4c8a188f_mus_model.json b/resources/string_quartet_3_rise/4c8a188f/4c8a188f_mus_model.json new file mode 100644 index 0000000..9bd5bff --- /dev/null +++ b/resources/string_quartet_3_rise/4c8a188f/4c8a188f_mus_model.json @@ -0,0 +1,270 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -7, 6, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ], [ -8, 8, 2, 2, -2, 2 ] ], 0.25 ], + [ [ [ -7, 6, 2, 2, -2, 2 ], [ -7, 9, 2, 2, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ], [ -8, 8, 2, 2, -2, 2 ] ], 0 ], + [ [ [ -9, 8, 2, 2, -2, 2 ], [ -7, 9, 2, 2, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ], [ -8, 8, 2, 2, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 9, 2, 2, -2, 2 ], [ -7, 9, 2, 2, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ], [ -8, 8, 2, 2, -2, 2 ] ], 0 ], + [ [ [ -9, 9, 2, 2, -2, 2 ], [ -7, 9, 2, 2, -2, 2 ], [ -8, 9, 2, 2, -2, 2 ], [ -8, 8, 2, 2, -2, 2 ] ], 0 ], + [ [ [ -9, 9, 2, 2, -2, 2 ], [ -7, 9, 2, 2, -2, 2 ], [ -8, 9, 2, 2, -2, 2 ], [ -9, 10, 2, 2, -2, 2 ] ], 0.25 ], + [ [ [ -9, 9, 2, 2, -2, 2 ], [ -7, 9, 2, 2, -2, 2 ], [ -8, 9, 2, 2, -2, 2 ], [ -8, 9, 1, 2, -2, 2 ] ], 0.25 ], + [ [ [ -8, 8, 2, 2, -2, 2 ], [ -7, 9, 2, 2, -2, 2 ], [ -8, 9, 2, 2, -2, 2 ], [ -8, 9, 1, 2, -2, 2 ] ], 0 ], + [ [ [ -8, 8, 2, 2, -2, 2 ], [ -7, 9, 2, 2, -2, 2 ], [ -8, 9, 2, 2, -2, 2 ], [ -7, 8, 2, 2, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 8, 2, 2, -2, 2 ], [ -7, 9, 2, 2, -2, 2 ], [ -8, 9, 2, 2, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ] ], 0 ], + [ [ [ -8, 8, 2, 2, -2, 2 ], [ -7, 9, 2, 2, -2, 2 ], [ -7, 8, 2, 2, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ] ], 0 ], + [ [ [ -8, 8, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -7, 8, 2, 2, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 8, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -6, 7, 1, 2, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ] ], 0 ], + [ [ [ -7, 7, 1, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -6, 7, 1, 2, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ] ], 0 ], + [ [ [ -7, 7, 1, 2, -2, 2 ], [ -5, 7, 2, 1, -2, 2 ], [ -6, 7, 1, 2, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ] ], 0.25 ], + [ [ [ -7, 7, 2, 1, -2, 2 ], [ -5, 7, 2, 1, -2, 2 ], [ -6, 7, 1, 2, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ] ], 0 ], + [ [ [ -7, 7, 2, 1, -2, 2 ], [ -5, 7, 2, 1, -2, 2 ], [ -6, 7, 2, 1, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ] ], 0 ], + [ [ [ -7, 7, 2, 1, -2, 2 ], [ -6, 7, 3, 2, -2, 2 ], [ -6, 7, 2, 1, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 7, 2, 1, -2, 2 ], [ -6, 7, 3, 2, -2, 2 ], [ -6, 7, 2, 1, -2, 2 ], [ -6, 7, 3, 1, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 3, 1, -2, 2 ], [ -6, 7, 3, 2, -2, 2 ], [ -6, 7, 2, 1, -2, 2 ], [ -6, 7, 3, 1, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 3, 1, -2, 2 ], [ -6, 7, 3, 2, -2, 2 ], [ -7, 7, 3, 2, -2, 2 ], [ -6, 7, 3, 1, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 3, 2, -2, 2 ], [ -6, 7, 3, 2, -2, 2 ], [ -7, 7, 3, 2, -2, 2 ], [ -6, 7, 3, 1, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 3, 2, -2, 2 ], [ -6, 7, 3, 2, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ], [ -6, 7, 3, 1, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 3, 2, -2, 2 ], [ -6, 7, 3, 2, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -6, 7, 3, 1, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 3, 2, -2, 2 ], [ -6, 7, 3, 2, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -8, 7, 4, 2, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 3, 2, -2, 2 ], [ -6, 7, 3, 2, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -7, 7, 3, 2, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 3, 2, -2, 2 ], [ -7, 8, 3, 2, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -7, 7, 3, 2, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 3, 2, -2, 2 ], [ -7, 7, 4, 2, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -7, 7, 3, 2, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 3, 2, -2, 2 ], [ -7, 7, 4, 2, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 3, 2, -2, 2 ], [ -7, 7, 4, 2, -2, 2 ], [ -7, 7, 3, 2, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 3, 2, -2, 2 ], [ -7, 7, 4, 2, -2, 2 ], [ -7, 7, 3, 2, -2, 2 ], [ -6, 7, 3, 2, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 3, 2, -2, 2 ], [ -7, 7, 4, 2, -2, 2 ], [ -7, 8, 4, 2, -2, 2 ], [ -6, 7, 3, 2, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 3, 2, -2, 2 ], [ -7, 7, 4, 2, -2, 2 ], [ -6, 6, 3, 2, -2, 2 ], [ -6, 7, 3, 2, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 3, 2, -2, 2 ], [ -7, 7, 4, 2, -2, 2 ], [ -6, 6, 3, 2, -2, 2 ], [ -7, 7, 4, 3, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 3, 2, -2, 2 ], [ -7, 7, 4, 2, -2, 2 ], [ -6, 7, 4, 1, -2, 2 ], [ -7, 7, 4, 3, -2, 2 ] ], 0 ], + [ [ [ -9, 7, 4, 3, -2, 2 ], [ -7, 7, 4, 2, -2, 2 ], [ -6, 7, 4, 1, -2, 2 ], [ -7, 7, 4, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 4, 3, -2, 2 ], [ -7, 7, 4, 2, -2, 2 ], [ -8, 7, 4, 3, -2, 2 ], [ -7, 7, 4, 3, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 4, 2, -2, 2 ], [ -7, 7, 4, 2, -2, 2 ], [ -8, 7, 4, 3, -2, 2 ], [ -7, 7, 4, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 8, 4, 2, -2, 2 ], [ -7, 7, 4, 2, -2, 2 ], [ -8, 7, 4, 3, -2, 2 ], [ -7, 7, 4, 3, -2, 2 ] ], 0.25 ], + [ [ [ -10, 7, 4, 3, -2, 2 ], [ -7, 7, 4, 2, -2, 2 ], [ -8, 7, 4, 3, -2, 2 ], [ -7, 7, 4, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 7, 4, 3, -2, 2 ], [ -9, 7, 4, 3, -2, 2 ], [ -8, 7, 4, 3, -2, 2 ], [ -7, 7, 4, 3, -2, 2 ] ], 0 ], + [ [ [ -10, 7, 4, 3, -2, 2 ], [ -9, 7, 4, 3, -2, 2 ], [ -8, 7, 4, 3, -2, 2 ], [ -8, 8, 4, 3, -2, 2 ] ], 0.25 ], + [ [ [ -10, 7, 4, 3, -2, 2 ], [ -9, 7, 4, 3, -2, 2 ], [ -8, 7, 4, 3, -2, 2 ], [ -9, 8, 4, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 7, 4, 3, -2, 2 ], [ -9, 7, 4, 3, -2, 2 ], [ -9, 9, 4, 3, -2, 2 ], [ -9, 8, 4, 3, -2, 2 ] ], 0 ], + [ [ [ -10, 7, 4, 3, -2, 2 ], [ -10, 9, 4, 3, -2, 2 ], [ -9, 9, 4, 3, -2, 2 ], [ -9, 8, 4, 3, -2, 2 ] ], 0.25 ], + [ [ [ -10, 7, 4, 3, -2, 2 ], [ -10, 9, 4, 3, -2, 2 ], [ -8, 7, 5, 3, -2, 2 ], [ -9, 8, 4, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 7, 4, 3, -2, 2 ], [ -10, 9, 4, 3, -2, 2 ], [ -7, 7, 4, 3, -2, 2 ], [ -9, 8, 4, 3, -2, 2 ] ], 0 ], + [ [ [ -10, 7, 4, 3, -2, 2 ], [ -8, 7, 4, 3, -2, 2 ], [ -7, 7, 4, 3, -2, 2 ], [ -9, 8, 4, 3, -2, 2 ] ], 0 ], + [ [ [ -10, 7, 4, 3, -2, 2 ], [ -8, 7, 4, 3, -2, 2 ], [ -7, 7, 4, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ] ], 0.5 ], + [ [ [ -10, 7, 4, 3, -2, 2 ], [ -8, 7, 4, 3, -2, 2 ], [ -8, 8, 4, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -10, 7, 4, 3, -2, 2 ], [ -8, 7, 4, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 7, 4, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -10, 7, 4, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -8, 7, 4, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 6, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -8, 7, 4, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ] ], 0 ], + [ [ [ -9, 6, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -9, 8, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ] ], 0 ], + [ [ [ -9, 6, 3, 3, -2, 2 ], [ -8, 8, 3, 3, -2, 2 ], [ -9, 8, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 6, 3, 3, -2, 2 ], [ -8, 8, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -10, 8, 3, 3, -2, 2 ], [ -8, 8, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ] ], 0 ], + [ [ [ -10, 8, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ], [ -8, 8, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ], [ -8, 8, 3, 3, -2, 2 ], [ -9, 8, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ], [ -8, 8, 3, 3, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ] ], 0 ], + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -8, 8, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ] ], 0 ], + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -8, 8, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ] ], 0 ], + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -8, 8, 3, 3, -2, 2 ], [ -9, 8, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -9, 8, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -8, 8, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ] ], 0 ], + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -8, 8, 3, 3, -2, 2 ], [ -7, 8, 3, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -8, 8, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ] ], 0 ], + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ] ], 0 ], + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 1 ], [ -7, 7, 2, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 1 ], [ -8, 7, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -6, 6, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -8, 6, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -8, 7, 3, 3, -2, 2 ], [ -6, 6, 3, 3, -2, 2 ] ], 0 ], + [ [ [ -8, 6, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ], [ -6, 6, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ], [ -6, 6, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -7, 6, 2, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ], [ -6, 6, 3, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 6, 2, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -6, 6, 2, 3, -2, 2 ], [ -6, 6, 3, 3, -2, 2 ] ], 0 ], + [ [ [ -7, 6, 2, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -6, 6, 2, 3, -2, 2 ], [ -5, 6, 3, 2, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, 3, 2, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -6, 6, 2, 3, -2, 2 ], [ -5, 6, 3, 2, -2, 2 ] ], 0.25 ], + [ [ [ -7, 6, 4, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -6, 6, 2, 3, -2, 2 ], [ -5, 6, 3, 2, -2, 2 ] ], 0 ], + [ [ [ -7, 6, 4, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -6, 6, 2, 3, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ] ], 0.25 ], + [ [ [ -7, 6, 4, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -6, 6, 2, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -7, 6, 4, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 2 ], [ -6, 6, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 3 ] ], 0 ], + [ [ [ -7, 6, 4, 3, -2, 2 ], [ -7, 5, 3, 3, -2, 3 ], [ -6, 6, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 3 ] ], 0 ], + [ [ [ -8, 6, 3, 4, -2, 3 ], [ -7, 5, 3, 3, -2, 3 ], [ -6, 6, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 3 ] ], 0.25 ], + [ [ [ -7, 6, 3, 2, -2, 3 ], [ -7, 5, 3, 3, -2, 3 ], [ -6, 6, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 3 ] ], 0.25 ], + [ [ [ -7, 6, 2, 3, -2, 3 ], [ -7, 5, 3, 3, -2, 3 ], [ -6, 6, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 3 ] ], 0.25 ], + [ [ [ -7, 6, 3, 3, -3, 3 ], [ -7, 5, 3, 3, -2, 3 ], [ -6, 6, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -8, 6, 3, 3, -2, 3 ], [ -7, 5, 3, 3, -2, 3 ], [ -6, 6, 3, 3, -2, 2 ], [ -7, 6, 3, 3, -2, 3 ] ], 0 ], + [ [ [ -8, 6, 3, 3, -2, 3 ], [ -7, 5, 3, 3, -2, 3 ], [ -8, 7, 3, 3, -2, 3 ], [ -7, 6, 3, 3, -2, 3 ] ], 0.25 ], + [ [ [ -8, 6, 3, 3, -2, 3 ], [ -7, 5, 3, 3, -2, 3 ], [ -7, 5, 4, 3, -2, 3 ], [ -7, 6, 3, 3, -2, 3 ] ], 0.25 ], + [ [ [ -8, 6, 3, 3, -2, 3 ], [ -7, 5, 3, 3, -2, 3 ], [ -6, 4, 3, 3, -2, 3 ], [ -7, 6, 3, 3, -2, 3 ] ], 0.25 ], + [ [ [ -8, 6, 3, 3, -2, 3 ], [ -7, 5, 3, 3, -2, 3 ], [ -7, 6, 2, 3, -2, 3 ], [ -7, 6, 3, 3, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -8, 6, 3, 3, -2, 3 ], [ -7, 5, 3, 3, -2, 3 ], [ -8, 6, 3, 4, -2, 3 ], [ -7, 6, 3, 3, -2, 3 ] ], 0 ], + [ [ [ -8, 6, 3, 3, -2, 3 ], [ -8, 7, 3, 3, -2, 3 ], [ -8, 6, 3, 4, -2, 3 ], [ -7, 6, 3, 3, -2, 3 ] ], 0.25 ], + [ [ [ -9, 7, 3, 3, -2, 3 ], [ -8, 7, 3, 3, -2, 3 ], [ -8, 6, 3, 4, -2, 3 ], [ -7, 6, 3, 3, -2, 3 ] ], 0.25 ], + [ [ [ -9, 7, 3, 3, -2, 3 ], [ -8, 7, 3, 3, -2, 3 ], [ -8, 6, 3, 3, -2, 3 ], [ -7, 6, 3, 3, -2, 3 ] ], 0 ], + [ [ [ -9, 6, 3, 3, -2, 3 ], [ -8, 7, 3, 3, -2, 3 ], [ -8, 6, 3, 3, -2, 3 ], [ -7, 6, 3, 3, -2, 3 ] ], 0.25 ], + [ [ [ -8, 6, 3, 2, -2, 3 ], [ -8, 7, 3, 3, -2, 3 ], [ -8, 6, 3, 3, -2, 3 ], [ -7, 6, 3, 3, -2, 3 ] ], 0 ], + [ [ [ -8, 6, 3, 2, -2, 3 ], [ -8, 7, 3, 3, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ], [ -7, 6, 3, 3, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -8, 6, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -1, 3 ], [ -7, 6, 3, 2, -2, 3 ], [ -7, 6, 3, 3, -2, 3 ] ], 0 ], + [ [ [ -8, 6, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -1, 3 ], [ -7, 6, 3, 2, -2, 3 ], [ -6, 6, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -7, 5, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -1, 3 ], [ -7, 6, 3, 2, -2, 3 ], [ -6, 6, 3, 2, -2, 3 ] ], 0 ], + [ [ [ -7, 5, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -1, 3 ], [ -7, 6, 3, 2, -2, 3 ], [ -6, 5, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -8, 7, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -1, 3 ], [ -7, 6, 3, 2, -2, 3 ], [ -6, 5, 3, 2, -2, 3 ] ], 0 ], + [ [ [ -8, 7, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -1, 3 ], [ -7, 6, 3, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -8, 7, 3, 2, -2, 3 ], [ -8, 6, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 3, 2, -2, 3 ], [ -8, 6, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ], [ -6, 6, 2, 2, -2, 3 ] ], 0 ], + [ [ [ -7, 6, 2, 2, -2, 3 ], [ -8, 6, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ], [ -6, 6, 2, 2, -2, 3 ] ], 0 ], + [ [ [ -7, 6, 2, 2, -2, 3 ], [ -8, 6, 3, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ], [ -6, 6, 2, 2, -2, 3 ] ], 0.25 ], + [ [ [ -7, 6, 2, 2, -2, 3 ], [ -8, 6, 3, 2, -2, 3 ], [ -6, 5, 3, 2, -2, 3 ], [ -6, 6, 2, 2, -2, 3 ] ], 0.25 ], + [ [ [ -7, 6, 2, 2, -2, 3 ], [ -8, 6, 3, 2, -2, 3 ], [ -6, 6, 3, 2, -2, 3 ], [ -6, 6, 2, 2, -2, 3 ] ], 0.25 ], + [ [ [ -7, 6, 2, 2, -2, 3 ], [ -8, 6, 3, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -6, 6, 2, 2, -2, 3 ] ], 0.25 ], + [ [ [ -7, 6, 2, 2, -2, 3 ], [ -8, 6, 3, 2, -2, 3 ], [ -6, 6, 3, 2, -2, 3 ], [ -6, 6, 2, 2, -2, 3 ] ], 0.25 ], + [ [ [ -7, 6, 2, 2, -2, 3 ], [ -8, 6, 3, 2, -2, 3 ], [ -6, 6, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 3, 2, -2, 3 ], [ -8, 6, 3, 2, -2, 3 ], [ -6, 6, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -8, 7, 3, 2, -2, 3 ], [ -7, 6, 3, 1, -2, 3 ], [ -6, 6, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -8, 7, 3, 2, -2, 3 ], [ -7, 6, 3, 1, -2, 3 ], [ -7, 6, 4, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -8, 7, 3, 2, -2, 3 ], [ -7, 6, 3, 1, -2, 3 ], [ -6, 5, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -8, 7, 3, 2, -2, 3 ], [ -8, 6, 4, 2, -2, 3 ], [ -6, 5, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -8, 7, 3, 2, -2, 3 ], [ -7, 5, 3, 2, -2, 3 ], [ -6, 5, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ] ], 0 ], + [ [ [ -8, 7, 3, 2, -2, 3 ], [ -7, 5, 3, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ] ], 0 ], + [ [ [ -8, 6, 3, 2, -2, 3 ], [ -7, 5, 3, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -8, 6, 3, 2, -2, 3 ], [ -7, 5, 3, 2, -2, 3 ], [ -6, 6, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ] ], 0 ], + [ [ [ -8, 6, 3, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ], [ -6, 6, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ] ], 0 ], + [ [ [ -8, 5, 3, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ], [ -6, 6, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -9, 7, 3, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ], [ -6, 6, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 3, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -9, 6, 3, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -9, 6, 3, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -8, 8, 3, 2, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -9, 6, 3, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ] ], 0 ], + [ [ [ -10, 8, 3, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ] ], 0 ], + [ [ [ -10, 8, 3, 2, -2, 3 ], [ -7, 7, 3, 1, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -8, 6, 3, 2, -2, 3 ], [ -7, 7, 3, 1, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ] ], 0.25 ], + [ [ [ -8, 6, 3, 2, -2, 3 ], [ -8, 7, 4, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ] ], 0 ], + [ [ [ -8, 6, 3, 2, -2, 3 ], [ -8, 7, 4, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -8, 6, 3, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -8, 6, 3, 2, -2, 3 ], [ -8, 8, 3, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 3, 2, -2, 3 ], [ -8, 8, 3, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -9, 8, 3, 2, -2, 3 ], [ -8, 8, 3, 2, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ] ], 0 ], + [ [ [ -9, 8, 3, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -9, 8, 3, 2, -2, 3 ], [ -6, 7, 3, 1, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ] ], 0 ], + [ [ [ -8, 7, 2, 2, -2, 3 ], [ -6, 7, 3, 1, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -8, 7, 2, 2, -2, 3 ], [ -7, 7, 4, 2, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ] ], 0.25 ], + [ [ [ -8, 7, 2, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ -9, 8, 3, 2, -2, 3 ], [ -7, 7, 3, 2, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ] ], + [ [ -9, 8, 3, 2, -2, 3 ], [ -6, 7, 3, 1, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ] ], + [ [ -8, 7, 2, 2, -2, 3 ], [ -6, 7, 3, 1, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ] ], + [ [ -8, 7, 2, 2, -2, 3 ], [ -7, 7, 4, 2, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ] ], + [ [ -8, 7, 2, 2, -2, 3 ], [ -7, 6, 3, 2, -2, 3 ], [ -7, 7, 2, 2, -2, 3 ], [ -8, 7, 3, 2, -2, 3 ] ] +], +"cur_uid": "4c8a188f", +"ref_uid": "47bdba0e", +"order_seed": 469205, +"dur_seed": 711965, +"motifs_seed": 539325, +"entrances_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"passages_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"exits_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0.0041152263374486, 0.0056818181818179, 0.080246913580247, 0.02840909090909, 0.20781893004115, 0.028409090909091, 0.41152263374486, 0, 0.44650205761317, 0.16477272727273, 0.47736625514403, 0, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 0.58, 1, 0.43, 1, 0.82 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 3, 0, 3 ], [ ] ], + [ [ 0 ], [ 3, 2, 1 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 0, 2, 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 0, 2, 2, 3 ], [ ] ], + [ [ 2, 0 ], [ 3, 1, 1, 3 ], [ ] ], + [ [ 0, 1 ], [ 2, 3, 2, 2 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 2, 0, 0, 0 ], [ ] ], + [ [ 0, 2 ], [ 1, 3, 3 ], [ ] ], + [ [ 3, 0 ], [ 2, 1, 2 ], [ ] ], + [ [ 0 ], [ 2, 1, 3, 2, 2 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 2, 1, 2, 0, 1 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 3, 2 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 1, 2, 2, 3 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 2, 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 0, 0 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 0, 3, 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 0, 0, 0 ], [ ] ], + [ [ 1, 3 ], [ 0, 2, 2, 2, 2 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 2, 0, 0, 2 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 3, 0, 3, 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 2, 2, 2, 2, 3 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 2, 1, 1, 2, 0 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 0 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 2 ], [ 0, 1, 3, 1, 1 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 1, 0, 1, 1 ], [ ] ] +], +"sus_weights": [ 0.69, 0.17, 0 ], +"order_size": [ 28, 28.275510204082 ], +"passages_size": [ 0, 6 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4cb92563/4cb92563_code.scd b/resources/string_quartet_3_rise/4cb92563/4cb92563_code.scd new file mode 100644 index 0000000..e1a9d92 --- /dev/null +++ b/resources/string_quartet_3_rise/4cb92563/4cb92563_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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"], {(62.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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/4cb92563/4cb92563_mus_model.json b/resources/string_quartet_3_rise/4cb92563/4cb92563_mus_model.json new file mode 100644 index 0000000..9293bc8 --- /dev/null +++ b/resources/string_quartet_3_rise/4cb92563/4cb92563_mus_model.json @@ -0,0 +1,63 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -2, 7, -4, 0, -3, 2 ], [ -2, 8, -4, 0, -3, 2 ] ], 0 ], + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -2, 7, -4, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0 ], + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -3, 8, -3, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ], + [ [ [ -5, 8, -3, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -3, 8, -3, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -3, 8, -3, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0 ], + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -2, 7, -4, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 2.125 ] + ], + [ + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -3, 9, -4, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -2, 8, -5, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -1, 6, -4, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -1, 7, -4, 0, -4, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -3, 8, -4, 1, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -2, 7, -4, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -3, 9, -4, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -2, 8, -5, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -1, 6, -4, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -3, 8, -4, 1, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], + [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -2, 7, -4, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], + [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -3, 9, -4, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], + [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -2, 8, -5, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], + [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -1, 6, -4, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ] +], +"cur_uid": "4cb92563", +"ref_uid": "787e1079", +"order_seed": 680610, +"dur_seed": 751307, +"motifs_seed": 328195, +"entrances_probs_vals": [ 0.82, 0, 0, 0, 3, 0.0098039215686275, 0, 0.065359477124183, 0, 0.081699346405229, 0.85135135135135, 0.098039215686274, 0.0033783783783784, 1, 0 ], +"passages_probs_vals": [ 0.82, 0, 0, 0, 3, 0.0098039215686275, 0, 0.065359477124183, 0, 0.081699346405229, 0.85135135135135, 0.098039215686274, 0.0033783783783784, 1, 0 ], +"exits_probs_vals": [ 0.82, 0, 0, 0, 3, 0.0098039215686275, 0, 0.065359477124183, 0, 0.081699346405229, 0.85135135135135, 0.098039215686274, 0.0033783783783784, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 1 ], [ 0, 3, 2, 0, 0, 2 ], [ ] ], + [ [ 1, 3, 0 ], [ 2, 2, 2, 2, 2 ], [ ] ], + [ [ 0, 1, 3 ], [ 2 ], [ ] ], + [ [ 3, 0, 1 ], [ 2, 2, 2 ], [ ] ] +], +"sus_weights": [ 0.7, 0.48, 0.49 ], +"order_size": [ 4.030612244898, 4.030612244898 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4da80bfb/4da80bfb_code.scd b/resources/string_quartet_3_rise/4da80bfb/4da80bfb_code.scd new file mode 100644 index 0000000..e1a9d92 --- /dev/null +++ b/resources/string_quartet_3_rise/4da80bfb/4da80bfb_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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"], {(62.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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/4da80bfb/4da80bfb_mus_model.json b/resources/string_quartet_3_rise/4da80bfb/4da80bfb_mus_model.json new file mode 100644 index 0000000..8e12257 --- /dev/null +++ b/resources/string_quartet_3_rise/4da80bfb/4da80bfb_mus_model.json @@ -0,0 +1,197 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -6, 8, -2, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -6, 8, -2, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -4, 9, -2, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 9, -2, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -4, 9, -2, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 9, -2, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -4, 8, -2, 0, -1, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 9, -2, 0, -2, 2 ], [ -4, 8, -3, 0, -2, 2 ], [ -4, 8, -2, 0, -1, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -4, 8, -2, 0, -3, 2 ], [ -4, 8, -3, 0, -2, 2 ], [ -4, 8, -2, 0, -1, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 8, -2, 0, -3, 2 ], [ -4, 8, -3, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -4, 7, -2, 0, -2, 2 ], [ -4, 8, -3, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 8, -2, 0, -2, 1 ], [ -4, 8, -3, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 8, -2, 0, -2, 1 ], [ -5, 9, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 8, -2, -1, -2, 2 ], [ -5, 9, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -4, 8, -2, -1, -2, 2 ], [ -5, 9, -2, 0, -2, 2 ], [ -4, 9, -2, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -4, 8, -2, -1, -2, 2 ], [ -5, 8, -2, 0, -2, 3 ], [ -4, 9, -2, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 8, -2, -1, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -4, 9, -2, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 7, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -4, 9, -2, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 7, -2, 0, -2, 2 ], [ -4, 8, -1, 0, -2, 2 ], [ -4, 9, -2, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 7, -2, 0, -2, 2 ], [ -4, 8, -1, 0, -2, 2 ], [ -3, 7, -1, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 7, -2, 0, -2, 2 ], [ -4, 8, -1, 0, -2, 2 ], [ -3, 7, -1, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 3 ] ], 0 ], + [ [ [ -5, 7, -2, 0, -2, 2 ], [ -4, 7, -3, 0, -2, 2 ], [ -3, 7, -1, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 3 ] ], 0 ], + [ [ [ -5, 7, -2, 0, -2, 2 ], [ -4, 7, -3, 0, -2, 2 ], [ -3, 7, -2, 0, -1, 2 ], [ -4, 7, -2, 0, -2, 3 ] ], 0.25 ], + [ [ [ -5, 7, -2, 0, -2, 2 ], [ -4, 7, -3, 0, -2, 2 ], [ -2, 6, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 3 ] ], 0 ], + [ [ [ -5, 7, -2, 0, -2, 2 ], [ -5, 7, -2, 1, -2, 2 ], [ -2, 6, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -5, 7, -2, 0, -2, 2 ], [ -5, 7, -2, 1, -2, 2 ], [ -2, 7, -2, 0, -2, 1 ], [ -4, 7, -2, 0, -2, 3 ] ], 0 ], + [ [ [ -5, 7, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ], [ -2, 7, -2, 0, -2, 1 ], [ -4, 7, -2, 0, -2, 3 ] ], 0.25 ], + [ [ [ -5, 7, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ], [ -2, 7, -2, 0, -2, 1 ], [ -4, 8, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 7, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ], [ -2, 7, -2, 0, -2, 1 ], [ -3, 8, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 7, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -3, 8, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 7, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -5, 6, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 3 ] ], 0.25 ], + [ [ [ -5, 6, -2, 0, -2, 2 ], [ -3, 6, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 3 ] ], 0.25 ], + [ [ [ -5, 6, -2, 0, -2, 2 ], [ -3, 6, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -2, 6, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 6, -2, 0, -2, 2 ], [ -4, 6, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -2, 6, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -2, 0, -2, 2 ], [ -4, 6, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 6, -2, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -6, 8, -2, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -6, 8, -2, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -6, 8, -2, 0, -2, 2 ], [ -4, 7, -3, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 7, -3, 0, -2, 2 ], [ -4, 7, -3, 0, -2, 2 ], [ -4, 8, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 7, -3, 0, -2, 2 ], [ -4, 7, -3, 0, -2, 2 ], [ -3, 7, -3, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 7, -3, 0, -2, 2 ], [ -4, 7, -3, 0, -2, 2 ], [ -4, 8, -3, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 7, -3, 0, -2, 2 ], [ -4, 7, -3, 0, -2, 2 ], [ -4, 8, -3, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 7, -3, 0, -2, 2 ], [ -5, 8, -3, 0, -2, 2 ], [ -4, 8, -3, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 7, -3, 0, -2, 2 ], [ -5, 8, -3, 0, -2, 2 ], [ -3, 7, -4, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 7, -3, 0, -2, 2 ], [ -4, 7, -4, 0, -2, 2 ], [ -3, 7, -4, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 7, -3, 0, -2, 2 ], [ -4, 7, -4, 0, -2, 2 ], [ -3, 7, -4, 0, -2, 2 ], [ -2, 7, -4, 0, -2, 2 ] ], 0 ], + [ [ [ -4, 6, -4, 0, -2, 2 ], [ -4, 7, -4, 0, -2, 2 ], [ -3, 7, -4, 0, -2, 2 ], [ -2, 7, -4, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 6, -4, 0, -2, 2 ], [ -4, 7, -4, 0, -2, 2 ], [ -3, 7, -4, 0, -2, 2 ], [ -3, 6, -4, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 6, -4, 0, -2, 2 ], [ -4, 7, -4, 0, -2, 2 ], [ -3, 7, -4, 0, -2, 2 ], [ -4, 8, -4, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 8, -4, 0, -2, 2 ], [ -4, 7, -4, 0, -2, 2 ], [ -3, 7, -4, 0, -2, 2 ], [ -4, 8, -4, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 8, -4, 0, -2, 2 ], [ -5, 8, -3, 0, -2, 2 ], [ -3, 7, -4, 0, -2, 2 ], [ -4, 8, -4, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 8, -4, 0, -2, 2 ], [ -5, 8, -3, 0, -2, 2 ], [ -4, 9, -4, 0, -2, 2 ], [ -4, 8, -4, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 8, -4, 0, -2, 2 ], [ -5, 8, -3, 0, -2, 2 ], [ -4, 9, -4, 0, -2, 2 ], [ -3, 8, -4, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 8, -4, 0, -2, 2 ], [ -5, 8, -3, 0, -2, 2 ], [ -3, 8, -5, 0, -2, 2 ], [ -3, 8, -4, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 8, -4, 0, -2, 2 ], [ -4, 8, -4, -1, -2, 2 ], [ -3, 8, -5, 0, -2, 2 ], [ -3, 8, -4, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 8, -4, 0, -2, 2 ], [ -4, 8, -4, -1, -2, 2 ], [ -4, 8, -4, 1, -2, 2 ], [ -3, 8, -4, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 8, -4, 0, -2, 2 ], [ -4, 8, -4, -1, -2, 2 ], [ -4, 8, -4, 1, -2, 2 ], [ -5, 8, -4, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 8, -4, 0, -2, 2 ], [ -5, 7, -4, 1, -2, 2 ], [ -4, 8, -4, 1, -2, 2 ], [ -5, 8, -4, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 8, -4, 1, -2, 2 ], [ -5, 7, -4, 1, -2, 2 ], [ -4, 8, -4, 1, -2, 2 ], [ -5, 8, -4, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 8, -4, 1, -2, 2 ], [ -5, 7, -4, 1, -2, 2 ], [ -4, 7, -4, 1, -2, 2 ], [ -5, 8, -4, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 7, -4, 1, -2, 2 ], [ -5, 7, -4, 1, -2, 2 ], [ -4, 7, -4, 1, -2, 2 ], [ -5, 8, -4, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 7, -4, 1, -2, 2 ], [ -5, 7, -4, 1, -2, 2 ], [ -5, 9, -4, 1, -2, 2 ], [ -5, 8, -4, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 7, -4, 1, -2, 2 ], [ -6, 9, -4, 1, -2, 2 ], [ -5, 9, -4, 1, -2, 2 ], [ -5, 8, -4, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 7, -4, 1, -2, 2 ], [ -6, 9, -4, 1, -2, 2 ], [ -5, 9, -4, 1, -2, 2 ], [ -6, 10, -4, 1, -2, 2 ] ], 0 ], + [ [ [ -7, 9, -4, 1, -2, 2 ], [ -6, 9, -4, 1, -2, 2 ], [ -5, 9, -4, 1, -2, 2 ], [ -6, 10, -4, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 9, -3, 1, -2, 2 ], [ -6, 9, -4, 1, -2, 2 ], [ -5, 9, -4, 1, -2, 2 ], [ -6, 10, -4, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 10, -5, 1, -2, 2 ], [ -6, 9, -4, 1, -2, 2 ], [ -5, 9, -4, 1, -2, 2 ], [ -6, 10, -4, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 10, -5, 1, -2, 2 ], [ -7, 11, -4, 1, -2, 2 ], [ -5, 9, -4, 1, -2, 2 ], [ -6, 10, -4, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 10, -5, 1, -2, 2 ], [ -7, 11, -4, 1, -2, 2 ], [ -6, 10, -3, 1, -2, 2 ], [ -6, 10, -4, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 10, -5, 1, -2, 2 ], [ -7, 11, -4, 1, -2, 2 ], [ -6, 11, -4, 1, -2, 2 ], [ -6, 10, -4, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 10, -5, 1, -2, 2 ], [ -6, 10, -4, 1, -3, 2 ], [ -6, 11, -4, 1, -2, 2 ], [ -6, 10, -4, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 10, -5, 1, -2, 2 ], [ -5, 10, -4, 1, -2, 2 ], [ -6, 11, -4, 1, -2, 2 ], [ -6, 10, -4, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 10, -5, 1, -2, 2 ], [ -5, 10, -4, 1, -2, 2 ], [ -6, 11, -4, 1, -2, 2 ], [ -7, 12, -4, 1, -2, 2 ] ], 0 ], + [ [ [ -7, 11, -4, 1, -2, 2 ], [ -5, 10, -4, 1, -2, 2 ], [ -6, 11, -4, 1, -2, 2 ], [ -7, 12, -4, 1, -2, 2 ] ], 0.25 ], + [ [ [ -7, 11, -4, 1, -2, 2 ], [ -5, 10, -4, 1, -2, 2 ], [ -6, 11, -4, 1, -2, 2 ], [ -6, 11, -5, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 11, -4, 1, -2, 2 ], [ -5, 10, -4, 1, -2, 2 ], [ -6, 11, -4, 1, -2, 2 ], [ -5, 11, -4, 1, -2, 2 ] ], 0 ], + [ [ [ -7, 11, -4, 1, -2, 2 ], [ -5, 10, -4, 1, -2, 2 ], [ -6, 10, -4, 1, -2, 2 ], [ -5, 11, -4, 1, -2, 2 ] ], 0 ], + [ [ [ -7, 11, -4, 1, -2, 2 ], [ -6, 11, -4, 1, -2, 2 ], [ -6, 10, -4, 1, -2, 2 ], [ -5, 11, -4, 1, -2, 2 ] ], 0.25 ], + [ [ [ -7, 11, -4, 1, -2, 2 ], [ -5, 11, -4, 0, -2, 2 ], [ -6, 10, -4, 1, -2, 2 ], [ -5, 11, -4, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 11, -4, 0, -2, 2 ], [ -5, 11, -4, 0, -2, 2 ], [ -6, 10, -4, 1, -2, 2 ], [ -5, 11, -4, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 11, -4, 0, -2, 2 ], [ -5, 11, -4, 0, -2, 2 ], [ -6, 10, -4, 1, -2, 2 ], [ -4, 11, -4, 0, -2, 2 ] ], 0 ], + [ [ [ -6, 11, -4, 0, -2, 2 ], [ -5, 11, -4, 0, -2, 2 ], [ -5, 10, -4, 0, -2, 2 ], [ -4, 11, -4, 0, -2, 2 ] ], 0.25 ], + [ [ [ -6, 11, -4, 0, -2, 2 ], [ -5, 11, -4, 0, -2, 2 ], [ -5, 10, -4, 0, -2, 2 ], [ -4, 10, -4, 0, -2, 2 ] ], 0.25 ], + [ [ [ -6, 11, -4, 0, -2, 2 ], [ -5, 11, -4, 0, -2, 2 ], [ -5, 10, -4, 0, -2, 2 ], [ -5, 12, -4, 0, -2, 2 ] ], 0 ], + [ [ [ -6, 11, -4, 0, -2, 2 ], [ -5, 11, -4, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -5, 12, -4, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 11, -4, 0, -2, 2 ], [ -7, 12, -4, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -5, 12, -4, 0, -2, 2 ] ], 0 ], + [ [ [ -6, 11, -4, 0, -2, 2 ], [ -7, 12, -4, 0, -2, 2 ], [ -5, 11, -4, 0, -2, 2 ], [ -5, 12, -4, 0, -2, 2 ] ], 0 ], + [ [ [ -6, 11, -4, 0, -2, 2 ], [ -7, 12, -4, 0, -2, 2 ], [ -5, 11, -4, 0, -2, 2 ], [ -4, 11, -5, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 11, -4, 0, -2, 2 ], [ -7, 12, -4, 0, -2, 2 ], [ -5, 11, -4, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ] ], 0 ], + [ [ [ -6, 11, -4, 0, -2, 2 ], [ -6, 10, -4, 0, -2, 2 ], [ -5, 11, -4, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ] ], 0.25 ], + [ [ [ -7, 11, -4, 0, -2, 2 ], [ -6, 10, -4, 0, -2, 2 ], [ -5, 11, -4, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ] ], 0 ], + [ [ [ -7, 11, -4, 0, -2, 2 ], [ -6, 10, -4, 0, -2, 2 ], [ -5, 11, -4, 0, -2, 2 ], [ -5, 10, -4, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 11, -4, 0, -2, 2 ], [ -6, 10, -4, 0, -2, 2 ], [ -5, 11, -4, 0, -2, 2 ], [ -6, 11, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -7, 11, -4, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -5, 11, -4, 0, -2, 2 ], [ -6, 11, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -7, 11, -4, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -6, 11, -4, 0, -2, 2 ], [ -6, 11, -3, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 12, -3, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -6, 11, -4, 0, -2, 2 ], [ -6, 11, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -8, 12, -3, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -7, 12, -3, 0, -2, 2 ], [ -6, 11, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -8, 12, -3, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -7, 12, -3, 0, -2, 2 ], [ -7, 13, -4, 0, -2, 2 ] ], 0.25 ], + [ [ [ -8, 12, -3, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -7, 12, -3, 0, -2, 2 ], [ -6, 12, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -8, 12, -3, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -7, 12, -4, 0, -1, 2 ], [ -6, 12, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -7, 11, -4, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -7, 12, -4, 0, -1, 2 ], [ -6, 12, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -7, 11, -4, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -6, 11, -4, 0, -2, 2 ], [ -6, 12, -3, 0, -2, 2 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ -8, 12, -3, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -7, 12, -3, 0, -2, 2 ], [ -7, 13, -4, 0, -2, 2 ] ], + [ [ -8, 12, -3, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -7, 12, -3, 0, -2, 2 ], [ -6, 12, -3, 0, -2, 2 ] ], + [ [ -8, 12, -3, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -7, 12, -4, 0, -1, 2 ], [ -6, 12, -3, 0, -2, 2 ] ], + [ [ -7, 11, -4, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -7, 12, -4, 0, -1, 2 ], [ -6, 12, -3, 0, -2, 2 ] ], + [ [ -7, 11, -4, 0, -2, 2 ], [ -6, 12, -4, 0, -2, 2 ], [ -6, 11, -4, 0, -2, 2 ], [ -6, 12, -3, 0, -2, 2 ] ] +], +"cur_uid": "4da80bfb", +"ref_uid": "731cf7ae", +"order_seed": 764613, +"dur_seed": 194916, +"motifs_seed": 249357, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 1.02, 0.0098039215686275, 0, 0.20915032679739, 0, 0.24183006535948, 0.82432432432432, 0.28758169934641, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 1.02, 0.0098039215686275, 0, 0.20915032679739, 0, 0.24183006535948, 0.82432432432432, 0.28758169934641, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 1.02, 0.0098039215686275, 0, 0.20915032679739, 0, 0.24183006535948, 0.82432432432432, 0.28758169934641, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 2, 0, 0 ], [ ] ], + [ [ 3 ], [ 1, 0, 2, 1, 1, 0, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1, 2, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3, 3, 2, 3 ], [ ] ], + [ [ 2 ], [ 0, 1, 3, 1, 3 ], [ ] ], + [ [ 3 ], [ 1, 0, 2, 1, 0, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1, 2 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 3, 3, 0 ], [ ] ], + [ [ 0 ], [ 1, 2, 3, 2, 1, 2, 3 ], [ ] ], + [ [ 3 ], [ 1, 0, 2, 0, 2 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 0 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 2, 1 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 3 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 1 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 3, 3, 2 ], [ ] ], + [ [ 0 ], [ 1, 2, 3 ], [ ] ], + [ [ 2 ], [ 3, 1, 0, 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 3, 2, 0, 2 ], [ ] ] +], +"sus_weights": [ 0.7, 0, 0 ], +"order_size": [ 20, 20.19387755102 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4da80bfb/lilypond/part_I.ly b/resources/string_quartet_3_rise/4da80bfb/lilypond/part_I.ly new file mode 100644 index 0000000..e4ed084 --- /dev/null +++ b/resources/string_quartet_3_rise/4da80bfb/lilypond/part_I.ly @@ -0,0 +1,14 @@ +{ + { gis'1^\markup { \pad-markup #0.2 "+21"} ~ } + \bar "|" + { gis'8[ ais'8^\markup { \pad-markup #0.2 "-40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}] ~ ais'4 gis'8^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ gis''8^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ais''4^\markup { \pad-markup #0.2 "-40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ } + \bar "|" + { ais''8[ fis''8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] cis'2^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} e''4^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + \bar "|" + { f''8^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ ais8^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] c'4^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ c'8[ c''8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ c''8[ ais8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { ais4 c'2^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ c'8[ d'8^\markup { \pad-markup #0.2 "+25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] } + \bar "|" + { dis'8^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}[ g''8^\markup { \pad-markup #0.2 "+23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ g''8[ ais''8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] dis''8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ f''8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] fis''8^\markup { \pad-markup #0.2 "-32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}[ f'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}]} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4da80bfb/lilypond/part_II.ly b/resources/string_quartet_3_rise/4da80bfb/lilypond/part_II.ly new file mode 100644 index 0000000..aa2e38c --- /dev/null +++ b/resources/string_quartet_3_rise/4da80bfb/lilypond/part_II.ly @@ -0,0 +1,14 @@ +{ + { dis''8^\markup { \pad-markup #0.2 "+23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ d''8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }}] cis''4^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ cis''8[ dis''8^\markup { \pad-markup #0.2 "+23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ dis''4 } + \bar "|" + { f''8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}[ g''8^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] fis''8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}[ f''8^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ f''8[ cis''8^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ cis''4 ~ } + \bar "|" + { cis''2 gis'8^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ a'8^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] e'8^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ f'8^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ } + \bar "|" + { f'2 ~ f'8[ gis'8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] a'8^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}[ ais'8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] } + \bar "|" + { dis'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ f'8^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}] ~ f'4 e'8^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }}[ g'8^\markup { \pad-markup #0.2 "+23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ g'4 ~ } + \bar "|" + { g'8[ c'8^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ c'8[ dis'8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ dis'8[ f'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ais'4^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4da80bfb/lilypond/part_III.ly b/resources/string_quartet_3_rise/4da80bfb/lilypond/part_III.ly new file mode 100644 index 0000000..70600ae --- /dev/null +++ b/resources/string_quartet_3_rise/4da80bfb/lilypond/part_III.ly @@ -0,0 +1,14 @@ +{ + { gis8^\markup { \pad-markup #0.2 "+21"}[ e'8^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}] ~ e'4 dis'8^\markup { \pad-markup #0.2 "+23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}[ f'8^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }}] cis''8^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}[ c''8^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }}] ~ } + \bar "|" + { c''8[ a8^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] b8^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}[ cis'8^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ cis'2 } + \bar "|" + { fis'8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ fis8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ fis8[ gis8^\markup { \pad-markup #0.2 "+21"}] a4^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} ~ a8[ e8^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] } + \bar "|" + { f2^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} e4^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} dis4^\markup { \pad-markup #0.2 "-20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} } + \bar "|" + { dis4^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} f4^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} g8^\markup { \pad-markup #0.2 "+23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}[ g8^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }}] c''4^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c''8[ g'8^\markup { \pad-markup #0.2 "+23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ais'2^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} f8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ dis8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}]} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4da80bfb/lilypond/part_IV.ly b/resources/string_quartet_3_rise/4da80bfb/lilypond/part_IV.ly new file mode 100644 index 0000000..b43b6de --- /dev/null +++ b/resources/string_quartet_3_rise/4da80bfb/lilypond/part_IV.ly @@ -0,0 +1,14 @@ +{ + { dis'8^\markup { \pad-markup #0.2 "+23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ dis'8^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }}] cis'8^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ c'8^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }}] ~ c'8[ b8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}] cis4^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { cis2. ~ cis8[ fis,8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { fis,2 gis,8^\markup { \pad-markup #0.2 "+21"}[ a,8^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ a,4 } + \bar "|" + { ais,4^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ ais,8[ c8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ c2 } + \bar "|" + { ais,8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ dis,8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] f,8^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ a8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}] gis4^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} ~ gis8[ g8^\markup { \pad-markup #0.2 "+23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { g4 ~ g8[ ais8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ ais2} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_I.ly b/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_I.ly index bca81dd..ba567c1 100644 --- a/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_I.ly +++ b/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_I.ly @@ -1,22 +1,22 @@ { - { b1^\markup { \pad-markup #0.2 "+36"} } + { cis'1^\markup { \pad-markup #0.2 "+36"} } \bar "|" - { fis'1^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } + { gis'1^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } \bar "|" - { fis'1 ~ } + { gis'1 ~ } \bar "|" - { fis'1 ~ } + { gis'1 ~ } \bar "|" - { fis'1 } + { gis'1 } \bar "|" - { a'1^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } + { b'1^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } \bar "|" - { a'1 } + { b'1 } \bar "|" - { ais'1^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + { c''1^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" - { ais'1 ~ } + { c''1 ~ } \bar "|" - { ais'2 b'2^\markup { \pad-markup #0.2 "-7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }}} + { c''2 cis''2^\markup { \pad-markup #0.2 "-7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_II.ly b/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_II.ly index 48f81fd..05fdfba 100644 --- a/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_II.ly +++ b/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_II.ly @@ -1,22 +1,22 @@ { - { gis1^\markup { \pad-markup #0.2 "-23"} ~ } + { ais1^\markup { \pad-markup #0.2 "-23"} ~ } \bar "|" - { gis1 } + { ais1 } \bar "|" - { dis'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} ~ } + { f'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} ~ } \bar "|" - { dis'1 ~ } + { f'1 ~ } \bar "|" - { dis'1 ~ } + { f'1 ~ } \bar "|" - { dis'1 ~ } + { f'1 ~ } \bar "|" - { dis'1 ~ } + { f'1 ~ } \bar "|" - { dis'1 ~ } + { f'1 ~ } \bar "|" - { dis'1 ~ } + { f'1 ~ } \bar "|" - { dis'1} + { f'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_III.ly b/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_III.ly index 6a243ff..0794eb2 100644 --- a/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_III.ly +++ b/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_III.ly @@ -1,22 +1,22 @@ { - { c''1^\markup { \pad-markup #0.2 "-37"} ~ } + { d''1^\markup { \pad-markup #0.2 "-37"} ~ } \bar "|" - { c''2 d'2^\markup { \pad-markup #0.2 "+25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } + { d''2 e'2^\markup { \pad-markup #0.2 "+25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } \bar "|" - { d'2 a'2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } + { e'2 b'2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } \bar "|" - { a'1 } + { b'1 } \bar "|" - { ais'1^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }} ~ } + { c''1^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }} ~ } \bar "|" - { ais'2 b'2^\markup { \pad-markup #0.2 "-7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }} ~ } + { c''2 cis''2^\markup { \pad-markup #0.2 "-7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }} ~ } \bar "|" - { b'2 dis2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + { cis''2 f2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } \bar "|" - { dis1 } + { f1 } \bar "|" - { ais2^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} b2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + { c'2^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} cis'2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } \bar "|" - { b1} + { cis'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_IV.ly b/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_IV.ly index a370cf4..6e90c4e 100644 --- a/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_IV.ly +++ b/resources/string_quartet_3_rise/4e9f1dcc/lilypond/part_IV.ly @@ -1,22 +1,22 @@ { - { b'2^\markup { \pad-markup #0.2 "+36"} e2^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }} ~ } + { cis''2^\markup { \pad-markup #0.2 "+36"} fis2^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }} ~ } \bar "|" - { e1 ~ } + { fis1 ~ } \bar "|" - { e1 } + { fis1 } \bar "|" - { b2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} b2^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } + { cis'2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} cis'2^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } \bar "|" - { b2 cis'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } + { cis'2 dis'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } \bar "|" - { cis'1 } + { dis'1 } \bar "|" - { f'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } + { g'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } \bar "|" - { f'2 gis'2^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + { g'2 ais'2^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } \bar "|" - { gis'1 } + { ais'1 } \bar "|" - { f,1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }}} + { g,1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4ef018fc/4ef018fc_code.scd b/resources/string_quartet_3_rise/4ef018fc/4ef018fc_code.scd new file mode 100644 index 0000000..57e638d --- /dev/null +++ b/resources/string_quartet_3_rise/4ef018fc/4ef018fc_code.scd @@ -0,0 +1,945 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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 = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + stepFunc.value(pDistance); +}; + +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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + [minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).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.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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, fDur, durAdd; + + 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); + }); + + //round last duration to measure + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + + 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.notNil) { + ~msg; + ~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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/4ef018fc/4ef018fc_mus_model.json b/resources/string_quartet_3_rise/4ef018fc/4ef018fc_mus_model.json new file mode 100644 index 0000000..71a4e25 --- /dev/null +++ b/resources/string_quartet_3_rise/4ef018fc/4ef018fc_mus_model.json @@ -0,0 +1,79 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 3.75 ], + [ [ [ 0, 0, 0, 0, 1, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.75 ] + ], + [ + [ [ [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, -1, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], + [ [ [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, -1, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 1, 0 ] ], 0.75 ], + [ [ [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, -1, 0, 1, 0 ], [ -1, 0, 0, 0, 1, 0 ], [ 0, -1, 0, 0, 1, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, -1, 0, 1, 0 ], [ -1, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 1, -1 ] ], 0.75 ] + ], + [ + [ [ [ 0, 0, 0, 0, 1, 0 ], [ 0, 0, -1, 0, 1, 0 ], [ 0, 0, 0, -1, 1, 0 ], [ 0, 0, 0, 0, 1, -1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 0, 0, 0, -1, 1, 0 ], [ 0, 0, 0, 0, 1, -1 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 1, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ 0, 0, 0, -1, 1, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 2.5 ] + ], + [ + [ [ [ 0, 0, 0, 0, 1, 0 ], [ "Rest" ], [ 0, 0, 0, -1, 1, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 0 ], + [ [ [ -1, 0, 0, 0, 2, 1 ], [ "Rest" ], [ 0, 0, 0, -1, 1, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 0.625 ], + [ [ [ -1, 0, 0, 0, 2, 1 ], [ "Rest" ], [ -2, 0, 0, 1, 2, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 0 ], + [ [ [ -1, 0, 0, 1, 2, 0 ], [ "Rest" ], [ -2, 0, 0, 1, 2, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 1.75 ] + ], + [ + [ [ [ -1, 0, 0, 1, 2, 0 ], [ "Rest" ], [ -1, 0, -1, 0, 2, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 2, 0 ], [ "Rest" ], [ -1, 0, -1, 0, 2, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 1.125 ], + [ [ [ 0, 0, 0, 0, 2, 0 ], [ -1, 0, 1, 0, 2, 0 ], [ -1, 0, -1, 0, 2, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 1.125 ], + [ [ [ 0, 0, 0, 0, 2, 0 ], [ -1, 0, 1, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], 2.625 ] + ], + [ + [ [ [ 0, 0, 0, 0, 2, 0 ], [ -1, 0, 1, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ], 0 ], + [ [ [ -1, 2, 0, 0, 2, 0 ], [ -1, 0, 1, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ], 0 ], + [ [ [ -1, 2, 0, 0, 2, 0 ], [ -2, 1, 0, 1, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ], 0.625 ], + [ [ [ -1, 2, 0, 0, 2, 0 ], [ -1, 1, 0, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ], 2.375 ], + [ [ [ -1, 2, 0, 0, 2, 0 ], [ -1, 1, 0, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ "Rest" ] ], 0 ], + [ [ [ -1, 2, 0, 0, 2, 0 ], [ "Rest" ], [ -2, 1, 0, 0, 2, 0 ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ -2, 1, 0, 0, 2, 0 ], [ "Rest" ] ], 1.125 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 4.125 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 2, 0 ], [ -1, 0, 1, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -1, 0, 0, 0, 2, 0 ] ], + [ [ 0, 0, 0, 0, 2, 0 ], [ -1, 0, 1, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ], + [ [ -1, 2, 0, 0, 2, 0 ], [ -1, 0, 1, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ], + [ [ -1, 2, 0, 0, 2, 0 ], [ -2, 1, 0, 1, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ], + [ [ -1, 2, 0, 0, 2, 0 ], [ -1, 1, 0, 0, 2, 0 ], [ -2, 1, 0, 0, 2, 0 ], [ -2, 2, 0, 0, 2, 0 ] ] +], +"cur_uid": "4ef018fc", +"ref_uid": "nil", +"order_seed": 612843, +"dur_seed": 369555, +"motifs_seed": 949457, +"entrances_probs_vals": [ 1, 0, 2.9365079365079, 0.47, 2.8021978021978, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0.48, 0, 2.1031746031746, 0.44, 1.3736263736264, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0.58, 0.95, 4.2063492063492, 0.58, 2.2252747252747, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2021.0526315789, 338 ], [ -1055.1083591331, 1453 ], [ -386, 1675.5417956656 ], [ -219, 1694.1176470588 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.39094650205761, 0, 0.43621399176955, 0.14772727272727, 0.47942386831276, 0, 0.51440329218107, 0, 0.56378600823045, 0.55113636363636, 0.62139917695473, 0, 1, 0 ], +"passages_weights": [ 0.7, 0.29, 0.66, 0.74, 0.68 ], +"hd_exp": 2, +"hd_invert": 0, +"order": +[ + [ [ 2 ], [ 0 ], [ 1, 3 ] ], + [ [ 0 ], [ 1, 3, 2, 3 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 3 ], [ 0, 2, 0 ], [ 1 ] ], + [ [ 3 ], [ 2, 0, 1, 2 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 5.0408163265306, 13.122448979592 ], +"passages_size": [ 0, 2 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4ef018fc/lilypond/part_I.ly b/resources/string_quartet_3_rise/4ef018fc/lilypond/part_I.ly new file mode 100644 index 0000000..f6a6dab --- /dev/null +++ b/resources/string_quartet_3_rise/4ef018fc/lilypond/part_I.ly @@ -0,0 +1,26 @@ +{ + { r1 } + \bar "|" + { r1 } + \bar "|" + { r4 c'4^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ c'8[ b8^\markup { \pad-markup #0.2 "+11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}] ~ b4 } + \bar "|" + { cis'1^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'2. ~ cis'8[ dis'8^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'4 ~ dis'8[ r8] r2 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4ef018fc/lilypond/part_II.ly b/resources/string_quartet_3_rise/4ef018fc/lilypond/part_II.ly new file mode 100644 index 0000000..59b8e14 --- /dev/null +++ b/resources/string_quartet_3_rise/4ef018fc/lilypond/part_II.ly @@ -0,0 +1,26 @@ +{ + { d'1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'2 ~ d'8[ gis8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ gis4 } + \bar "|" + { ais1^\markup { \pad-markup #0.2 "-18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { ais2 ~ ais16[ b8.^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}] ~ b4 ~ } + \bar "|" + { b4 ~ b8.[ a16^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}] ~ a2 ~ } + \bar "|" + { a2 ~ a16[ gis8.^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ gis4 ~ } + \bar "|" + { gis1 ~ } + \bar "|" + { gis1 ~ } + \bar "|" + { gis2. ~ gis8.[ r16] } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4ef018fc/lilypond/part_III.ly b/resources/string_quartet_3_rise/4ef018fc/lilypond/part_III.ly new file mode 100644 index 0000000..46b46f8 --- /dev/null +++ b/resources/string_quartet_3_rise/4ef018fc/lilypond/part_III.ly @@ -0,0 +1,26 @@ +{ + { r1 } + \bar "|" + { r1 } + \bar "|" + { r4 e'2.^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} } + \bar "|" + { dis'1^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { dis'4 r2. } + \bar "|" + { r1 } + \bar "|" + { f'1^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { f'2. ~ f'8[ fis'8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }}] ~ } + \bar "|" + { fis'8.[ gis'16^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ gis'2. ~ } + \bar "|" + { gis'4 ~ gis'8[ r8] r2 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4ef018fc/lilypond/part_IV.ly b/resources/string_quartet_3_rise/4ef018fc/lilypond/part_IV.ly new file mode 100644 index 0000000..5c0d6f1 --- /dev/null +++ b/resources/string_quartet_3_rise/4ef018fc/lilypond/part_IV.ly @@ -0,0 +1,26 @@ +{ + { r1 } + \bar "|" + { r2. r8[ gis'8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↑" }}] ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'4 a'4^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} ~ a'16[ b'8.^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ b'4 ~ } + \bar "|" + { b'4 ~ b'8.[ cis''16^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ cis''2 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''2. ~ cis''8[ dis''8^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { dis''1 ~ } + \bar "|" + { dis''4 ~ dis''8[ r8] r2 } + \bar "|" + { r1 } + \bar "|" + { r1 } +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4f53a446/4f53a446_code.scd b/resources/string_quartet_3_rise/4f53a446/4f53a446_code.scd new file mode 100644 index 0000000..e1a9d92 --- /dev/null +++ b/resources/string_quartet_3_rise/4f53a446/4f53a446_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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"], {(62.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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/4f53a446/4f53a446_mus_model.json b/resources/string_quartet_3_rise/4f53a446/4f53a446_mus_model.json new file mode 100644 index 0000000..5af5206 --- /dev/null +++ b/resources/string_quartet_3_rise/4f53a446/4f53a446_mus_model.json @@ -0,0 +1,64 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -5, 6, 0, 2, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 1.125 ], + [ [ [ -3, 4, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 1.875 ], + [ [ [ -4, 6, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 2 ], + [ [ [ -4, 5, 0, 1, -2, 3 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 1.5 ], + [ [ [ -3, 5, 0, 1, -3, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 1.5 ] + ], + [ + [ [ [ -2, 4, 0, 1, -2, 1 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 1.875 ], + [ [ [ -4, 4, 0, 2, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 1.75 ] + ], + [ + [ [ [ -4, 4, 0, 2, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 4, 0, 2, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 5, -1, 2, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -2, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 5, -1, 2, -2, 2 ] ], 1.125 ], + [ [ [ -3, 5, -2, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 5, -2, 1, -2, 2 ] ], 0.75 ], + [ [ [ -3, 5, -2, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -2, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 6, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 6.25 ] + ] + ] +], +"last_changes": +[ + [ [ -3, 5, -2, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 5, -1, 2, -2, 2 ] ], + [ [ -3, 5, -2, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 5, -2, 1, -2, 2 ] ], + [ [ -3, 5, -2, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], + [ [ -3, 5, -2, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], + [ [ -6, 6, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ] +], +"cur_uid": "4f53a446", +"ref_uid": "5f3f1c84", +"order_seed": 818224, +"dur_seed": 715279, +"motifs_seed": 485520, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 3, 0.0098039215686275, 0, 0.20915032679739, 0, 0.44444444444444, 0.80743243243243, 0.76470588235294, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 3, 0.0098039215686275, 0, 0.20915032679739, 0, 0.44444444444444, 0.80743243243243, 0.76470588235294, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 3, 0.0098039215686275, 0, 0.20915032679739, 0, 0.44444444444444, 0.80743243243243, 0.76470588235294, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 2, 1 ], [ 3, 0, 0, 0 ], [ ] ], + [ [ 3, 1 ], [ 0, 2, 0 ], [ ] ], + [ [ 1, 2, 3 ], [ 0, 0 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 3, 3, 1, 0 ], [ ] ] +], +"sus_weights": [ 0.7, 0.48, 0.49 ], +"order_size": [ 4, 4.030612244898 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4f53a446/lilypond/part_I.ly b/resources/string_quartet_3_rise/4f53a446/lilypond/part_I.ly new file mode 100644 index 0000000..629df46 --- /dev/null +++ b/resources/string_quartet_3_rise/4f53a446/lilypond/part_I.ly @@ -0,0 +1,22 @@ +{ + { ais1^\markup { \pad-markup #0.2 "-45"} ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais1 ~ } + \bar "|" + { ais4 ~ ais16[ ais8.^\markup { \pad-markup #0.2 "+40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }}] ~ ais4 ~ ais8[ a8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { a4 gis2.^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + \bar "|" + { gis1 ~ } + \bar "|" + { gis1} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4f53a446/lilypond/part_II.ly b/resources/string_quartet_3_rise/4f53a446/lilypond/part_II.ly new file mode 100644 index 0000000..74ba4e1 --- /dev/null +++ b/resources/string_quartet_3_rise/4f53a446/lilypond/part_II.ly @@ -0,0 +1,22 @@ +{ + { d'1^\markup { \pad-markup #0.2 "+26"} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 } + \bar "|" + { cis'1^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1 ~ } + \bar "|" + { cis'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4f53a446/lilypond/part_III.ly b/resources/string_quartet_3_rise/4f53a446/lilypond/part_III.ly new file mode 100644 index 0000000..69d6915 --- /dev/null +++ b/resources/string_quartet_3_rise/4f53a446/lilypond/part_III.ly @@ -0,0 +1,22 @@ +{ + { f'1^\markup { \pad-markup #0.2 "-43"} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'4 ~ f'16[ fis'8.^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] ~ fis'2 ~ } + \bar "|" + { fis'4 gis'2.^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { gis'1 ~ } + \bar "|" + { gis'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/4f53a446/lilypond/part_IV.ly b/resources/string_quartet_3_rise/4f53a446/lilypond/part_IV.ly new file mode 100644 index 0000000..21a8095 --- /dev/null +++ b/resources/string_quartet_3_rise/4f53a446/lilypond/part_IV.ly @@ -0,0 +1,22 @@ +{ + { a'2^\markup { \pad-markup #0.2 "+28"} ~ a'16[ ais'8.^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ ais'4 ~ } + \bar "|" + { ais'2 c''2^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { c''2 cis''2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }} } + \bar "|" + { cis''2.^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} b'4^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } + \bar "|" + { b'2 cis''2^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }} ~ } + \bar "|" + { cis''4 ~ cis''8.[ g'16^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}] ~ g'2 ~ } + \bar "|" + { g'4 ~ g'16[ a'8.^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] ~ a'2 ~ } + \bar "|" + { a'4 gis,2.^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { gis,1 ~ } + \bar "|" + { gis,1} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/521654f8/lilypond/part_I.ly b/resources/string_quartet_3_rise/521654f8/lilypond/part_I.ly index 4b86b39..9dbd058 100644 --- a/resources/string_quartet_3_rise/521654f8/lilypond/part_I.ly +++ b/resources/string_quartet_3_rise/521654f8/lilypond/part_I.ly @@ -1,22 +1,22 @@ { - { f'1^\markup { \pad-markup #0.2 "-25"} ~ } + { g'1^\markup { \pad-markup #0.2 "-25"} ~ } \bar "|" - { f'2 c''2^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }} ~ } + { g'2 d''2^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }} ~ } \bar "|" - { c''2 g2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { d''2 a2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g1 } + { a1 } \bar "|" - { b1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { cis'1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { b2 ais'2^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + { cis'2 c''2^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" - { ais'1 ~ } + { c''1 ~ } \bar "|" - { ais'2 ais'2^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + { c''2 c''2^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } \bar "|" - { ais'1} + { c''1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/521654f8/lilypond/part_II.ly b/resources/string_quartet_3_rise/521654f8/lilypond/part_II.ly index 03e091f..ed0f60d 100644 --- a/resources/string_quartet_3_rise/521654f8/lilypond/part_II.ly +++ b/resources/string_quartet_3_rise/521654f8/lilypond/part_II.ly @@ -1,22 +1,22 @@ { - { gis'1^\markup { \pad-markup #0.2 "-9"} ~ } + { ais'1^\markup { \pad-markup #0.2 "-9"} ~ } \bar "|" - { gis'1 ~ } + { ais'1 ~ } \bar "|" - { gis'1 } + { ais'1 } \bar "|" - { b'1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + { cis''1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } \bar "|" - { b'1 ~ } + { cis''1 ~ } \bar "|" - { b'1 ~ } + { cis''1 ~ } \bar "|" - { b'1 } + { cis''1 } \bar "|" - { b'2^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }} c''2^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} ~ } + { cis''2^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }} d''2^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} ~ } \bar "|" - { c''1 } + { d''1 } \bar "|" - { e'1^\markup { \pad-markup #0.2 "-20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}} + { fis'1^\markup { \pad-markup #0.2 "-20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/521654f8/lilypond/part_III.ly b/resources/string_quartet_3_rise/521654f8/lilypond/part_III.ly index 8972ef2..41a7194 100644 --- a/resources/string_quartet_3_rise/521654f8/lilypond/part_III.ly +++ b/resources/string_quartet_3_rise/521654f8/lilypond/part_III.ly @@ -1,22 +1,22 @@ { - { a'2^\markup { \pad-markup #0.2 "+46"} c''2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { b'2^\markup { \pad-markup #0.2 "+46"} d''2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { c''1 ~ } + { d''1 ~ } \bar "|" - { c''1 ~ } + { d''1 ~ } \bar "|" - { c''2 c'2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } + { d''2 d'2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } \bar "|" - { dis'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} ~ } + { f'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} ~ } \bar "|" - { dis'1 ~ } + { f'1 ~ } \bar "|" - { dis'1 ~ } + { f'1 ~ } \bar "|" - { dis'1 } + { f'1 } \bar "|" - { gis'1^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + { ais'1^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } \bar "|" - { gis'2 e2^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}} + { ais'2 fis2^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/521654f8/lilypond/part_IV.ly b/resources/string_quartet_3_rise/521654f8/lilypond/part_IV.ly index 25ed6e8..c33586c 100644 --- a/resources/string_quartet_3_rise/521654f8/lilypond/part_IV.ly +++ b/resources/string_quartet_3_rise/521654f8/lilypond/part_IV.ly @@ -1,22 +1,22 @@ { - { f1^\markup { \pad-markup #0.2 "-25"} } + { g1^\markup { \pad-markup #0.2 "-25"} } \bar "|" - { c'1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} } + { d'1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} } \bar "|" - { g'1^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + { a'1^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" - { g'1 ~ } + { a'1 ~ } \bar "|" - { g'2 b,2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + { a'2 cis2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } \bar "|" - { b,2 fis2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} } + { cis2 gis2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} } \bar "|" - { c'1^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + { d'1^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } \bar "|" - { c'1 ~ } + { d'1 ~ } \bar "|" - { c'1 ~ } + { d'1 ~ } \bar "|" - { c'1} + { d'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/531df78c/lilypond/part_I.ly b/resources/string_quartet_3_rise/531df78c/lilypond/part_I.ly index 0acee0f..7220198 100644 --- a/resources/string_quartet_3_rise/531df78c/lilypond/part_I.ly +++ b/resources/string_quartet_3_rise/531df78c/lilypond/part_I.ly @@ -1,48 +1,48 @@ { - { fis'1^\markup { \pad-markup #0.2 "+21"} } + { gis'1^\markup { \pad-markup #0.2 "+21"} } \bar "|" - { d'1^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} } + { e'1^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} } \bar "|" - { e'1^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} } + { fis'1^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} } \bar "|" - { f'1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + { g'1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } \bar "|" - { f'1 ~ } + { g'1 ~ } \bar "|" - { f'1 ~ } + { g'1 ~ } \bar "|" - { f'1 ~ } + { g'1 ~ } \bar "|" - { f'1 ~ } + { g'1 ~ } \bar "|" - { f'2 g'2^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { g'2 a'2^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { g'1 } + { a'1 } \bar "|" - { a'1^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + { b'1^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" - { a'1 } + { b'1 } \bar "|" - { b'1^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + { cis''1^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } \bar "|" - { b'1 ~ } + { cis''1 ~ } \bar "|" - { b'1 ~ } + { cis''1 ~ } \bar "|" - { b'2 c''2^\markup { \pad-markup #0.2 "-24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } + { cis''2 d''2^\markup { \pad-markup #0.2 "-24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } \bar "|" - { c''1 } + { d''1 } \bar "|" - { gis1^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { ais1^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { gis1 } + { ais1 } \bar "|" - { f'1^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + { g'1^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } \bar "|" - { f'1 ~ } + { g'1 ~ } \bar "|" - { f'2 gis'2^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + { g'2 ais'2^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } \bar "|" - { gis'1} + { ais'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/531df78c/lilypond/part_II.ly b/resources/string_quartet_3_rise/531df78c/lilypond/part_II.ly index 71926a1..3208fce 100644 --- a/resources/string_quartet_3_rise/531df78c/lilypond/part_II.ly +++ b/resources/string_quartet_3_rise/531df78c/lilypond/part_II.ly @@ -1,48 +1,48 @@ { - { a1^\markup { \pad-markup #0.2 "-48"} ~ } + { b1^\markup { \pad-markup #0.2 "-48"} ~ } \bar "|" - { a1 ~ } + { b1 ~ } \bar "|" - { a1 ~ } + { b1 ~ } \bar "|" - { a1 ~ } + { b1 ~ } \bar "|" - { a1 ~ } + { b1 ~ } \bar "|" - { a2 ais2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + { b2 c'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } \bar "|" - { ais2 c'2^\markup { \pad-markup #0.2 "-32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} } + { c'2 d'2^\markup { \pad-markup #0.2 "-32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} } \bar "|" - { fis'1^\markup { \pad-markup #0.2 "+48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} } + { gis'1^\markup { \pad-markup #0.2 "+48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} } \bar "|" - { ais'1^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + { c''1^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } \bar "|" - { ais'2 g2^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { c''2 a2^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g2 a2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { a2 b2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } \bar "|" - { a1 ~ } + { b1 ~ } \bar "|" - { a2 cis'2^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + { b2 dis'2^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } \bar "|" - { cis'1 ~ } + { dis'1 ~ } \bar "|" - { cis'1 ~ } + { dis'1 ~ } \bar "|" - { cis'2 dis'2^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + { dis'2 f'2^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" - { dis'2 fis'2^\markup { \pad-markup #0.2 "-42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} } + { f'2 gis'2^\markup { \pad-markup #0.2 "-42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} } \bar "|" - { ais'1^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + { c''1^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } \bar "|" - { ais'1 ~ } + { c''1 ~ } \bar "|" - { ais'1 ~ } + { c''1 ~ } \bar "|" - { ais'1 } + { c''1 } \bar "|" - { d'1^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}} + { e'1^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/531df78c/lilypond/part_III.ly b/resources/string_quartet_3_rise/531df78c/lilypond/part_III.ly index 95b2a0b..9a6bd85 100644 --- a/resources/string_quartet_3_rise/531df78c/lilypond/part_III.ly +++ b/resources/string_quartet_3_rise/531df78c/lilypond/part_III.ly @@ -1,48 +1,48 @@ { - { a'1^\markup { \pad-markup #0.2 "-48"} ~ } + { b'1^\markup { \pad-markup #0.2 "-48"} ~ } \bar "|" - { a'1 ~ } + { b'1 ~ } \bar "|" - { a'2 b'2^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { b'2 cis''2^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { b'2 c''2^\markup { \pad-markup #0.2 "-32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } + { cis''2 d''2^\markup { \pad-markup #0.2 "-32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } \bar "|" - { c''1 } + { d''1 } \bar "|" - { f1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} } + { g1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} } \bar "|" - { d'1^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + { e'1^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } \bar "|" - { d'1 ~ } + { e'1 ~ } \bar "|" - { d'1 } + { e'1 } \bar "|" - { d'1^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + { e'1^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } \bar "|" - { d'2 dis'2^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + { e'2 f'2^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } \bar "|" - { dis'1 ~ } + { f'1 ~ } \bar "|" - { dis'2 e'2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + { f'2 fis'2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } \bar "|" - { e'1 } + { fis'1 } \bar "|" - { g'1^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} } + { a'1^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} } \bar "|" - { gis'1^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + { ais'1^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } \bar "|" - { gis'1 ~ } + { ais'1 ~ } \bar "|" - { gis'1 ~ } + { ais'1 ~ } \bar "|" - { gis'1 ~ } + { ais'1 ~ } \bar "|" - { gis'1 } + { ais'1 } \bar "|" - { ais1^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + { c'1^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } \bar "|" - { f'1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + { g'1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } \bar "|" - { f'2 c''2^\markup { \pad-markup #0.2 "-24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }}} + { g'2 d''2^\markup { \pad-markup #0.2 "-24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/531df78c/lilypond/part_IV.ly b/resources/string_quartet_3_rise/531df78c/lilypond/part_IV.ly index 52220bd..bbcb5c1 100644 --- a/resources/string_quartet_3_rise/531df78c/lilypond/part_IV.ly +++ b/resources/string_quartet_3_rise/531df78c/lilypond/part_IV.ly @@ -1,48 +1,48 @@ { - { d2^\markup { \pad-markup #0.2 "-50"} e2^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + { e2^\markup { \pad-markup #0.2 "-50"} fis2^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" - { e2 b2^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + { fis2 cis'2^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b1 } + { cis'1 } \bar "|" - { c'2^\markup { \pad-markup #0.2 "-32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} a'2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + { d'2^\markup { \pad-markup #0.2 "-32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} b'2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } \bar "|" - { a'1 ~ } + { b'1 ~ } \bar "|" - { a'1 ~ } + { b'1 ~ } \bar "|" - { a'2 c''2^\markup { \pad-markup #0.2 "-32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } + { b'2 d''2^\markup { \pad-markup #0.2 "-32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } \bar "|" - { c''1 ~ } + { d''1 ~ } \bar "|" - { c''1 ~ } + { d''1 ~ } \bar "|" - { c''1 } + { d''1 } \bar "|" - { g'1^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + { a'1^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } \bar "|" - { g'1 } + { a'1 } \bar "|" - { gis'1^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } + { ais'1^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } \bar "|" - { gis'2 a'2^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + { ais'2 b'2^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } \bar "|" - { a'1 } + { b'1 } \bar "|" - { cis1^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + { dis1^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } \bar "|" - { cis1 ~ } + { dis1 ~ } \bar "|" - { cis2 dis2^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + { dis2 f2^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" - { dis2 f2^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { f2 g2^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } \bar "|" - { f2 ais,2^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { g2 c2^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { ais,1 ~ } + { c1 ~ } \bar "|" - { ais,1} + { c1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/5f38e4bd/5f38e4bd_code.scd b/resources/string_quartet_3_rise/5f38e4bd/5f38e4bd_code.scd new file mode 100644 index 0000000..070e09d --- /dev/null +++ b/resources/string_quartet_3_rise/5f38e4bd/5f38e4bd_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/5f38e4bd/5f38e4bd_mus_model.json b/resources/string_quartet_3_rise/5f38e4bd/5f38e4bd_mus_model.json new file mode 100644 index 0000000..b1057d9 --- /dev/null +++ b/resources/string_quartet_3_rise/5f38e4bd/5f38e4bd_mus_model.json @@ -0,0 +1,422 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 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.25 ], + [ [ [ 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 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 2, -1, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, 0, 0, 0 ], [ 2, -1, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, 0, 0, 0 ], [ 2, -1, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 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.25 ], + [ [ [ 1, -1, -1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, -1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ 0, -1, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 0.25 ], + [ [ [ 1, 0, -2, 0, 0, 0 ], [ 0, -1, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 1, 0, -2, 0, 0, 0 ], [ 0, -1, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 0, -1, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 1, -1, -1, -1, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 1, -1, -1, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.25 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ], [ 3, -1, -2, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ], [ 3, -1, -2, -1, 0, 0 ], [ 2, -1, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 1, 0, -2, 0, 0, 0 ], [ 3, -1, -2, -1, 0, 0 ], [ 2, -1, -2, -1, 0, 0 ] ], 0.25 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 3, -1, -2, -1, 0, 0 ], [ 2, -1, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 3, -1, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 2, 0, -3, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ] ], 0.25 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 3, -1, -2, -1, 0, 0 ], [ 2, 0, -3, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 3, -1, -2, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ] ], 0.25 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 3, -1, -2, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ], [ 2, 0, -3, -1, 0, 0 ] ], 0 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ], [ 2, 0, -3, -1, 0, 0 ] ], 0.25 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 2, 0, -3, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 3, 0, -3, -1, 0, 0 ], [ 2, 0, -3, -1, 0, 0 ] ], 0 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 3, 0, -3, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 2, 0, -3, -1, 0, 0 ], [ 3, 0, -3, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ] ], 0.25 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 3, 0, -3, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ] ], 0.25 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 2, 0, -2, 0, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ] ], 0.25 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 1, 0, -2, 0, 0, 0 ], [ 2, 0, -2, 0, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 1, 0, -2, 0, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 0, 2, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 1, 2, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 0, 2, -2, -1, 0, 0 ] ], 0.25 ], + [ [ [ 2, 1, -3, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 0, 2, -2, -1, 0, 0 ] ], 0.25 ], + [ [ [ 1, 1, -2, 0, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 0, 2, -2, -1, 0, 0 ] ], 0.25 ], + [ [ [ 2, 1, -2, -2, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 0, 2, -2, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 1, -1, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 0, 2, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -1, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 1, 1, -3, -1, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -1, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 1, 1, -3, -1, 0, 0 ] ], 0.25 ], + [ [ [ 2, 0, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 1, 1, -3, -1, 0, 0 ] ], 0.25 ], + [ [ [ 0, 2, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 1, 1, -3, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 2, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 2, 1, -3, -1, 0, 0 ], [ 1, 1, -3, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 2, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 1, 1, -2, 0, 0, 0 ], [ 1, 1, -3, -1, 0, 0 ] ], 0.25 ], + [ [ [ 0, 2, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 1, 1, -2, 0, 0, 0 ], [ 0, 1, -2, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 1, -2, 0, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 1, 1, -2, 0, 0, 0 ], [ 0, 1, -2, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 1, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 1, 1, -2, 0, 0, 0 ], [ 0, 1, -2, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 0, 1, -2, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 1, -2, -2, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 0, 1, -2, 0, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -2, -2, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 2, 1, -2, -2, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -2, -2, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 3, 1, -2, -2, 0, 0 ], [ 2, 1, -2, -2, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 1, -2, -2, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 2, 1, -2, -2, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 2, 1, -2, -2, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 0, 2, -2, -1, 0, 0 ] ], 0.25 ], + [ [ [ 0, 1, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 0, 2, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 2, 0, -2, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 1, -2, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 2, 0, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -2, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -2, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ], [ 2, 0, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ] ], 0.25 ], + [ [ [ 0, 1, -2, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -2, -1, 0, 0 ], [ 0, 2, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 2, -2, -1, 0, 0 ], [ 0, 2, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -2, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 2, 1, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -2, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 0, 2, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ] ], 0.25 ], + [ [ [ -1, 2, -2, -1, 0, 0 ], [ 0, 1, -2, -1, 0, 0 ], [ 0, 2, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -2, -1, 0, 0 ], [ 0, 1, -2, -1, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 2, -2, -1, 0, 0 ], [ 0, 1, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 1 ], [ 1, 1, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -3, -1, 0, 0 ], [ 0, 1, -2, -1, 0, 0 ], [ 1, 1, -2, -1, 0, 1 ], [ 1, 1, -2, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -3, -1, 0, 0 ], [ 0, 1, -2, -1, 0, 1 ], [ 1, 1, -2, -1, 0, 1 ], [ 1, 1, -2, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 1, -3, -1, 0, 0 ], [ 0, 1, -2, -1, 0, 1 ], [ 1, 1, -2, -1, 0, 1 ], [ 1, 0, -2, -1, 0, 1 ] ], 0 ], + [ [ [ 0, 1, -3, -1, 0, 0 ], [ 0, 1, -2, -1, 0, 1 ], [ 1, 1, -2, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 1 ] ], 0.25 ], + [ [ [ -1, 0, -2, -1, 0, 1 ], [ 0, 1, -2, -1, 0, 1 ], [ 1, 1, -2, -1, 0, 0 ], [ 1, 0, -2, -1, 0, 1 ] ], 0 ], + [ [ [ -1, 0, -2, -1, 0, 1 ], [ 0, 1, -2, -1, 0, 1 ], [ 1, 1, -2, -1, 0, 0 ], [ 0, 2, -2, -1, 0, 1 ] ], 0.25 ], + [ [ [ -1, 0, -2, -1, 0, 1 ], [ 0, 1, -2, -1, 0, 1 ], [ 1, 1, -2, -1, 0, 0 ], [ 1, 1, -3, -1, 0, 1 ] ], 0.25 ] + ], + [ + [ [ [ -1, 0, -2, -1, 0, 1 ], [ 0, 1, -2, -1, 0, 1 ], [ 0, 1, -3, -1, 0, 2 ], [ 1, 1, -3, -1, 0, 1 ] ], 0 ], + [ [ [ -1, 1, -2, -1, 0, 1 ], [ 0, 1, -2, -1, 0, 1 ], [ 0, 1, -3, -1, 0, 2 ], [ 1, 1, -3, -1, 0, 1 ] ], 0 ], + [ [ [ -1, 1, -2, -1, 0, 1 ], [ 1, 0, -3, -1, 0, 1 ], [ 0, 1, -3, -1, 0, 2 ], [ 1, 1, -3, -1, 0, 1 ] ], 0.25 ] + ], + [ + [ [ [ -1, 1, -2, -1, 0, 1 ], [ 0, 1, -3, -1, 0, 1 ], [ 0, 1, -3, -1, 0, 2 ], [ 1, 1, -3, -1, 0, 1 ] ], 0 ], + [ [ [ -1, 0, -3, -1, 0, 2 ], [ 0, 1, -3, -1, 0, 1 ], [ 0, 1, -3, -1, 0, 2 ], [ 1, 1, -3, -1, 0, 1 ] ], 0 ], + [ [ [ -1, 0, -3, -1, 0, 2 ], [ 0, 1, -3, -1, 0, 1 ], [ 0, 1, -3, -1, 0, 2 ], [ 0, 0, -3, -1, 0, 2 ] ], 0.25 ], + [ [ [ -1, 0, -3, -1, 0, 2 ], [ 0, 1, -3, -1, 0, 1 ], [ 0, 1, -3, -1, 0, 2 ], [ -1, 2, -3, -1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 2, -3, -1, 0, 2 ], [ 0, 1, -3, -1, 0, 1 ], [ 0, 1, -3, -1, 0, 2 ], [ -1, 2, -3, -1, 0, 2 ] ], 0 ], + [ [ [ -2, 2, -3, -1, 0, 2 ], [ 0, 1, -3, -1, 0, 1 ], [ 0, 1, -3, -1, 0, 2 ], [ 1, 0, -3, -1, 0, 2 ] ], 0 ], + [ [ [ -2, 2, -3, -1, 0, 2 ], [ 0, 0, -3, -1, 0, 2 ], [ 0, 1, -3, -1, 0, 2 ], [ 1, 0, -3, -1, 0, 2 ] ], 0.25 ], + [ [ [ -2, 1, -3, -1, 0, 2 ], [ 0, 0, -3, -1, 0, 2 ], [ 0, 1, -3, -1, 0, 2 ], [ 1, 0, -3, -1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 1, -3, -1, 0, 2 ], [ 0, 0, -3, -1, 0, 2 ], [ 0, 0, -3, -1, 0, 3 ], [ 1, 0, -3, -1, 0, 2 ] ], 0 ], + [ [ [ -2, 1, -3, -1, 0, 2 ], [ 0, 0, -3, -1, 0, 2 ], [ 0, 0, -3, -1, 0, 3 ], [ 1, -1, -3, -1, 0, 2 ] ], 0 ], + [ [ [ 0, -1, -3, -1, 0, 2 ], [ 0, 0, -3, -1, 0, 2 ], [ 0, 0, -3, -1, 0, 3 ], [ 1, -1, -3, -1, 0, 2 ] ], 0.25 ], + [ [ [ 0, -1, -3, -1, 0, 2 ], [ 0, 0, -3, -1, 0, 2 ], [ 0, 0, -3, -1, 0, 3 ], [ 0, 1, -3, -1, 0, 2 ] ], 0 ], + [ [ [ 0, -1, -3, -1, 0, 2 ], [ 0, 0, -3, -1, 0, 2 ], [ 0, 0, -3, 0, 0, 2 ], [ 0, 1, -3, -1, 0, 2 ] ], 0.25 ], + [ [ [ -1, 1, -3, -1, 0, 2 ], [ 0, 0, -3, -1, 0, 2 ], [ 0, 0, -3, 0, 0, 2 ], [ 0, 1, -3, -1, 0, 2 ] ], 0.25 ], + [ [ [ 1, -1, -3, -1, 0, 2 ], [ 0, 0, -3, -1, 0, 2 ], [ 0, 0, -3, 0, 0, 2 ], [ 0, 1, -3, -1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, -3, -1, 0, 2 ], [ 0, 1, -3, -1, -1, 2 ], [ 0, 0, -3, 0, 0, 2 ], [ 0, 1, -3, -1, 0, 2 ] ], 0 ], + [ [ [ 1, 1, -3, -1, -1, 2 ], [ 0, 1, -3, -1, -1, 2 ], [ 0, 0, -3, 0, 0, 2 ], [ 0, 1, -3, -1, 0, 2 ] ], 0 ], + [ [ [ 1, 1, -3, -1, -1, 2 ], [ 0, 1, -3, -1, -1, 2 ], [ 1, 0, -3, -1, 0, 2 ], [ 0, 1, -3, -1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ 1, 1, -3, -1, -1, 2 ], [ 0, 1, -3, -1, -1, 2 ], [ 1, 0, -3, -1, 0, 2 ], [ 0, 2, -3, -1, -1, 2 ] ], 0 ], + [ [ [ 1, 1, -3, -1, -1, 2 ], [ 0, 1, -3, -1, -1, 2 ], [ 1, 2, -3, -1, -1, 2 ], [ 0, 2, -3, -1, -1, 2 ] ], 0.25 ], + [ [ [ -1, 2, -3, -1, -1, 2 ], [ 0, 1, -3, -1, -1, 2 ], [ 1, 2, -3, -1, -1, 2 ], [ 0, 2, -3, -1, -1, 2 ] ], 0 ], + [ [ [ -1, 2, -3, -1, -1, 2 ], [ 0, 1, -3, -1, -1, 2 ], [ 1, 1, -3, -1, -1, 2 ], [ 0, 2, -3, -1, -1, 2 ] ], 0.25 ], + [ [ [ -1, 2, -3, -1, -1, 2 ], [ 0, 1, -3, -1, -1, 2 ], [ 0, 1, -2, -1, -1, 2 ], [ 0, 2, -3, -1, -1, 2 ] ], 0.25 ], + [ [ [ -1, 2, -3, -1, -1, 2 ], [ 0, 1, -3, -1, -1, 2 ], [ 1, 0, -3, -1, -1, 2 ], [ 0, 2, -3, -1, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -1, 2, -3, -1, -1, 2 ], [ 0, 1, -3, -1, -1, 2 ], [ 1, 0, -3, -1, -1, 2 ], [ 1, 1, -3, -1, -1, 2 ] ], 0.25 ], + [ [ [ -1, 2, -3, -1, -1, 2 ], [ -1, 2, -2, -1, -1, 2 ], [ 1, 0, -3, -1, -1, 2 ], [ 1, 1, -3, -1, -1, 2 ] ], 0 ], + [ [ [ -1, 2, -3, -1, -1, 2 ], [ -1, 2, -2, -1, -1, 2 ], [ 0, 2, -3, -1, -1, 2 ], [ 1, 1, -3, -1, -1, 2 ] ], 0.25 ], + [ [ [ -1, 2, -3, -1, -1, 2 ], [ -1, 2, -2, -1, -1, 2 ], [ 0, 2, -3, -1, -1, 2 ], [ 0, 2, -2, -1, -1, 2 ] ], 0 ], + [ [ [ -1, 2, -3, -1, -1, 2 ], [ -1, 2, -2, -1, -1, 2 ], [ 0, 2, -3, 0, -1, 2 ], [ 0, 2, -2, -1, -1, 2 ] ], 0.25 ], + [ [ [ -1, 2, -3, -1, -1, 2 ], [ -1, 2, -2, -1, -1, 2 ], [ 0, 2, -3, 0, -1, 2 ], [ -1, 2, -3, 0, -1, 2 ] ], 0.25 ], + [ [ [ -1, 2, -3, -1, -1, 2 ], [ -1, 2, -2, -1, -1, 2 ], [ 0, 2, -3, 0, -1, 2 ], [ 0, 2, -3, -1, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -1, 2, -3, -1, -1, 2 ], [ -1, 2, -2, -1, -1, 2 ], [ 1, 2, -3, -1, -1, 2 ], [ 0, 2, -3, -1, -1, 2 ] ], 0 ], + [ [ [ -1, 3, -3, -1, -1, 2 ], [ -1, 2, -2, -1, -1, 2 ], [ 1, 2, -3, -1, -1, 2 ], [ 0, 2, -3, -1, -1, 2 ] ], 0.25 ], + [ [ [ -1, 3, -3, -1, -1, 2 ], [ 0, 1, -3, -1, -1, 2 ], [ 1, 2, -3, -1, -1, 2 ], [ 0, 2, -3, -1, -1, 2 ] ], 0 ], + [ [ [ 0, 2, -4, -1, -1, 2 ], [ 0, 1, -3, -1, -1, 2 ], [ 1, 2, -3, -1, -1, 2 ], [ 0, 2, -3, -1, -1, 2 ] ], 0 ], + [ [ [ 0, 2, -4, -1, -1, 2 ], [ 0, 1, -3, -1, -1, 2 ], [ 1, 1, -3, -1, -1, 2 ], [ 0, 2, -3, -1, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ 0, 2, -4, -1, -1, 2 ], [ 0, 2, -5, -1, -1, 2 ], [ 1, 1, -3, -1, -1, 2 ], [ 0, 2, -3, -1, -1, 2 ] ], 0 ], + [ [ [ 0, 2, -4, -1, -1, 2 ], [ 0, 2, -5, -1, -1, 2 ], [ 1, 1, -3, -1, -1, 2 ], [ 1, 1, -4, -1, -1, 2 ] ], 0 ], + [ [ [ 0, 2, -4, -1, -1, 2 ], [ 0, 2, -5, -1, -1, 2 ], [ 0, 2, -4, 0, -1, 2 ], [ 1, 1, -4, -1, -1, 2 ] ], 0.25 ], + [ [ [ 0, 2, -4, -1, -1, 2 ], [ -1, 2, -4, -1, -1, 2 ], [ 0, 2, -4, 0, -1, 2 ], [ 1, 1, -4, -1, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -1, 3, -4, 0, -1, 2 ], [ -1, 2, -4, -1, -1, 2 ], [ 0, 2, -4, 0, -1, 2 ], [ 1, 1, -4, -1, -1, 2 ] ], 0 ], + [ [ [ -1, 3, -4, 0, -1, 2 ], [ -1, 2, -4, -1, -1, 2 ], [ 0, 2, -4, 0, -1, 2 ], [ -1, 2, -4, 0, -1, 2 ] ], 0 ], + [ [ [ -1, 3, -4, 0, -1, 2 ], [ -2, 3, -4, 0, -1, 2 ], [ 0, 2, -4, 0, -1, 2 ], [ -1, 2, -4, 0, -1, 2 ] ], 0.25 ], + [ [ [ -1, 3, -4, 0, -1, 2 ], [ -2, 3, -4, 0, -1, 2 ], [ 0, 2, -4, 0, -1, 2 ], [ 0, 3, -4, 0, -1, 2 ] ], 0 ], + [ [ [ -1, 3, -4, 0, -1, 2 ], [ -1, 2, -4, 0, -1, 2 ], [ 0, 2, -4, 0, -1, 2 ], [ 0, 3, -4, 0, -1, 2 ] ], 0 ], + [ [ [ -1, 2, -4, 0, 0, 2 ], [ -1, 2, -4, 0, -1, 2 ], [ 0, 2, -4, 0, -1, 2 ], [ 0, 3, -4, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 3, -4, 0, -1, 2 ], [ -1, 2, -4, 0, -1, 2 ], [ 0, 2, -4, 0, -1, 2 ], [ 0, 3, -4, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 2, -4, 0, -1, 2 ], [ -1, 2, -4, 0, -1, 2 ], [ 0, 2, -4, 0, -1, 2 ], [ 0, 3, -4, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 2, -4, 0, -1, 2 ], [ -1, 2, -4, 0, -1, 2 ], [ -1, 3, -4, 0, -1, 2 ], [ 0, 3, -4, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 2, -4, 0, -1, 2 ], [ -2, 4, -4, 0, -1, 2 ], [ -1, 3, -4, 0, -1, 2 ], [ 0, 3, -4, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 2, -4, 0, -1, 2 ], [ -2, 4, -4, 0, -1, 2 ], [ -1, 4, -4, 0, -1, 2 ], [ 0, 3, -4, 0, -1, 2 ] ], 0 ], + [ [ [ -3, 4, -4, 0, -1, 2 ], [ -2, 4, -4, 0, -1, 2 ], [ -1, 4, -4, 0, -1, 2 ], [ 0, 3, -4, 0, -1, 2 ] ], 0.25 ], + [ [ [ -3, 4, -4, 0, -1, 2 ], [ -2, 4, -4, 0, -1, 2 ], [ 0, 3, -5, 0, -1, 2 ], [ 0, 3, -4, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 4, -4, 0, -1, 2 ], [ -1, 3, -5, 0, -1, 2 ], [ 0, 3, -5, 0, -1, 2 ], [ 0, 3, -4, 0, -1, 2 ] ], 0 ], + [ [ [ -3, 4, -4, 0, -1, 2 ], [ -1, 3, -5, 0, -1, 2 ], [ 0, 3, -5, 0, -1, 2 ], [ 1, 2, -5, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 3, -5, 0, -1, 2 ], [ -1, 3, -5, 0, -1, 2 ], [ 0, 3, -5, 0, -1, 2 ], [ 1, 2, -5, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 3, -5, 0, -1, 2 ], [ -1, 3, -5, 0, -1, 2 ], [ 0, 2, -5, 0, -1, 2 ], [ 1, 2, -5, 0, -1, 2 ] ], 0 ], + [ [ [ -1, 2, -5, 0, -1, 2 ], [ -1, 3, -5, 0, -1, 2 ], [ 0, 2, -5, 0, -1, 2 ], [ 1, 2, -5, 0, -1, 2 ] ], 0.25 ], + [ [ [ -1, 2, -5, 0, -1, 2 ], [ 0, 1, -5, 0, -1, 2 ], [ 0, 2, -5, 0, -1, 2 ], [ 1, 2, -5, 0, -1, 2 ] ], 0.25 ], + [ [ [ -1, 2, -5, 0, -1, 2 ], [ 0, 1, -5, 0, -1, 2 ], [ 0, 2, -6, 0, -1, 2 ], [ 1, 2, -5, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ 0, 1, -6, 0, -1, 2 ], [ 0, 1, -5, 0, -1, 2 ], [ 0, 2, -6, 0, -1, 2 ], [ 1, 2, -5, 0, -1, 2 ] ], 0 ], + [ [ [ 0, 1, -6, 0, -1, 2 ], [ 0, 1, -5, 0, -1, 2 ], [ 0, 2, -6, 0, -1, 2 ], [ 2, 1, -6, 0, -1, 2 ] ], 0.25 ], + [ [ [ 0, 1, -6, 0, -1, 2 ], [ 1, 1, -6, 0, -1, 2 ], [ 0, 2, -6, 0, -1, 2 ], [ 2, 1, -6, 0, -1, 2 ] ], 0.25 ], + [ [ [ 0, 1, -6, 0, -1, 2 ], [ 0, 3, -6, 0, -1, 2 ], [ 0, 2, -6, 0, -1, 2 ], [ 2, 1, -6, 0, -1, 2 ] ], 0 ], + [ [ [ -1, 3, -6, 0, -1, 2 ], [ 0, 3, -6, 0, -1, 2 ], [ 0, 2, -6, 0, -1, 2 ], [ 2, 1, -6, 0, -1, 2 ] ], 0.25 ], + [ [ [ -1, 3, -6, 0, -1, 2 ], [ 0, 3, -6, 0, -1, 2 ], [ 0, 2, -6, 0, -1, 2 ], [ 1, 2, -6, 0, -1, 2 ] ], 0.25 ], + [ [ [ -1, 2, -6, 0, -1, 2 ], [ 0, 3, -6, 0, -1, 2 ], [ 0, 2, -6, 0, -1, 2 ], [ 1, 2, -6, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -1, 2, -6, 0, -1, 2 ], [ 0, 3, -6, 0, -1, 2 ], [ -1, 4, -6, 0, -1, 2 ], [ 1, 2, -6, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 4, -6, 0, -1, 2 ], [ 0, 3, -6, 0, -1, 2 ], [ -1, 4, -6, 0, -1, 2 ], [ 1, 2, -6, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 4, -6, 0, -1, 2 ], [ 0, 3, -6, 0, -1, 2 ], [ -1, 4, -6, 0, -1, 2 ], [ 0, 4, -6, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 4, -6, 0, -1, 2 ], [ 0, 3, -6, 0, -1, 2 ], [ -1, 3, -6, 0, -1, 2 ], [ 0, 4, -6, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 4, -6, 0, -1, 2 ], [ -1, 4, -6, 0, -1, 2 ], [ -1, 3, -6, 0, -1, 2 ], [ 0, 4, -6, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 4, -6, 0, -1, 2 ], [ -1, 4, -6, 0, -1, 2 ], [ -2, 5, -6, 0, -1, 2 ], [ 0, 4, -6, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 4, -6, 0, -1, 2 ], [ -1, 4, -6, 0, -1, 2 ], [ -2, 5, -6, 0, -1, 2 ], [ -1, 5, -6, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -6, 0, -1, 2 ], [ -1, 4, -6, 0, -1, 2 ], [ -2, 5, -6, 0, -1, 2 ], [ -1, 5, -6, 0, -1, 2 ] ], 0 ], + [ [ [ -3, 6, -6, 0, -1, 2 ], [ -2, 6, -6, 0, -1, 2 ], [ -2, 5, -6, 0, -1, 2 ], [ -1, 5, -6, 0, -1, 2 ] ], 0 ], + [ [ [ -3, 6, -6, 0, -1, 2 ], [ -2, 6, -6, 0, -1, 2 ], [ -1, 4, -6, 0, -1, 2 ], [ -1, 5, -6, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 5, -6, 0, -1, 2 ], [ -2, 6, -6, 0, -1, 2 ], [ -1, 4, -6, 0, -1, 2 ], [ -1, 5, -6, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 5, -6, 0, -1, 2 ], [ -2, 6, -6, 0, -1, 2 ], [ -3, 6, -6, 0, -1, 2 ], [ -1, 5, -6, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 5, -6, 0, -1, 2 ], [ -2, 5, -6, 0, -1, 3 ], [ -3, 6, -6, 0, -1, 2 ], [ -1, 5, -6, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 5, -6, 0, -1, 2 ], [ -2, 5, -6, 0, -1, 3 ], [ -2, 5, -7, 0, -1, 2 ], [ -1, 5, -6, 0, -1, 2 ] ], 0 ], + [ [ [ -1, 5, -6, -1, -1, 2 ], [ -2, 5, -6, 0, -1, 3 ], [ -2, 5, -7, 0, -1, 2 ], [ -1, 5, -6, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 5, -5, 0, -1, 2 ], [ -2, 5, -6, 0, -1, 3 ], [ -2, 5, -7, 0, -1, 2 ], [ -1, 5, -6, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 5, -5, 0, -1, 2 ], [ -2, 5, -6, 0, -1, 3 ], [ -3, 5, -6, 1, -1, 2 ], [ -1, 5, -6, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 5, -5, 0, -1, 2 ], [ -2, 5, -6, 1, -1, 2 ], [ -3, 5, -6, 1, -1, 2 ], [ -1, 5, -6, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 5, -5, 0, -1, 2 ], [ -2, 5, -6, 1, -1, 2 ], [ -2, 5, -6, 0, -1, 2 ], [ -1, 5, -6, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 5, -5, 0, -1, 2 ], [ -2, 5, -6, 1, -1, 2 ], [ -2, 5, -6, 0, -1, 2 ], [ -2, 5, -5, 1, -1, 2 ] ], 0 ], + [ [ [ -2, 5, -5, 0, -1, 2 ], [ -2, 5, -6, 1, -1, 2 ], [ -3, 5, -5, 1, -1, 2 ], [ -2, 5, -5, 1, -1, 2 ] ], 0 ], + [ [ [ -3, 6, -6, 1, -1, 2 ], [ -2, 5, -6, 1, -1, 2 ], [ -3, 5, -5, 1, -1, 2 ], [ -2, 5, -5, 1, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -6, 1, -1, 2 ], [ -2, 5, -6, 1, -1, 2 ], [ -3, 5, -5, 1, -1, 2 ], [ -3, 7, -6, 1, -1, 2 ] ], 0 ], + [ [ [ -3, 6, -6, 1, -1, 2 ], [ -3, 6, -5, 1, -1, 2 ], [ -3, 5, -5, 1, -1, 2 ], [ -3, 7, -6, 1, -1, 2 ] ], 0 ], + [ [ [ -3, 6, -6, 1, -1, 2 ], [ -3, 6, -5, 1, -1, 2 ], [ -4, 7, -6, 1, -1, 2 ], [ -3, 7, -6, 1, -1, 2 ] ], 0.25 ], + [ [ [ -3, 6, -6, 1, -1, 2 ], [ -3, 6, -5, 1, -1, 2 ], [ -3, 6, -7, 1, -1, 2 ], [ -3, 7, -6, 1, -1, 2 ] ], 0 ], + [ [ [ -3, 6, -6, 1, -1, 2 ], [ -3, 5, -6, 1, -1, 2 ], [ -3, 6, -7, 1, -1, 2 ], [ -3, 7, -6, 1, -1, 2 ] ], 0 ], + [ [ [ -3, 6, -6, 1, -1, 2 ], [ -3, 5, -6, 1, -1, 2 ], [ -3, 6, -7, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0.25 ], + [ [ [ -3, 6, -6, 1, -1, 2 ], [ -3, 6, -6, 1, -2, 2 ], [ -3, 6, -7, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -6, 1, -1, 2 ], [ -4, 6, -7, 1, -1, 2 ], [ -3, 6, -7, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0.25 ], + [ [ [ -2, 5, -7, 1, -1, 2 ], [ -4, 6, -7, 1, -1, 2 ], [ -3, 6, -7, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0 ], + [ [ [ -2, 5, -7, 1, -1, 2 ], [ -4, 6, -7, 1, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 5, -7, 1, -1, 2 ], [ -4, 6, -7, 1, -1, 2 ], [ -3, 5, -7, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0 ], + [ [ [ -3, 6, -7, 1, -1, 2 ], [ -4, 6, -7, 1, -1, 2 ], [ -3, 5, -7, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0 ], + [ [ [ -3, 6, -7, 1, -1, 2 ], [ -2, 5, -7, 1, -1, 2 ], [ -3, 5, -7, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 5, -7, 1, -1, 3 ], [ -2, 5, -7, 1, -1, 2 ], [ -3, 5, -7, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0 ], + [ [ [ -3, 5, -7, 1, -1, 3 ], [ -2, 5, -7, 0, -1, 2 ], [ -3, 5, -7, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0 ], + [ [ [ -3, 5, -7, 1, -1, 3 ], [ -2, 5, -7, 0, -1, 2 ], [ -3, 5, -7, 1, -1, 2 ], [ -2, 5, -7, 1, -1, 3 ] ], 0.25 ], + [ [ [ -3, 5, -7, 1, -1, 3 ], [ -4, 5, -7, 1, -1, 3 ], [ -3, 5, -7, 1, -1, 2 ], [ -2, 5, -7, 1, -1, 3 ] ], 0 ], + [ [ [ -3, 5, -7, 2, -1, 2 ], [ -4, 5, -7, 1, -1, 3 ], [ -3, 5, -7, 1, -1, 2 ], [ -2, 5, -7, 1, -1, 3 ] ], 0.25 ], + [ [ [ -2, 5, -7, 1, -1, 2 ], [ -4, 5, -7, 1, -1, 3 ], [ -3, 5, -7, 1, -1, 2 ], [ -2, 5, -7, 1, -1, 3 ] ], 0.25 ] + ], + [ + [ [ [ -2, 5, -7, 1, -1, 2 ], [ -4, 5, -7, 1, -1, 3 ], [ -3, 5, -7, 1, -1, 3 ], [ -2, 5, -7, 1, -1, 3 ] ], 0.25 ], + [ [ [ -2, 5, -7, 1, -1, 2 ], [ -2, 4, -7, 1, -1, 2 ], [ -3, 5, -7, 1, -1, 3 ], [ -2, 5, -7, 1, -1, 3 ] ], 0.25 ], + [ [ [ -2, 5, -7, 1, -1, 2 ], [ -2, 4, -7, 1, -1, 2 ], [ -3, 5, -7, 1, -1, 3 ], [ -2, 6, -7, 1, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 5, -7, 1, -1, 2 ], [ -3, 6, -7, 1, -1, 2 ], [ -3, 5, -7, 1, -1, 3 ], [ -2, 6, -7, 1, -1, 2 ] ], 0.25 ], + [ [ [ -2, 5, -7, 1, -1, 2 ], [ -3, 6, -7, 1, -1, 2 ], [ -3, 7, -7, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0.25 ], + [ [ [ -3, 6, -6, 1, -1, 2 ], [ -3, 6, -7, 1, -1, 2 ], [ -3, 7, -7, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -6, 1, -1, 2 ], [ -3, 6, -7, 1, -1, 2 ], [ -2, 6, -6, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0.25 ], + [ [ [ -3, 5, -7, 1, -1, 2 ], [ -3, 6, -7, 1, -1, 2 ], [ -2, 6, -6, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0 ], + [ [ [ -3, 5, -7, 1, -1, 2 ], [ -2, 5, -7, 1, -1, 2 ], [ -2, 6, -6, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0.25 ], + [ [ [ -3, 6, -7, 1, -1, 2 ], [ -2, 5, -7, 1, -1, 2 ], [ -2, 6, -6, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0.25 ], + [ [ [ -2, 6, -7, 0, -1, 2 ], [ -2, 5, -7, 1, -1, 2 ], [ -2, 6, -6, 1, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0 ], + [ [ [ -2, 6, -7, 0, -1, 2 ], [ -2, 5, -7, 1, -1, 2 ], [ -1, 6, -7, 0, -1, 2 ], [ -2, 6, -7, 1, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 6, -7, 0, -1, 2 ], [ -2, 5, -7, 1, -1, 2 ], [ -1, 6, -7, 0, -1, 2 ], [ -1, 5, -7, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 6, -7, 0, -1, 2 ], [ -2, 5, -7, 0, -1, 2 ], [ -1, 6, -7, 0, -1, 2 ], [ -1, 5, -7, 0, -1, 2 ] ], 0 ], + [ [ [ -3, 6, -7, 0, -1, 2 ], [ -2, 5, -7, 0, -1, 2 ], [ -1, 6, -7, 0, -1, 2 ], [ -1, 5, -7, 0, -1, 2 ] ], 0.25 ], + [ [ [ -3, 6, -7, 0, -1, 2 ], [ -2, 5, -7, 0, -1, 2 ], [ -1, 6, -7, 0, -1, 2 ], [ -2, 7, -7, 0, -1, 2 ] ], 0.25 ], + [ [ [ -3, 6, -7, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ], [ -1, 6, -7, 0, -1, 2 ], [ -2, 7, -7, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -7, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ], [ -1, 6, -7, 0, -1, 2 ], [ -2, 7, -7, 0, -1, 2 ] ], 0.25 ], + [ [ [ -3, 7, -7, 0, -1, 2 ], [ -3, 8, -7, 0, -1, 2 ], [ -1, 6, -7, 0, -1, 2 ], [ -2, 7, -7, 0, -1, 2 ] ], 0 ], + [ [ [ -3, 7, -7, 0, -1, 2 ], [ -3, 8, -7, 0, -1, 2 ], [ -2, 8, -7, 0, -1, 2 ], [ -2, 7, -7, 0, -1, 2 ] ], 0.25 ], + [ [ [ -3, 7, -7, 0, -1, 2 ], [ -1, 6, -7, 0, -1, 2 ], [ -2, 8, -7, 0, -1, 2 ], [ -2, 7, -7, 0, -1, 2 ] ], 0.25 ], + [ [ [ -3, 7, -7, 0, -1, 2 ], [ -1, 6, -7, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ], [ -2, 7, -7, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -7, 0, -1, 2 ], [ -3, 6, -7, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ], [ -2, 7, -7, 0, -1, 2 ] ], 0.25 ], + [ [ [ -3, 7, -7, 0, -1, 2 ], [ -3, 6, -7, 0, -1, 2 ], [ -3, 8, -7, 0, -1, 2 ], [ -2, 7, -7, 0, -1, 2 ] ], 0 ], + [ [ [ -3, 7, -7, 0, -1, 2 ], [ -3, 6, -7, 0, -1, 2 ], [ -3, 8, -7, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ] ], 0 ], + [ [ [ -3, 7, -7, 0, -1, 2 ], [ -4, 8, -7, 0, -1, 2 ], [ -3, 8, -7, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ] ], 0.25 ], + [ [ [ -3, 7, -7, 0, -1, 2 ], [ -3, 7, -8, 0, -1, 2 ], [ -3, 8, -7, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -3, 7, -8, 0, -1, 2 ], [ -3, 8, -7, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -3, 7, -8, 0, -1, 2 ], [ -2, 6, -6, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -2, 5, -7, 0, -1, 2 ], [ -2, 6, -6, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -3, 7, -7, 0, -1, 2 ], [ -2, 6, -6, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -3, 6, -7, 0, -1, 2 ], [ -2, 6, -6, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -2, 6, -7, -1, -1, 2 ], [ -2, 6, -6, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -2, 6, -7, -1, -1, 2 ], [ -1, 5, -7, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -2, 5, -8, 0, -1, 2 ], [ -1, 5, -7, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -2, 5, -8, 0, -1, 2 ], [ -1, 5, -7, 0, -1, 2 ], [ -1, 5, -8, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -2, 5, -8, 0, -1, 2 ], [ 0, 5, -8, 0, -1, 2 ], [ -1, 5, -8, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -1, 6, -8, 0, -1, 2 ], [ 0, 5, -8, 0, -1, 2 ], [ -1, 5, -8, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -1, 6, -8, 0, -1, 2 ], [ -2, 7, -8, 0, -1, 2 ], [ -1, 5, -8, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -1, 6, -8, 0, -1, 2 ], [ -1, 6, -9, 0, -1, 2 ], [ -1, 5, -8, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -2, 7, -8, 0, -1, 2 ], [ -1, 6, -9, 0, -1, 2 ], [ -1, 5, -8, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -2, 7, -8, 0, -1, 2 ], [ -1, 6, -9, 0, -1, 2 ], [ -1, 6, -8, 0, -1, 2 ] ], 0 ], + [ [ [ -2, 6, -8, 0, -1, 2 ], [ -2, 7, -8, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ], [ -1, 6, -8, 0, -1, 2 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ -2, 6, -8, 0, -1, 2 ], [ -1, 6, -8, 0, -1, 2 ], [ -2, 7, -8, 0, -1, 2 ], [ -1, 5, -8, 0, -1, 2 ] ], + [ [ -2, 6, -8, 0, -1, 2 ], [ -1, 6, -8, 0, -1, 2 ], [ -1, 6, -9, 0, -1, 2 ], [ -1, 5, -8, 0, -1, 2 ] ], + [ [ -2, 6, -8, 0, -1, 2 ], [ -2, 7, -8, 0, -1, 2 ], [ -1, 6, -9, 0, -1, 2 ], [ -1, 5, -8, 0, -1, 2 ] ], + [ [ -2, 6, -8, 0, -1, 2 ], [ -2, 7, -8, 0, -1, 2 ], [ -1, 6, -9, 0, -1, 2 ], [ -1, 6, -8, 0, -1, 2 ] ], + [ [ -2, 6, -8, 0, -1, 2 ], [ -2, 7, -8, 0, -1, 2 ], [ -2, 6, -7, 0, -1, 2 ], [ -1, 6, -8, 0, -1, 2 ] ] +], +"cur_uid": "5f38e4bd", +"ref_uid": "nil", +"order_seed": 944308, +"dur_seed": 253607, +"motifs_seed": 530942, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0.0041152263374486, 0.0056818181818179, 0.080246913580247, 0.02840909090909, 0.20781893004115, 0.028409090909091, 0.41152263374486, 0, 0.44855967078189, 0.34659090909091, 0.47736625514403, 0, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58847736625514, 0.93181818181818, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 2, 3, 1, 2, 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 1, 3, 1, 1 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 0, 3 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1, 1, 3, 2, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1, 1, 2, 1, 2 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 0, 0, 0 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 0, 0, 2 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 0, 2 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 0, 3 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 2, 1 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 1, 2 ], [ ] ], + [ [ 3 ], [ 2, 0, 1 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 3, 3 ], [ ] ], + [ [ 3 ], [ 2, 0, 1 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 3 ], [ ] ], + [ [ 2 ], [ 0, 3, 1, 0 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 3, 2, 0, 0 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 2, 2, 2 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 3, 2, 3, 3 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 0, 2 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 1 ], [ ] ], + [ [ 2 ], [ 0, 3, 1, 3, 1, 0, 0 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 2, 0, 2 ], [ ] ], + [ [ 2 ], [ 1, 3, 0 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 2 ], [ ] ], + [ [ 2 ], [ 0, 3, 1, 1, 0, 3, 0 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 2 ], [ ] ], + [ [ 0 ], [ 1, 2, 3 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 0, 2 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 0, 2, 1, 2 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 2, 1, 3, 1 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 3 ], [ 2, 0, 1 ], [ ] ], + [ [ 2 ], [ 0, 1, 3, 1, 0, 0 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 0, 0, 2 ], [ ] ], + [ [ 2 ], [ 3, 1, 0, 3, 1 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 1, 2 ], [ ] ], + [ [ 0 ], [ 1, 2, 3, 1, 1 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 1, 1, 1, 2 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 1, 2, 2 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ] +], +"sus_weights": [ 0.69, 0, 0 ], +"order_size": [ 49.489795918367, 49.489795918367 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/5f38e4bd/lilypond/part_I.ly b/resources/string_quartet_3_rise/5f38e4bd/lilypond/part_I.ly new file mode 100644 index 0000000..aeeb44a --- /dev/null +++ b/resources/string_quartet_3_rise/5f38e4bd/lilypond/part_I.ly @@ -0,0 +1,34 @@ +{ + { d'8^\markup { \pad-markup #0.2 "+0"}[ g8^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] a8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ ais8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ ais8[ c'8^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }}] d'4^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { d'8[ ais8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ ais8[ c'8^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }}] ~ c'4 d'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ e'8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { e'4 f'4^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} a2^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } + \bar "|" + { b2^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} c'2^\markup { \pad-markup #0.2 "-26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} } + \bar "|" + { cis'4^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ cis'8[ fis'8^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] b8^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ a'8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] e'4^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { e'4 ~ e'8[ f'8^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] g'8^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}[ gis'8^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] ~ gis'8[ ais8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] } + \bar "|" + { c'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}[ ais'8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] ~ ais'8[ dis'8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] f'2^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} } + \bar "|" + { fis'2^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} b'4^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ais'8^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ e'8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] } + \bar "|" + { fis'4^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ fis'8[ g'8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ g'8[ c'8^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] g''4^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g''2 gis''2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} } + \bar "|" + { a''4^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ a''8[ e''8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ e''4 fis''4^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } + \bar "|" + { cis''2.^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} dis''8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}[ cis''8^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] } + \bar "|" + { d''2^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ d''8[ dis''8^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ dis''4 ~ } + \bar "|" + { dis''4 d''2.^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { d''4 a'8^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}[ b'8^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ b'2 ~ } + \bar "|" + { b'4 e'2.^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/5f38e4bd/lilypond/part_II.ly b/resources/string_quartet_3_rise/5f38e4bd/lilypond/part_II.ly new file mode 100644 index 0000000..ce4c626 --- /dev/null +++ b/resources/string_quartet_3_rise/5f38e4bd/lilypond/part_II.ly @@ -0,0 +1,34 @@ +{ + { d''8^\markup { \pad-markup #0.2 "+0"}[ a'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ a'4 ais'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { ais'2 c''4^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} d''8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}[ f'8^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ } + \bar "|" + { f'8[ a8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ a8[ e''8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] f''4^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} fis''8^\markup { \pad-markup #0.2 "+27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}[ e''8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { e''2 b'4^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} c''8^\markup { \pad-markup #0.2 "-26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ cis''8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}] ~ } + \bar "|" + { cis''4 e''8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ fis''8^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] b'4^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} a'8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ e''8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] } + \bar "|" + { b8^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ b'8^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] c''8^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}[ e'8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ e'4 f'4^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} ~ } + \bar "|" + { f'4 ~ f'8[ fis'8^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}] g'4^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ g'8[ ais'8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}] } + \bar "|" + { fis''8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ b'8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] dis'8^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}[ e'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] ~ e'8[ fis'8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] e''4^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { e''8[ fis''8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] b'8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ c''8^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ c''2 ~ } + \bar "|" + { c''8[ g'8^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] d''8^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ dis''8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}] ~ dis''8[ gis'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ gis'8[ e'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ } + \bar "|" + { e'2 ~ e'8[ fis'8^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] b8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ cis'8^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { cis'8[ fis'8^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}] gis8^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ a8^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] b8^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}[ cis'8^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] dis'8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ cis'8^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] } + \bar "|" + { d'4^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ d'8[ e'8^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }}] g2^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } + \bar "|" + { dis'2^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} a'4^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} fis''4^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { fis''8[ e''8^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ e''2 fis''4^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} } + \bar "|" + { e'4^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} fis'4^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} gis'2^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/5f38e4bd/lilypond/part_III.ly b/resources/string_quartet_3_rise/5f38e4bd/lilypond/part_III.ly new file mode 100644 index 0000000..4d6c344 --- /dev/null +++ b/resources/string_quartet_3_rise/5f38e4bd/lilypond/part_III.ly @@ -0,0 +1,34 @@ +{ + { d'8^\markup { \pad-markup #0.2 "+0"}[ g'8^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ g'4 d''8^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ dis''8^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] ais8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ dis8^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] } + \bar "|" + { d4^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} dis4^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} f8^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}[ a8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] fis'8^\markup { \pad-markup #0.2 "+27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}[ e''8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] } + \bar "|" + { d''4^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} c''4^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} f'8^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ e''8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ e''8[ fis'8^\markup { \pad-markup #0.2 "+27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] } + \bar "|" + { e'1^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { e'2. a8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ b8^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] } + \bar "|" + { b'8^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ e8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] c'2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} cis'8^\markup { \pad-markup #0.2 "+13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}[ gis8^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { gis8[ ais8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ ais2 ~ ais8[ b8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }}] ~ } + \bar "|" + { b2 ~ b8[ ais8^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ ais4 ~ } + \bar "|" + { ais4 b8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}[ ais8^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] d8^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ g8^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] c'4^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c'4 d'4^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} dis'4^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} cis'4^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { cis'8[ a'8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] b'2^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ b'8[ fis'8^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { fis'8[ gis'8^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ gis'8[ ais'8^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}] b'4^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ b'8[ ais'8^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] } + \bar "|" + { b8^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}[ c'8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] d4^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} g'8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ a8^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }}] dis4^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { dis8[ c'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ c'8[ d'8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ d'4 ~ d'8[ g'8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { g'4 a4^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} e'4^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} fis'8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ e''8^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { e''8[ e8^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] fis8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ gis8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ gis8[ a8^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}] b8^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}[ e8^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}]} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/5f38e4bd/lilypond/part_IV.ly b/resources/string_quartet_3_rise/5f38e4bd/lilypond/part_IV.ly new file mode 100644 index 0000000..d80cec5 --- /dev/null +++ b/resources/string_quartet_3_rise/5f38e4bd/lilypond/part_IV.ly @@ -0,0 +1,34 @@ +{ + { d'2^\markup { \pad-markup #0.2 "+0"} ~ d'8[ dis'8^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ dis'4 ~ } + \bar "|" + { dis'4 f'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}[ fis'8^\markup { \pad-markup #0.2 "+27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] a'2^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} ~ } + \bar "|" + { a'1 } + \bar "|" + { b'8^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ c''8^\markup { \pad-markup #0.2 "-26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] cis''8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}[ fis'8^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }}] g'8^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}[ a'8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] b4^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b8[ cis8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] e8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ fis8^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }}] b,8^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ e8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ e4 } + \bar "|" + { b,4^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} c4^\markup { \pad-markup #0.2 "-26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} f,4^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} c8^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ ais,8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { ais,8[ c8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] f,8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ dis8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ dis8[ f8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] dis'8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}[ b'8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { b'8[ fis8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ fis2. ~ } + \bar "|" + { fis8[ cis'8^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] d'4^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ d'8[ g'8^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] f'8^\markup { \pad-markup #0.2 "+40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }}[ g8^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] } + \bar "|" + { c4^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} d4^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} dis8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ gis8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ gis4 } + \bar "|" + { a4^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} b4^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} e4^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} fis4^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { fis8[ gis8^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] cis'8^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ e'8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}] f'4^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} fis'4^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { fis'4 ~ fis'8[ g'8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] d'8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ dis'8^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}] f'8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }}[ g'8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { g'2 ~ g'8[ fis'8^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}] ~ fis'8[ g8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] } + \bar "|" + { d'8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ e'8^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}] e4^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ e8[ b8^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ b4 ~ } + \bar "|" + { b2 cis'2^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/5f3f1c84/5f3f1c84_code.scd b/resources/string_quartet_3_rise/5f3f1c84/5f3f1c84_code.scd new file mode 100644 index 0000000..070e09d --- /dev/null +++ b/resources/string_quartet_3_rise/5f3f1c84/5f3f1c84_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/5f3f1c84/5f3f1c84_mus_model.json b/resources/string_quartet_3_rise/5f3f1c84/5f3f1c84_mus_model.json new file mode 100644 index 0000000..a6ca59d --- /dev/null +++ b/resources/string_quartet_3_rise/5f3f1c84/5f3f1c84_mus_model.json @@ -0,0 +1,105 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -7, 6, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ] ], 1 ], + [ [ [ -7, 6, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ] ], 1 ], + [ [ [ -8, 8, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 6, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -7, 7, 2, 2, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ] ], 1 ], + [ [ [ -8, 6, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -3, 2 ], [ -6, 6, 2, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 6, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -5, 6, 1, 2, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ] ], 1 ], + [ [ [ -8, 6, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -5, 6, 1, 2, -2, 2 ], [ -6, 6, 3, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 6, 2, 2, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -5, 6, 1, 2, -2, 2 ], [ -6, 6, 3, 2, -2, 2 ] ], 1 ], + [ [ [ -7, 6, 2, 2, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -5, 6, 1, 2, -2, 2 ], [ -6, 6, 3, 2, -2, 2 ] ], 1 ], + [ [ [ -7, 6, 2, 2, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -5, 6, 1, 2, -2, 2 ], [ -5, 6, 0, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 2, 2, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -6, 6, 2, 2, -2, 3 ], [ -5, 6, 0, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -6, 6, 0, 2, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -6, 6, 2, 2, -2, 3 ], [ -5, 6, 0, 2, -2, 2 ] ], 1 ], + [ [ [ -6, 6, 0, 2, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -6, 7, 0, 2, -2, 2 ], [ -5, 6, 0, 2, -2, 2 ] ], 1 ], + [ [ [ -6, 6, 0, 2, -2, 2 ], [ -4, 6, 0, 1, -2, 2 ], [ -6, 7, 0, 2, -2, 2 ], [ -5, 6, 0, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 6, 0, 1, -2, 2 ], [ -4, 6, 0, 1, -2, 2 ], [ -6, 7, 0, 2, -2, 2 ], [ -5, 6, 0, 2, -2, 2 ] ], 1 ], + [ [ [ -5, 6, 0, 1, -2, 2 ], [ -4, 6, 0, 1, -2, 2 ], [ -5, 6, 1, 2, -2, 2 ], [ -5, 6, 0, 2, -2, 2 ] ], 1 ], + [ [ [ -5, 6, 0, 1, -2, 2 ], [ -4, 6, 0, 2, -2, 1 ], [ -5, 6, 1, 2, -2, 2 ], [ -5, 6, 0, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 5, 1, 2, -2, 2 ], [ -4, 6, 0, 2, -2, 1 ], [ -5, 6, 1, 2, -2, 2 ], [ -5, 6, 0, 2, -2, 2 ] ], 1 ], + [ [ [ -5, 5, 1, 2, -2, 2 ], [ -6, 5, 1, 2, -2, 2 ], [ -5, 6, 1, 2, -2, 2 ], [ -5, 6, 0, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 5, 1, 2, -2, 2 ], [ -6, 5, 1, 2, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -5, 6, 0, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 5, 1, 2, -2, 2 ], [ -6, 6, 1, 2, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -5, 6, 0, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 5, 1, 2, -2, 2 ], [ -5, 5, 0, 2, -1, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -5, 6, 0, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 5, 1, 2, -2, 2 ], [ -5, 5, 0, 2, -1, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -5, 5, 0, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 6, 0, 2, -2, 2 ], [ -5, 5, 0, 2, -1, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -5, 5, 0, 3, -2, 2 ] ], 1 ], + [ [ [ -5, 6, 0, 2, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -5, 5, 0, 3, -2, 2 ] ], 1 ], + [ [ [ -5, 6, 0, 2, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -5, 4, 0, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -5, 6, 0, 2, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -6, 6, 0, 2, -2, 2 ] ], 8 ] + ] + ] +], +"last_changes": +[ + [ [ -5, 5, 1, 2, -2, 2 ], [ -5, 5, 0, 2, -1, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -5, 5, 0, 3, -2, 2 ] ], + [ [ -5, 6, 0, 2, -2, 2 ], [ -5, 5, 0, 2, -1, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -5, 5, 0, 3, -2, 2 ] ], + [ [ -5, 6, 0, 2, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -5, 5, 0, 3, -2, 2 ] ], + [ [ -5, 6, 0, 2, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -5, 4, 0, 2, -2, 2 ] ], + [ [ -5, 6, 0, 2, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -6, 6, 0, 2, -2, 2 ] ] +], +"cur_uid": "5f3f1c84", +"ref_uid": "47bdba0e", +"order_seed": 108266, +"dur_seed": 863525, +"motifs_seed": 142859, +"entrances_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0, 0, 0, 1, 1, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], +"step_probs_vals": [ 0, 1200, 0.0061728395061728, 0.10227272727273, 0.074074074074074, 0.10227272727273, 0.2037037037037, 0.090909090909091, 0.45679012345679, 0.011363636363636, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 0.23, 0.47, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 2 ], [ 1, 0, 3 ], [ ] ], + [ [ 3, 1, 0 ], [ 2 ], [ ] ], + [ [ 3 ], [ 0, 2, 1 ], [ ] ], + [ [ 3 ], [ 0, 2, 1 ], [ ] ], + [ [ 2, 3 ], [ 0, 1 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 3, 2, 0 ], [ 1 ], [ ] ], + [ [ 1, 2, 0 ], [ 3 ], [ ] ], + [ [ 2 ], [ 0, 1, 3 ], [ ] ], + [ [ 0, 2, 1 ], [ 3 ], [ ] ] +], +"sus_weights": [ 0.35, 0.37, 0.38 ], +"order_size": [ 5.0408163265306, 25.244897959184 ], +"passages_size": [ 0, 0 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_I.ly b/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_I.ly new file mode 100644 index 0000000..b372a5c --- /dev/null +++ b/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_I.ly @@ -0,0 +1,36 @@ +{ + { f'1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { a'2 a'2^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1 } + \bar "|" + { c''1^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + \bar "|" + { c''2 g2^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} } + \bar "|" + { a1^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_II.ly b/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_II.ly new file mode 100644 index 0000000..c1bef83 --- /dev/null +++ b/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_II.ly @@ -0,0 +1,36 @@ +{ + { ais2^\markup { \pad-markup #0.2 "-29"} c'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c'1 } + \bar "|" + { g'2^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} cis''2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 } + \bar "|" + { cis''1^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} } + \bar "|" + { e'1^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { e'2 cis''2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''2 d'2^\markup { \pad-markup #0.2 "+26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_III.ly b/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_III.ly new file mode 100644 index 0000000..258cee7 --- /dev/null +++ b/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_III.ly @@ -0,0 +1,36 @@ +{ + { c''1^\markup { \pad-markup #0.2 "+2"} ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''2 f'2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'2 c''2^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { c''1 } + \bar "|" + { cis''1^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }} } + \bar "|" + { fis1^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } + \bar "|" + { cis'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} gis'2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↑" }} ~ } + \bar "|" + { gis'1 } + \bar "|" + { f'1^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_IV.ly b/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_IV.ly new file mode 100644 index 0000000..192bd0c --- /dev/null +++ b/resources/string_quartet_3_rise/5f3f1c84/lilypond/part_IV.ly @@ -0,0 +1,36 @@ +{ + { f1^\markup { \pad-markup #0.2 "+0"} } + \bar "|" + { g2^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} f,2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { f,1 ~ } + \bar "|" + { f,1 } + \bar "|" + { f1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { f2 a2^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a1 } + \bar "|" + { c'1^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c'2 fis'2^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'2 a'2^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6109371f/6109371f_code.scd b/resources/string_quartet_3_rise/6109371f/6109371f_code.scd new file mode 100644 index 0000000..070e09d --- /dev/null +++ b/resources/string_quartet_3_rise/6109371f/6109371f_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/6109371f/6109371f_mus_model.json b/resources/string_quartet_3_rise/6109371f/6109371f_mus_model.json new file mode 100644 index 0000000..92df37e --- /dev/null +++ b/resources/string_quartet_3_rise/6109371f/6109371f_mus_model.json @@ -0,0 +1,440 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -8, 7, 1, 2, -1, 2 ], [ -7, 5, 1, 4, -2, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 1, 2, -1, 2 ], [ -6, 6, 0, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 1, 2, -1, 2 ], [ -6, 6, 0, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -5, 6, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 1, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -5, 6, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -7, 6, 0, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -5, 6, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -8, 6, 1, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -5, 6, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -8, 6, 1, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 7, 1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -8, 6, 1, 2, -1, 2 ], [ -7, 6, 1, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 7, 1, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 1, 2, -1, 2 ], [ -7, 6, 1, 2, -1, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 7, 1, 2, -1, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 2, -1, 2 ], [ -7, 6, 1, 2, -1, 2 ], [ -7, 8, 1, 2, -1, 2 ], [ -6, 7, 1, 2, -1, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 2, -1, 2 ], [ -8, 8, 1, 2, -1, 2 ], [ -7, 8, 1, 2, -1, 2 ], [ -6, 7, 1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 2, -1, 2 ], [ -6, 7, 1, 1, -1, 2 ], [ -7, 8, 1, 2, -1, 2 ], [ -6, 7, 1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ], [ -7, 8, 1, 2, -1, 2 ], [ -6, 7, 1, 2, -1, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ], [ -6, 7, 0, 2, -1, 2 ], [ -6, 7, 1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 2, -1, 2 ], [ -7, 8, 1, 2, -1, 2 ], [ -6, 7, 0, 2, -1, 2 ], [ -6, 7, 1, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 1, 2, -1, 2 ], [ -7, 8, 1, 2, -1, 2 ], [ -6, 7, 0, 2, -1, 2 ], [ -6, 7, 1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -8, 7, 1, 2, -1, 2 ], [ -7, 8, 1, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ], [ -6, 7, 1, 2, -1, 2 ] ], 0 ], + [ [ [ -8, 7, 1, 2, -1, 2 ], [ -7, 8, 1, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ], [ -7, 9, 1, 2, -1, 2 ] ], 0 ], + [ [ [ -9, 9, 1, 2, -1, 2 ], [ -7, 8, 1, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ], [ -7, 9, 1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 9, 1, 2, -1, 2 ], [ -7, 8, 1, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ], [ -7, 8, 1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -8, 8, 0, 2, -1, 2 ], [ -7, 8, 1, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ], [ -7, 8, 1, 2, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 8, 0, 2, -1, 2 ], [ -7, 8, 1, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ], [ -7, 8, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -8, 8, 0, 2, -1, 2 ], [ -7, 8, 1, 2, -1, 2 ], [ -8, 9, 0, 2, -1, 2 ], [ -7, 8, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -8, 8, 0, 2, -1, 2 ], [ -6, 7, 0, 2, -1, 2 ], [ -8, 9, 0, 2, -1, 2 ], [ -7, 8, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -8, 8, 0, 2, -1, 2 ], [ -7, 9, 0, 2, -1, 2 ], [ -8, 9, 0, 2, -1, 2 ], [ -7, 8, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -8, 8, 0, 2, -1, 2 ], [ -7, 9, 0, 2, -1, 2 ], [ -7, 8, -1, 2, -1, 2 ], [ -7, 8, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -8, 8, 0, 2, -1, 2 ], [ -7, 9, 0, 2, -1, 2 ], [ -6, 8, 0, 2, -1, 2 ], [ -7, 8, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -8, 8, 0, 2, -1, 2 ], [ -7, 9, 0, 2, -1, 2 ], [ -6, 8, -1, 2, -1, 2 ], [ -7, 8, 0, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -7, 9, 0, 2, -1, 2 ], [ -6, 8, -1, 2, -1, 2 ], [ -7, 8, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -7, 9, 0, 2, -1, 2 ], [ -7, 10, 0, 2, -1, 2 ], [ -7, 8, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -7, 9, 0, 2, -1, 2 ], [ -7, 10, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -7, 9, 0, 2, -1, 2 ], [ -8, 9, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -9, 9, 0, 2, -1, 2 ], [ -7, 9, 0, 2, -1, 2 ], [ -8, 9, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 9, 0, 2, -1, 2 ], [ -7, 9, 0, 2, -1, 2 ], [ -7, 9, 0, 1, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 9, 0, 2, -1, 2 ], [ -7, 9, 0, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -9, 9, 0, 2, -1, 2 ], [ -9, 11, 0, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -9, 11, 0, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -9, 11, 0, 2, -1, 2 ], [ -7, 10, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -9, 10, 0, 2, -1, 2 ], [ -7, 10, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -9, 10, 0, 2, -1, 2 ], [ -7, 10, 0, 2, -1, 2 ], [ -9, 12, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -9, 10, 0, 2, -1, 2 ], [ -8, 11, 1, 2, -1, 2 ], [ -9, 12, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -9, 10, 0, 2, -1, 2 ], [ -8, 11, 1, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -9, 10, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -9, 10, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -7, 10, -1, 2, -1, 2 ] ], 0 ], + [ [ [ -9, 10, -1, 2, -1, 2 ], [ -9, 10, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -7, 10, -1, 2, -1, 2 ] ], 0 ], + [ [ [ -9, 10, -1, 2, -1, 2 ], [ -8, 10, -1, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -7, 10, -1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -8, 10, -1, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -7, 10, -1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 10, -1, 2, -1, 2 ], [ -8, 10, -1, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -7, 10, -1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 10, 0, 3, -1, 2 ], [ -8, 10, -1, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -7, 10, -1, 2, -1, 2 ] ], 0 ], + [ [ [ -10, 10, 0, 3, -1, 2 ], [ -8, 10, 1, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -7, 10, -1, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 10, 0, 3, -1, 2 ], [ -8, 10, 1, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -8, 10, 0, 3, -1, 2 ] ], 0 ], + [ [ [ -10, 10, 0, 3, -1, 2 ], [ -7, 9, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -8, 10, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -10, 10, 0, 3, -1, 2 ], [ -9, 10, 0, 3, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -8, 10, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -10, 10, 0, 3, -1, 2 ], [ -9, 11, 0, 3, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -8, 10, 0, 3, -1, 2 ] ], 0.25 ], + [ [ [ -10, 10, 0, 3, -1, 2 ], [ -9, 11, 0, 3, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -7, 10, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 10, 0, 3, -1, 2 ], [ -9, 11, 0, 3, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -8, 10, 1, 3, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -9, 11, 0, 3, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -8, 10, 1, 3, -1, 2 ] ], 0 ], + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -9, 11, 0, 3, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -7, 10, 0, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -9, 11, 0, 3, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 11, 0, 2, -1, 2 ], [ -9, 11, 0, 3, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -9, 11, 0, 2, -1, 2 ], [ -8, 10, -1, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -8, 10, -1, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -8, 10, -1, 2, -1, 2 ], [ -9, 12, 0, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -8, 10, -1, 2, -1, 2 ], [ -9, 12, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ], [ -9, 12, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ], [ -8, 10, 1, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -7, 10, -1, 2, -1, 2 ], [ -8, 10, 1, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -7, 10, -1, 2, -1, 2 ], [ -7, 10, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -7, 10, -1, 2, -1, 2 ], [ -8, 11, -1, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ], [ -8, 11, -1, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -10, 11, 0, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ], [ -9, 11, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ], [ -9, 11, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -8, 10, 1, 2, -1, 2 ], [ -9, 11, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -7, 9, 0, 2, -1, 2 ], [ -9, 11, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -8, 11, 0, 2, -1, 2 ], [ -9, 11, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -7, 10, -1, 2, -1, 2 ], [ -9, 11, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -7, 10, -1, 2, -1, 2 ], [ -9, 11, 0, 2, -1, 2 ], [ -9, 12, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -8, 10, 0, 2, -1, 2 ], [ -9, 11, 0, 2, -1, 2 ], [ -9, 12, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -10, 12, 0, 2, -1, 2 ], [ -9, 11, 0, 2, -1, 2 ], [ -9, 12, 0, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 10, 0, 2, -1, 2 ], [ -10, 12, 0, 2, -1, 2 ], [ -10, 12, 1, 2, -1, 2 ], [ -9, 12, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -10, 13, 0, 2, -1, 2 ], [ -10, 12, 0, 2, -1, 2 ], [ -10, 12, 1, 2, -1, 2 ], [ -9, 12, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 12, 0, 2, -1, 3 ], [ -10, 12, 0, 2, -1, 2 ], [ -10, 12, 1, 2, -1, 2 ], [ -9, 12, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 12, 1, 2, -1, 2 ], [ -10, 12, 0, 2, -1, 2 ], [ -10, 12, 1, 2, -1, 2 ], [ -9, 12, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -8, 11, 0, 2, -1, 2 ], [ -10, 12, 0, 2, -1, 2 ], [ -10, 12, 1, 2, -1, 2 ], [ -9, 12, 0, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 11, 0, 2, -1, 2 ], [ -10, 12, 0, 2, -1, 2 ], [ -10, 12, 1, 2, -1, 2 ], [ -9, 11, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -8, 12, 0, 2, -1, 1 ], [ -10, 12, 0, 2, -1, 2 ], [ -10, 12, 1, 2, -1, 2 ], [ -9, 11, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -8, 12, 0, 2, -1, 1 ], [ -10, 12, 0, 2, -1, 2 ], [ -10, 12, 1, 2, -1, 2 ], [ -10, 13, 0, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 12, 0, 2, -1, 2 ], [ -10, 12, 0, 2, -1, 2 ], [ -10, 12, 1, 2, -1, 2 ], [ -10, 13, 0, 2, -1, 2 ] ], 0 ], + [ [ [ -9, 12, 0, 2, -1, 2 ], [ -10, 12, 0, 2, -1, 2 ], [ -10, 12, 1, 2, -1, 2 ], [ -9, 12, -1, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -11, 12, 0, 2, -1, 2 ], [ -10, 12, 0, 2, -1, 2 ], [ -10, 12, 1, 2, -1, 2 ], [ -9, 12, -1, 2, -1, 2 ] ], 0 ], + [ [ [ -11, 12, 0, 2, -1, 2 ], [ -9, 11, -1, 2, -1, 2 ], [ -10, 12, 1, 2, -1, 2 ], [ -9, 12, -1, 2, -1, 2 ] ], 0 ], + [ [ [ -11, 12, 0, 2, -1, 2 ], [ -9, 11, -1, 2, -1, 2 ], [ -8, 11, -1, 2, -1, 2 ], [ -9, 12, -1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 11, -1, 2, -1, 2 ], [ -9, 11, -1, 2, -1, 2 ], [ -8, 11, -1, 2, -1, 2 ], [ -9, 12, -1, 2, -1, 2 ] ], 0 ], + [ [ [ -10, 11, -1, 2, -1, 2 ], [ -10, 13, -1, 2, -1, 2 ], [ -8, 11, -1, 2, -1, 2 ], [ -9, 12, -1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 11, -1, 2, -1, 2 ], [ -10, 12, -1, 2, -1, 2 ], [ -8, 11, -1, 2, -1, 2 ], [ -9, 12, -1, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 11, -1, 2, -1, 2 ], [ -10, 12, -1, 2, -1, 2 ], [ -8, 11, -1, 2, -1, 2 ], [ -9, 11, -1, 2, -1, 2 ] ], 0 ], + [ [ [ -10, 11, -1, 2, -1, 2 ], [ -8, 10, -1, 2, -1, 2 ], [ -8, 11, -1, 2, -1, 2 ], [ -9, 11, -1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -9, 10, -1, 2, -1, 2 ], [ -8, 10, -1, 2, -1, 2 ], [ -8, 11, -1, 2, -1, 2 ], [ -9, 11, -1, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 12, -1, 2, -1, 2 ], [ -8, 10, -1, 2, -1, 2 ], [ -8, 11, -1, 2, -1, 2 ], [ -9, 11, -1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 12, -1, 2, -1, 2 ], [ -9, 12, -1, 2, -1, 2 ], [ -8, 11, -1, 2, -1, 2 ], [ -9, 11, -1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 12, -1, 2, -1, 2 ], [ -9, 12, -1, 2, -1, 2 ], [ -8, 12, -1, 2, -1, 2 ], [ -9, 11, -1, 2, -1, 2 ] ], 0 ], + [ [ [ -10, 12, -1, 2, -1, 2 ], [ -8, 11, -1, 2, -1, 2 ], [ -8, 12, -1, 2, -1, 2 ], [ -9, 11, -1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 12, -1, 2, -1, 2 ], [ -8, 11, -1, 2, -1, 2 ], [ -7, 10, -1, 2, -1, 2 ], [ -9, 11, -1, 2, -1, 2 ] ], 0.25 ], + [ [ [ -10, 12, -1, 2, -1, 2 ], [ -7, 11, -1, 1, -1, 2 ], [ -7, 10, -1, 2, -1, 2 ], [ -9, 11, -1, 2, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 12, -1, 2, -1, 2 ], [ -7, 11, -1, 1, -1, 2 ], [ -7, 10, -1, 2, -1, 2 ], [ -9, 10, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -10, 12, -1, 2, -1, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -7, 10, -1, 2, -1, 2 ], [ -9, 10, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -7, 10, -1, 2, -1, 2 ], [ -9, 10, -1, 2, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -8, 9, -1, 2, 0, 2 ], [ -7, 10, -1, 2, -1, 2 ], [ -9, 10, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -8, 9, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -8, 9, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -8, 10, -2, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -8, 10, -2, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -8, 9, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -8, 10, -2, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -8, 10, -2, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -7, 9, -1, 2, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -8, 10, -2, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.875 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -7, 10, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -8, 9, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -9, 10, 0, 2, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -10, 12, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -10, 12, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -9, 12, -1, 2, 0, 2 ], [ -10, 12, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 3 ], [ -10, 12, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -7, 9, -1, 2, 0, 2 ], [ -10, 12, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -7, 9, -1, 2, 0, 2 ], [ -9, 10, 0, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -7, 9, -1, 2, 0, 2 ], [ -8, 9, -1, 2, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ], [ -8, 9, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -10, 12, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -9, 11, -2, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -9, 11, -2, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -9, 11, -2, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 11, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -9, 11, -2, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -10, 11, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 11, -1, 1, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.875 ], + [ [ [ -11, 11, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -11, 11, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 3, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -8, 10, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 3, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -8, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -9, 11, -1, 3, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -8, 11, -1, 2, -1, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -9, 11, -1, 3, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -8, 11, -1, 2, -1, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -2, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -9, 11, -2, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -2, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 11, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -2, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -10, 11, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -9, 12, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 1, 0, 2 ], [ -9, 12, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -10, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 1, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 1, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -9, 11, -1, 1, 0, 2 ], [ -8, 11, -1, 1, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 11, -1, 1, 0, 2 ], [ -9, 11, 0, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -10, 11, 0, 2, 0, 2 ], [ -9, 11, 0, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 10, -1, 2, 0, 2 ], [ -9, 11, 0, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -9, 10, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -9, 10, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -7, 10, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 12, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -7, 10, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 12, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, 0, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 12, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -7, 11, -1, 1, 0, 2 ] ], 0 ], + [ [ [ -10, 11, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -7, 11, -1, 1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 11, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -9, 11, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -10, 11, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -9, 10, -1, 2, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0 ], + [ [ [ -10, 10, -1, 2, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -8, 10, -1, 1, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -9, 10, -1, 1, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -8, 10, -1, 1, 0, 2 ], [ -8, 11, -1, 2, 0, 2 ] ], 0.25 ], + [ [ [ -9, 10, -1, 1, 0, 2 ], [ -8, 10, -1, 2, 0, 2 ], [ -8, 10, -1, 1, 0, 2 ], [ -7, 10, -1, 1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 10, -1, 1, 0, 2 ], [ -7, 9, -1, 1, 0, 2 ], [ -8, 10, -1, 1, 0, 2 ], [ -7, 10, -1, 1, 0, 2 ] ], 0 ], + [ [ [ -8, 9, -1, 1, 0, 2 ], [ -7, 9, -1, 1, 0, 2 ], [ -8, 10, -1, 1, 0, 2 ], [ -7, 10, -1, 1, 0, 2 ] ], 0.25 ], + [ [ [ -8, 9, -1, 1, 0, 2 ], [ -7, 9, -1, 1, 0, 2 ], [ -8, 11, -1, 1, 0, 2 ], [ -7, 10, -1, 1, 0, 2 ] ], 0.25 ], + [ [ [ -8, 9, -1, 1, 0, 2 ], [ -7, 9, -1, 1, 0, 2 ], [ -6, 9, -1, 1, 0, 2 ], [ -7, 10, -1, 1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 9, -1, 1, 0, 2 ], [ -7, 9, -1, 1, 0, 2 ], [ -6, 9, -1, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ] ], 0 ], + [ [ [ -8, 9, -1, 1, 0, 2 ], [ -8, 10, -1, 1, 0, 2 ], [ -6, 9, -1, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -8, 9, -1, 1, 0, 2 ], [ -8, 10, -1, 1, 0, 2 ], [ -6, 9, -1, 1, 0, 2 ], [ -7, 9, -1, 1, 0, 2 ] ], 0 ], + [ [ [ -8, 9, -1, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ], [ -6, 9, -1, 1, 0, 2 ], [ -7, 9, -1, 1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 8, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ], [ -6, 9, -1, 1, 0, 2 ], [ -7, 9, -1, 1, 0, 2 ] ], 0 ], + [ [ [ -7, 8, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ], [ -5, 8, -2, 1, 0, 2 ], [ -7, 9, -1, 1, 0, 2 ] ], 0 ], + [ [ [ -7, 8, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ], [ -5, 8, -2, 1, 0, 2 ], [ -6, 8, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -7, 8, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ], [ -5, 8, -2, 1, 0, 2 ], [ -7, 10, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -8, 10, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ], [ -5, 8, -2, 1, 0, 2 ], [ -7, 10, -2, 1, 0, 2 ] ], 0 ], + [ [ [ -8, 10, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -7, 10, -2, 1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 10, -2, 1, 0, 2 ], [ -7, 8, -2, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -7, 10, -2, 1, 0, 2 ] ], 0 ], + [ [ [ -8, 10, -2, 1, 0, 2 ], [ -7, 8, -2, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -6, 9, -3, 1, 0, 2 ] ], 0 ], + [ [ [ -7, 9, -3, 1, 0, 2 ], [ -7, 8, -2, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -6, 9, -3, 1, 0, 2 ] ], 0.25 ], + [ [ [ -7, 9, -3, 1, 0, 2 ], [ -7, 8, -2, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -7, 9, -3, 1, 0, 2 ], [ -7, 8, -2, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -6, 8, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -7, 9, -3, 1, 0, 2 ], [ -7, 8, -2, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -7, 9, -1, 1, 0, 2 ] ], 0.25 ], + [ [ [ -7, 9, -2, 1, 0, 2 ], [ -7, 8, -2, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -7, 9, -1, 1, 0, 2 ] ], 0 ], + [ [ [ -7, 9, -2, 1, 0, 2 ], [ -8, 10, -2, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -7, 9, -1, 1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 9, -2, 0, 0, 2 ], [ -8, 10, -2, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -7, 9, -1, 1, 0, 2 ] ], 0 ], + [ [ [ -6, 9, -2, 0, 0, 2 ], [ -8, 10, -2, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -7, 10, -2, 1, 0, 2 ] ], 0 ], + [ [ [ -6, 9, -2, 0, 0, 2 ], [ -7, 9, -2, 0, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -7, 10, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -7, 9, -1, 1, 0, 2 ], [ -7, 9, -2, 0, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -7, 10, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -7, 9, -1, 1, 0, 2 ], [ -7, 9, -2, 0, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ] ], 0 ], + [ [ [ -7, 9, -1, 1, 0, 2 ], [ -8, 9, -1, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -7, 9, -2, 1, 1, 2 ], [ -8, 9, -1, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 10, -2, 1, 0, 2 ], [ -8, 9, -1, 1, 0, 2 ], [ -6, 9, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -7, 10, -2, 1, 0, 2 ], [ -8, 9, -1, 1, 0, 2 ], [ -7, 9, -1, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -7, 10, -2, 1, 0, 2 ], [ -8, 9, -1, 1, 0, 2 ], [ -6, 8, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -6, 8, -1, 1, 0, 2 ], [ -8, 9, -1, 1, 0, 2 ], [ -6, 8, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -7, 9, -2, 2, 0, 2 ], [ -8, 9, -1, 1, 0, 2 ], [ -6, 8, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -7, 9, -2, 2, 0, 2 ], [ -8, 9, -1, 1, 0, 2 ], [ -6, 9, -1, 0, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ] ], 0 ], + [ [ [ -7, 10, -1, 1, 0, 2 ], [ -8, 9, -1, 1, 0, 2 ], [ -6, 9, -1, 0, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 9, -2, 1, 0, 2 ], [ -8, 9, -1, 1, 0, 2 ], [ -6, 9, -1, 0, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -6, 9, -2, 1, 0, 2 ], [ -8, 9, -1, 1, 0, 2 ], [ -7, 10, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ] ], 0 ], + [ [ [ -6, 9, -2, 1, 0, 2 ], [ -7, 8, -2, 1, 0, 2 ], [ -7, 10, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -6, 9, -2, 1, 0, 2 ], [ -8, 10, -2, 1, 0, 2 ], [ -7, 10, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 9, -2, 1, 0, 2 ], [ -8, 10, -2, 1, 0, 2 ], [ -7, 10, -2, 1, 0, 2 ], [ -6, 10, -2, 1, 0, 2 ] ], 0.25 ], + [ [ [ -6, 9, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ], [ -7, 10, -2, 1, 0, 2 ], [ -6, 10, -2, 1, 0, 2 ] ], 0 ], + [ [ [ -6, 9, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ], [ -6, 9, -3, 1, 0, 2 ], [ -6, 10, -2, 1, 0, 2 ] ], 0 ], + [ [ [ -6, 9, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ], [ -6, 9, -3, 1, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0.25 ], + [ [ [ -6, 9, -2, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ], [ -7, 9, -2, 2, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0.25 ], + [ [ [ -6, 9, -2, 1, 0, 2 ], [ -6, 9, -2, 0, 0, 2 ], [ -7, 9, -2, 2, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0 ], + [ [ [ -6, 9, -2, 1, 0, 2 ], [ -6, 9, -2, 0, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0.25 ], + [ [ [ -6, 9, -2, 1, 0, 2 ], [ -6, 9, -2, 0, 0, 2 ], [ -7, 9, -3, 1, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 9, -3, 0, 0, 2 ], [ -6, 9, -2, 0, 0, 2 ], [ -7, 9, -3, 1, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0 ], + [ [ [ -5, 9, -3, 0, 0, 2 ], [ -6, 9, -2, 0, 0, 2 ], [ -6, 9, -3, 0, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0.25 ], + [ [ [ -5, 9, -3, 0, 0, 2 ], [ -6, 9, -2, 0, 0, 2 ], [ -5, 8, -2, 0, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0.25 ], + [ [ [ -5, 9, -3, 0, 0, 2 ], [ -6, 9, -2, 0, 0, 2 ], [ -6, 9, -1, 0, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0.25 ], + [ [ [ -5, 9, -3, 0, 0, 2 ], [ -6, 9, -2, 0, 0, 2 ], [ -6, 9, -3, 1, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0.25 ], + [ [ [ -5, 9, -3, 0, 0, 2 ], [ -6, 9, -2, 0, 0, 2 ], [ -6, 9, -3, 0, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0 ], + [ [ [ -6, 9, -2, 1, 0, 2 ], [ -6, 9, -2, 0, 0, 2 ], [ -6, 9, -3, 0, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 9, -3, 1, 1, 2 ], [ -6, 9, -2, 0, 0, 2 ], [ -6, 9, -3, 0, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0 ], + [ [ [ -6, 9, -3, 1, 1, 2 ], [ -6, 9, -2, 0, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0.25 ], + [ [ [ -6, 9, -3, 1, 1, 2 ], [ -6, 9, -4, 1, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0.25 ], + [ [ [ -6, 9, -3, 1, 1, 2 ], [ -7, 9, -3, 2, 0, 2 ], [ -7, 9, -2, 1, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 9, -3, 1, 1, 2 ], [ -7, 9, -3, 2, 0, 2 ], [ -7, 8, -3, 2, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0 ], + [ [ [ -7, 10, -3, 2, 0, 2 ], [ -7, 9, -3, 2, 0, 2 ], [ -7, 8, -3, 2, 0, 2 ], [ -5, 9, -3, 1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 10, -3, 2, 0, 2 ], [ -7, 9, -3, 2, 0, 2 ], [ -7, 8, -3, 2, 0, 2 ], [ -6, 10, -3, 1, 0, 2 ] ], 0.25 ], + [ [ [ -7, 10, -3, 2, 0, 2 ], [ -8, 11, -3, 2, 0, 2 ], [ -7, 8, -3, 2, 0, 2 ], [ -6, 10, -3, 1, 0, 2 ] ], 0 ], + [ [ [ -7, 10, -3, 2, 0, 2 ], [ -8, 11, -3, 2, 0, 2 ], [ -8, 10, -3, 2, 0, 2 ], [ -6, 10, -3, 1, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 10, -3, 2, 0, 2 ], [ -8, 11, -3, 2, 0, 2 ], [ -7, 10, -3, 1, 0, 2 ], [ -6, 10, -3, 1, 0, 2 ] ], 0 ], + [ [ [ -7, 10, -3, 2, 0, 2 ], [ -8, 11, -3, 2, 0, 2 ], [ -7, 10, -3, 1, 0, 2 ], [ -7, 10, -2, 2, 0, 2 ] ], 0 ], + [ [ [ -7, 10, -3, 2, 0, 2 ], [ -8, 10, -3, 2, 0, 2 ], [ -7, 10, -3, 1, 0, 2 ], [ -7, 10, -2, 2, 0, 2 ] ], 0.25 ], + [ [ [ -7, 10, -3, 2, 0, 2 ], [ -7, 10, -4, 2, 0, 2 ], [ -7, 10, -3, 1, 0, 2 ], [ -7, 10, -2, 2, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 10, -3, 2, 0, 2 ], [ -7, 10, -4, 2, 0, 2 ], [ -7, 10, -3, 1, 0, 2 ], [ -7, 10, -4, 3, 0, 2 ] ], 0 ], + [ [ [ -7, 10, -3, 2, 0, 2 ], [ -7, 10, -4, 2, 0, 2 ], [ -7, 10, -5, 2, 0, 2 ], [ -7, 10, -4, 3, 0, 2 ] ], 0 ], + [ [ [ -6, 9, -4, 2, 0, 2 ], [ -7, 10, -4, 2, 0, 2 ], [ -7, 10, -5, 2, 0, 2 ], [ -7, 10, -4, 3, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 10, -4, 3, 0, 2 ], [ -7, 10, -4, 2, 0, 2 ], [ -7, 10, -5, 2, 0, 2 ], [ -7, 10, -4, 3, 0, 2 ] ], 0 ], + [ [ [ -8, 10, -4, 3, 0, 2 ], [ -8, 10, -3, 3, 0, 2 ], [ -7, 10, -5, 2, 0, 2 ], [ -7, 10, -4, 3, 0, 2 ] ], 0.25 ], + [ [ [ -8, 10, -4, 3, 0, 2 ], [ -8, 10, -3, 3, 0, 2 ], [ -8, 9, -4, 3, 0, 2 ], [ -7, 10, -4, 3, 0, 2 ] ], 0 ], + [ [ [ -8, 10, -4, 3, 0, 2 ], [ -7, 9, -4, 3, 0, 2 ], [ -8, 9, -4, 3, 0, 2 ], [ -7, 10, -4, 3, 0, 2 ] ], 0.25 ], + [ [ [ -9, 9, -4, 3, 0, 2 ], [ -7, 9, -4, 3, 0, 2 ], [ -8, 9, -4, 3, 0, 2 ], [ -7, 10, -4, 3, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 10, -4, 3, 0, 2 ], [ -7, 9, -4, 3, 0, 2 ], [ -8, 9, -4, 3, 0, 2 ], [ -7, 10, -4, 3, 0, 2 ] ], 0 ], + [ [ [ -9, 10, -4, 3, 0, 2 ], [ -7, 9, -4, 3, 0, 2 ], [ -8, 9, -4, 3, 0, 2 ], [ -7, 9, -4, 3, 0, 3 ] ], 0.25 ], + [ [ [ -9, 10, -4, 3, 0, 2 ], [ -7, 9, -4, 3, 0, 2 ], [ -7, 8, -4, 3, 0, 2 ], [ -7, 9, -4, 3, 0, 3 ] ], 0 ], + [ [ [ -8, 9, -5, 3, 0, 2 ], [ -7, 9, -4, 3, 0, 2 ], [ -7, 8, -4, 3, 0, 2 ], [ -7, 9, -4, 3, 0, 3 ] ], 0.25 ] + ], + [ + [ [ [ -8, 9, -4, 3, 0, 2 ], [ -7, 9, -4, 3, 0, 2 ], [ -7, 8, -4, 3, 0, 2 ], [ -7, 9, -4, 3, 0, 3 ] ], 0 ], + [ [ [ -8, 9, -4, 3, 0, 2 ], [ -7, 8, -4, 3, 0, 3 ], [ -7, 8, -4, 3, 0, 2 ], [ -7, 9, -4, 3, 0, 3 ] ], 0 ], + [ [ [ -8, 9, -4, 3, 0, 2 ], [ -7, 8, -4, 3, 0, 3 ], [ -8, 9, -4, 3, 0, 3 ], [ -7, 9, -4, 3, 0, 3 ] ], 0.25 ], + [ [ [ -8, 9, -4, 3, 0, 2 ], [ -8, 10, -4, 3, 0, 3 ], [ -8, 9, -4, 3, 0, 3 ], [ -7, 9, -4, 3, 0, 3 ] ], 0.25 ], + [ [ [ -8, 9, -4, 3, 0, 2 ], [ -7, 9, -5, 3, 0, 3 ], [ -8, 9, -4, 3, 0, 3 ], [ -7, 9, -4, 3, 0, 3 ] ], 0.25 ], + [ [ [ -8, 9, -4, 3, 0, 2 ], [ -8, 9, -3, 3, 0, 3 ], [ -8, 9, -4, 3, 0, 3 ], [ -7, 9, -4, 3, 0, 3 ] ], 0 ], + [ [ [ -8, 9, -4, 3, 0, 2 ], [ -8, 9, -3, 3, 0, 3 ], [ -7, 9, -5, 3, 0, 3 ], [ -7, 9, -4, 3, 0, 3 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ -8, 9, -4, 3, 0, 2 ], [ -7, 8, -4, 3, 0, 3 ], [ -8, 9, -4, 3, 0, 3 ], [ -7, 9, -4, 3, 0, 3 ] ], + [ [ -8, 9, -4, 3, 0, 2 ], [ -8, 10, -4, 3, 0, 3 ], [ -8, 9, -4, 3, 0, 3 ], [ -7, 9, -4, 3, 0, 3 ] ], + [ [ -8, 9, -4, 3, 0, 2 ], [ -7, 9, -5, 3, 0, 3 ], [ -8, 9, -4, 3, 0, 3 ], [ -7, 9, -4, 3, 0, 3 ] ], + [ [ -8, 9, -4, 3, 0, 2 ], [ -8, 9, -3, 3, 0, 3 ], [ -8, 9, -4, 3, 0, 3 ], [ -7, 9, -4, 3, 0, 3 ] ], + [ [ -8, 9, -4, 3, 0, 2 ], [ -8, 9, -3, 3, 0, 3 ], [ -7, 9, -5, 3, 0, 3 ], [ -7, 9, -4, 3, 0, 3 ] ] +], +"cur_uid": "6109371f", +"ref_uid": "7276dc78", +"order_seed": 760163, +"dur_seed": 875928, +"motifs_seed": 478284, +"entrances_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"passages_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"exits_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0.0041152263374486, 0.0056818181818179, 0.080246913580247, 0.02840909090909, 0.20781893004115, 0.028409090909091, 0.41152263374486, 0, 0.44855967078189, 0.34659090909091, 0.47736625514403, 0, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58847736625514, 0.93181818181818, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 2 ], [ 0, 1, 3, 1, 0, 0, 3, 1 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 1, 1, 2, 1 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 0, 3, 0 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 1, 2, 2, 2 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 2, 0, 2 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 2 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 3, 2 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 0, 0, 0, 1 ], [ ] ], + [ [ 0, 2 ], [ 3, 1, 1, 1, 3, 3 ], [ ] ], + [ [ 1, 2 ], [ 0, 3 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 0 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 0, 3 ], [ 2, 1, 2, 2 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 1, 1, 1 ], [ ] ], + [ [ 0, 2 ], [ 1, 3, 1, 1 ], [ ] ], + [ [ 3, 1 ], [ 2, 0, 0, 0, 0 ], [ ] ], + [ [ 2, 1 ], [ 3, 0, 3, 0, 3 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 0, 1, 1 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 1, 2, 1 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 3, 0 ], [ 1, 2, 2, 1, 2 ], [ ] ], + [ [ 0, 2 ], [ 1, 3, 3, 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 3, 3, 3, 3, 3 ], [ ] ], + [ [ 0, 1 ], [ 3, 2, 2, 2, 2, 3, 3 ], [ ] ], + [ [ 1, 0 ], [ 2, 3, 3, 2, 2, 2, 3 ], [ ] ], + [ [ 3 ], [ 1, 0, 2, 0, 0 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 0, 2, 0 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 2, 2, 0 ], [ ] ], + [ [ 2, 3 ], [ 1, 0 ], [ ] ], + [ [ 2 ], [ 0, 1, 3, 0, 3, 3, 0 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 2, 0, 3 ], [ ] ], + [ [ 3 ], [ 1, 0, 2, 2 ], [ ] ], + [ [ 0, 2 ], [ 3, 1, 3, 1 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 3, 0, 2 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 3, 3, 3, 0, 1 ], [ ] ], + [ [ 2 ], [ 0, 3, 1, 0, 3, 1, 0 ], [ ] ], + [ [ 3, 1 ], [ 0, 2, 2, 0, 0, 2, 0 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 1 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 3, 2, 1, 2, 2 ], [ ] ], + [ [ 1, 3 ], [ 0, 2, 2, 2, 2, 2, 0 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 1 ], [ ] ], + [ [ 1, 3 ], [ 2, 0 ], [ ] ], + [ [ 0 ], [ 3, 1, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1, 1 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 1, 0 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 0 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 1, 1, 1, 2 ], [ ] ] +], +"sus_weights": [ 0.69, 0.3, 0 ], +"order_size": [ 49.489795918367, 49.489795918367 ], +"passages_size": [ 0, 6 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/615c4008/615c4008_code.scd b/resources/string_quartet_3_rise/615c4008/615c4008_code.scd new file mode 100644 index 0000000..070e09d --- /dev/null +++ b/resources/string_quartet_3_rise/615c4008/615c4008_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/615c4008/615c4008_mus_model.json b/resources/string_quartet_3_rise/615c4008/615c4008_mus_model.json new file mode 100644 index 0000000..65a90eb --- /dev/null +++ b/resources/string_quartet_3_rise/615c4008/615c4008_mus_model.json @@ -0,0 +1,267 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -8, 5, 2, 4, -2, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 6, 1, 4, -2, 2 ], [ -8, 5, 2, 4, -2, 2 ], [ -6, 6, 1, 2, -1, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 6, 1, 4, -2, 2 ], [ -8, 5, 2, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 6, 1, 4, -2, 2 ], [ -7, 4, 1, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 6, 1, 4, -2, 2 ], [ -8, 6, 1, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 6, 1, 4, -2, 2 ], [ -7, 5, 1, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 6, 1, 4, -2, 2 ], [ -8, 7, 1, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 6, 1, 4, -2, 2 ], [ -8, 7, 1, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -7, 7, 1, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 7, 1, 4, -2, 2 ], [ -8, 7, 1, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -7, 7, 1, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 1, 4, -2, 2 ], [ -7, 6, 0, 4, -2, 2 ], [ -7, 6, 1, 4, -2, 2 ], [ -7, 7, 1, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 1, 4, -2, 2 ], [ -7, 6, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 7, 1, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 7, 1, 4, -2, 2 ], [ -7, 6, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -6, 6, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -8, 6, 0, 4, -2, 2 ], [ -7, 6, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -6, 6, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 6, 0, 4, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -6, 6, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 4, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -6, 6, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 4, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -6, 7, 0, 3, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -6, 7, 0, 3, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 7, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -7, 7, 1, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 7, 0, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -7, 7, 1, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -7, 6, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 7, 1, 4, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -6, 6, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 8, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 8, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -2, 2 ], [ -7, 8, 0, 3, -2, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 7, 0, 3, -2, 3 ], [ -7, 7, 0, 3, -2, 2 ], [ -7, 8, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 7, 0, 3, -2, 3 ], [ -7, 7, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -2, 3 ] ], 0.25 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 7, 0, 3, -2, 3 ], [ -7, 7, 0, 3, -2, 2 ], [ -7, 7, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 7, 0, 3, -2, 3 ], [ -8, 7, 0, 3, -1, 3 ], [ -7, 7, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 3, -2, 2 ], [ -8, 7, 0, 3, -2, 3 ], [ -8, 7, 0, 3, -1, 3 ], [ -6, 7, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 7, 0, 3, -2, 3 ], [ -8, 7, 0, 3, -1, 3 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 7, 0, 3, -2, 3 ], [ -7, 7, 1, 3, -2, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -7, 7, 0, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -7, 7, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -1, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -7, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 7, 0, 3, -1, 3 ], [ -8, 8, 0, 3, -2, 2 ], [ -6, 7, 0, 3, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 7, 0, 3, -1, 3 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -1, 3 ] ], 0.25 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 8, 0, 3, -2, 3 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -1, 3 ] ], 0.25 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 8, 0, 3, -2, 3 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 3, -2, 3 ] ], 0.25 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 8, 0, 4, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 3, -2, 3 ] ], 0.25 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -7, 8, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 3, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 8, 1, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 3, -2, 3 ] ], 0 ], + [ [ [ -9, 7, 0, 3, -1, 3 ], [ -8, 8, 1, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -8, 8, -1, 3, -2, 2 ], [ -8, 8, 1, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -8, 8, -1, 3, -2, 2 ], [ -7, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 4, -2, 2 ], [ -7, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 0, 3, -2, 2 ], [ -7, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 4, -2, 1 ], [ -7, 7, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.625 ], + [ [ [ -9, 8, 0, 4, -2, 1 ], [ -9, 8, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -10, 8, 0, 4, -2, 2 ], [ -9, 8, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -10, 8, 0, 4, -2, 2 ], [ -9, 9, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -10, 8, 0, 4, -2, 2 ], [ -8, 8, -1, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -10, 8, 0, 4, -2, 2 ], [ -8, 8, -1, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 0, 3, -2, 2 ], [ -8, 8, -1, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 3, -2, 2 ], [ -8, 8, -1, 4, -2, 2 ], [ -9, 9, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 3, -2, 2 ], [ -9, 8, 0, 4, -2, 2 ], [ -9, 9, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 3, -2, 2 ], [ -8, 8, 0, 3, -2, 2 ], [ -9, 9, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 3, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -9, 9, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -9, 9, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 0, 4, -2, 2 ], [ -8, 8, 0, 4, -2, 2 ], [ -8, 8, -1, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 4, -2, 2 ], [ -7, 8, -1, 4, -2, 2 ], [ -8, 8, -1, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -9, 8, -1, 4, -2, 2 ], [ -7, 8, -1, 4, -2, 2 ], [ -8, 8, -1, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, -1, 4, -2, 2 ], [ -7, 8, -1, 4, -2, 2 ], [ -9, 9, -1, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -7, 8, 0, 4, -3, 2 ], [ -7, 8, -1, 4, -2, 2 ], [ -9, 9, -1, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -7, 8, 0, 4, -3, 2 ], [ -7, 8, -1, 4, -2, 2 ], [ -8, 7, 0, 4, -2, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -7, 8, 0, 4, -3, 2 ], [ -7, 8, -1, 4, -2, 2 ], [ -8, 8, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 8, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ], + [ [ [ -7, 8, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 8, -1, 4, -3, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 8, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 6, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -2, 2 ] ], 0 ], + [ [ [ -7, 8, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 6, 0, 4, -3, 2 ], [ -7, 6, 0, 4, -3, 2 ] ], 0.25 ], + [ [ [ -8, 6, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 6, 0, 4, -3, 2 ], [ -7, 6, 0, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 6, 0, 4, -3, 2 ], [ -7, 6, 0, 4, -3, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -7, 6, 0, 4, -3, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 7, -1, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 7, -1, 4, -3, 2 ], [ -7, 7, -1, 4, -3, 2 ] ], 0 ], + [ [ [ -8, 7, -1, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 7, -1, 4, -3, 2 ], [ -7, 7, -1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -8, 7, -1, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 7, -1, 4, -3, 2 ], [ -6, 7, 0, 3, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, -1, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 5, -3, 2 ], [ -6, 7, 0, 3, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 0, 5, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 5, -3, 2 ], [ -6, 7, 0, 3, -3, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 5, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 5, -3, 2 ], [ -6, 7, -1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 5, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 5, -3, 2 ], [ -8, 7, 0, 5, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 0, 5, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -6, 7, 0, 4, -3, 2 ], [ -8, 7, 0, 5, -3, 2 ] ], 0.25 ], + [ [ [ -9, 7, 0, 5, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 5, -3, 2 ] ], 0 ], + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 5, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 5, -3, 2 ] ], 0 ], + [ [ [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 5, -3, 2 ] ], 0 ], + [ [ [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 9, 0, 4, -3, 2 ], [ -7, 8, -1, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -7, 8, -1, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 8, 1, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -9, 8, 1, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -9, 8, 1, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 3, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 3, -3, 2 ], [ -8, 9, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 3, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -8, 7, 0, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 1, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -8, 6, 1, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -8, 6, 1, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -6, 6, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -8, 6, 1, 4, -3, 2 ], [ -7, 6, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -6, 6, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 6, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -6, 6, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -7, 7, 1, 4, -3, 2 ], [ -7, 6, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -6, 6, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -7, 7, 1, 4, -3, 2 ], [ -7, 6, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -7, 7, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -7, 7, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 7, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 8, 1, 3, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 8, 1, 3, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ], [ -8, 9, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 8, 1, 3, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 9, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -8, 8, 2, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 9, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 9, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ], [ -9, 9, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -8, 7, 2, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 7, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -7, 7, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 7, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0.25 ], + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -7, 8, 1, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -10, 8, 1, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -6, 7, 0, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 7, 0, 4, -3, 2 ], [ -8, 8, 1, 4, -3, 2 ], [ -6, 7, 0, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 0, 4, -3, 2 ], [ -8, 7, 0, 4, -3, 2 ], [ -6, 7, 0, 4, -3, 2 ], [ -8, 7, 1, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 7, 0, 4, -3, 2 ], [ -8, 7, 0, 4, -3, 2 ], [ -6, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 4, -3, 2 ], [ -6, 7, 0, 4, -3, 2 ], [ -7, 7, 0, 4, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 4, -3, 2 ], [ -6, 7, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ] ], 0 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -7, 9, 0, 4, -3, 2 ] ], 0.25 ], + [ [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ -9, 8, 0, 4, -3, 2 ], [ -8, 7, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ] ], + [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ] ], + [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -7, 8, 0, 4, -3, 2 ] ], + [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -7, 9, 0, 4, -3, 2 ] ], + [ [ -9, 8, 0, 4, -3, 2 ], [ -9, 9, 0, 4, -3, 2 ], [ -8, 9, 0, 4, -3, 2 ], [ -8, 8, 0, 4, -3, 2 ] ] +], +"cur_uid": "615c4008", +"ref_uid": "7276dc78", +"order_seed": 913894, +"dur_seed": 642726, +"motifs_seed": 376961, +"entrances_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"passages_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"exits_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1452.6315789474 ], [ -702, 1694.1176470588 ], [ -702, 1972.7554179567 ] ], +"step_probs_vals": [ -1200, 1200, 0.0041152263374486, 0.0056818181818179, 0.080246913580247, 0.02840909090909, 0.20781893004115, 0.028409090909091, 0.41152263374486, 0, 0.44650205761317, 0.16477272727273, 0.47736625514403, 0, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 0.58, 1, 0.43, 1, 0.82 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 3 ], [ 1, 0, 2, 1, 1, 1 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 1 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 0, 1, 3, 1 ], [ ] ], + [ [ 0, 2 ], [ 3, 1, 1, 3, 3, 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 1, 3, 3 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 3, 0 ], [ 2, 1, 2, 2, 1 ], [ ] ], + [ [ 2, 0 ], [ 3, 1, 3, 1, 1 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 1, 0, 0 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 0, 1, 1, 2 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 1, 1, 0 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 1, 3 ], [ 2, 0, 2, 2 ], [ ] ], + [ [ 0, 3 ], [ 1, 2 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 2, 3, 0, 3 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 3, 2, 2, 0 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 1, 0, 1, 1, 0 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 2, 1 ], [ ] ], + [ [ 1, 3 ], [ 0, 2, 0 ], [ ] ], + [ [ 2 ], [ 1, 3, 0 ], [ ] ], + [ [ 2 ], [ 0, 3, 1, 0, 0, 3, 1, 3 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 0, 1, 3 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 1, 1, 3, 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 2, 2, 0, 2 ], [ ] ], + [ [ 2 ], [ 0, 1, 3, 0 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 2, 3, 3 ], [ ] ] +], +"sus_weights": [ 0.69, 0.17, 0 ], +"order_size": [ 28.275510204082, 28.275510204082 ], +"passages_size": [ 0, 6 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/615c4008/lilypond/part_I.ly b/resources/string_quartet_3_rise/615c4008/lilypond/part_I.ly new file mode 100644 index 0000000..c5c36d9 --- /dev/null +++ b/resources/string_quartet_3_rise/615c4008/lilypond/part_I.ly @@ -0,0 +1,24 @@ +{ + { cis''2^\markup { \pad-markup #0.2 "+50"} e''4^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} f''4^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { f''4 g'8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ d'8^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] c''4^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} d''8^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ e''8^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }}] } + \bar "|" + { f''8^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}[ a'8^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ais'8^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ c''8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] d''2^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { d''8[ e''8^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ e''8[ f''8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ f''4 g''4^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + \bar "|" + { g''1 ~ } + \bar "|" + { g''1 ~ } + \bar "|" + { g''8.[ b16^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ b8.[ cis'16^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ cis'16[ d'8^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} gis'16^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }}] ~ gis'8.[ d''16^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] ~ } + \bar "|" + { d''16[ e'8.^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ e'16[ f'8.^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }}] ~ f'4 ~ f'8.[ ais'16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { ais'2. ~ ais'16[ f''8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} dis''16^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { dis''8.[ f''16^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ f''16[ e''8^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} f''16^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ f''16[ ais'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} c''16^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ c''4 ~ } + \bar "|" + { c''16[ f'8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ais16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ ais2 ~ ais16[ fis'8.^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}]} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/615c4008/lilypond/part_II.ly b/resources/string_quartet_3_rise/615c4008/lilypond/part_II.ly new file mode 100644 index 0000000..aa7dccc --- /dev/null +++ b/resources/string_quartet_3_rise/615c4008/lilypond/part_II.ly @@ -0,0 +1,24 @@ +{ + { g'8^\markup { \pad-markup #0.2 "-35"}[ a'8^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ a'2 c'4^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { c'1 ~ } + \bar "|" + { c'8[ d'8^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ d'4 e'8^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }}[ fis'8^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }}] g'8^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }}[ a8^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a8[ g'8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ g'2 ~ g'16[ c'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} d'16^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { d'4 ~ d'16[ dis'8.^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ dis'16[ ais8^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} c'16^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}] ~ c'16[ cis'8.^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { cis'16[ a'8^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} b'16^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] ~ b'8.[ cis''16^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ cis''16[ d''8.^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ d''16[ e''8.^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}] ~ } + \bar "|" + { e''16[ fis''8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} cis''16^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ cis''2. ~ } + \bar "|" + { cis''8.[ c''16^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ c''16[ f'8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ais16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ ais2 ~ } + \bar "|" + { ais2 ~ ais8.[ c'16^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ c'4 ~ } + \bar "|" + { c'4 ~ c'16[ d'8^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ais'16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ ais'16[ f''8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} fis''16^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}] ~ fis''4} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/615c4008/lilypond/part_III.ly b/resources/string_quartet_3_rise/615c4008/lilypond/part_III.ly new file mode 100644 index 0000000..91051dc --- /dev/null +++ b/resources/string_quartet_3_rise/615c4008/lilypond/part_III.ly @@ -0,0 +1,24 @@ +{ + { f8^\markup { \pad-markup #0.2 "+36"}[ fis8^\markup { \pad-markup #0.2 "+48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}] a8^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ cis'8^\markup { \pad-markup #0.2 "+50"}] e'8^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ f'8^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] ~ f'4 } + \bar "|" + { c''4^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} d''8^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ e''8^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }}] ~ e''8[ f'8^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] g'4^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + \bar "|" + { g'8[ a8^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ais4^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ ais8[ d'8^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ d'4 } + \bar "|" + { e'4^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} f'4^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }} g'8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }}[ a'8^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] cis'8^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }}[ d'8^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { d'4 ~ d'8.[ g16^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ g16[ d'8^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} dis'16^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ dis'8.[ g16^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { g16[ a8^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} g'16^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ g'8.[ dis''16^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ dis''4 ~ dis''8.[ fis'16^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'4 ~ fis'16[ gis'8^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} a'16^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] ~ a'16[ cis'8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} f16^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ f4 ~ } + \bar "|" + { f16[ g8.^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}] ~ g16[ c'8.^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ c'8.[ d'16^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }}] ~ d'8.[ dis'16^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { dis'8.[ f'16^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ f'8.[ ais'16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ ais'16[ f'8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} g'16^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}] ~ g'16[ a'8^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ais'16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { ais'4 ~ ais'16[ f'8.^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ f'4 ~ f'16[ fis8.^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}]} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/615c4008/lilypond/part_IV.ly b/resources/string_quartet_3_rise/615c4008/lilypond/part_IV.ly new file mode 100644 index 0000000..a8ec19c --- /dev/null +++ b/resources/string_quartet_3_rise/615c4008/lilypond/part_IV.ly @@ -0,0 +1,24 @@ +{ + { g,8^\markup { \pad-markup #0.2 "+1"}[ a,8^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}] ~ a,4 e4^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ e8[ f8^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { f8[ c8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] d2.^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + \bar "|" + { d2 e2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { e2. f8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}[ g8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] } + \bar "|" + { a,8^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ ais,8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }}] ~ ais,8.[ g,16^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ g,4 ~ g,8.[ a,16^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}] ~ } + \bar "|" + { a,8.[ g16^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ g8.[ dis16^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ dis16[ cis''8.^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }}] ~ cis''4 ~ } + \bar "|" + { cis''4 ~ cis''16[ b,8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} fis16^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ fis16[ d8.^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ d16[ e8.^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { e8.[ fis16^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ fis16[ gis8.^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ gis16[ cis8.^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ cis16[ f,8.^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { f,4 ~ f,8.[ f16^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ f16[ fis8.^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] ~ fis16[ ais,8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} dis16^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { dis16[ f8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ais'16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ ais'8.[ ais,16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ ais,16[ f8.^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ f4 ~ } + \bar "|" + { f4 ~ f16[ ais,8.^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ ais,8.[ f,16^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ f,16[ fis,8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} cis16^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}]} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/624f7439/624f7439_code.scd b/resources/string_quartet_3_rise/624f7439/624f7439_code.scd new file mode 100644 index 0000000..e1a9d92 --- /dev/null +++ b/resources/string_quartet_3_rise/624f7439/624f7439_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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"], {(62.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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/624f7439/624f7439_mus_model.json b/resources/string_quartet_3_rise/624f7439/624f7439_mus_model.json new file mode 100644 index 0000000..1692c9e --- /dev/null +++ b/resources/string_quartet_3_rise/624f7439/624f7439_mus_model.json @@ -0,0 +1,141 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -6, 6, -1, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 3 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -3, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -3, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ], [ -3, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 6, -1, 0, -2, 2 ], [ -3, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -3, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -3, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -5, 7, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -4, 6, -1, 1, -3, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 7, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 6, -1, 1, -1, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 7, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 7, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -4, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 7, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -5, 7, -1, 1, -2, 2 ], [ -4, 7, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -5, 7, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 2, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 6, -1, 1, -1, 2 ], [ -5, 6, -1, 2, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 7, -1, 1, -2, 2 ], [ -5, 6, -1, 2, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 7, -1, 1, -2, 2 ], [ -5, 7, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 7, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -4, 5, -2, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 5, -2, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 5, -2, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -4, 5, -1, 2, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -4, 5, -1, 2, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -3, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 2, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -3, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 5, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 5, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -3, 5, -1, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 5, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 6, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 6, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 5, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 4, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, 0, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 6, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ -4, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], + [ [ -5, 6, 0, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], + [ [ -4, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], + [ [ -4, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], + [ [ -4, 6, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ] +], +"cur_uid": "624f7439", +"ref_uid": "4f53a446", +"order_seed": 192987, +"dur_seed": 454936, +"motifs_seed": 709798, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 1.02, 0.0098039215686275, 0, 0.20915032679739, 0, 0.24183006535948, 0.82432432432432, 0.28758169934641, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 1.02, 0.0098039215686275, 0, 0.20915032679739, 0, 0.24183006535948, 0.82432432432432, 0.28758169934641, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 1.02, 0.0098039215686275, 0, 0.20915032679739, 0, 0.24183006535948, 0.82432432432432, 0.28758169934641, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 0, 2, 3 ], [ 1, 1, 1, 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 2, 2, 2 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 0, 1, 1, 1 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 2, 2, 1, 2 ], [ ] ], + [ [ 0, 3 ], [ 1, 2, 1 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 3, 2 ], [ 0, 1, 1, 0 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 2, 3, 2, 1 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 0, 2 ], [ 1, 3, 3, 1, 1 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 2, 0, 3 ], [ ] ], + [ [ 1, 3 ], [ 0, 2, 0, 0, 0, 0 ], [ ] ], + [ [ 3, 1 ], [ 2, 0 ], [ ] ] +], +"sus_weights": [ 0.7, 0.48, 0.49 ], +"order_size": [ 14, 14.132653061224 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/62918688/62918688_code.scd b/resources/string_quartet_3_rise/62918688/62918688_code.scd new file mode 100644 index 0000000..e1a9d92 --- /dev/null +++ b/resources/string_quartet_3_rise/62918688/62918688_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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"], {(62.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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/62918688/62918688_mus_model.json b/resources/string_quartet_3_rise/62918688/62918688_mus_model.json new file mode 100644 index 0000000..13329cd --- /dev/null +++ b/resources/string_quartet_3_rise/62918688/62918688_mus_model.json @@ -0,0 +1,60 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -5, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -3, 2 ] ], 0.875 ], + [ [ [ -5, 5, -1, 1, -3, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -3, 2 ] ], 0.875 ] + ], + [ + [ [ [ -5, 5, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -3, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ], [ -4, 6, -1, 1, -3, 2 ], [ -4, 5, -1, 1, -3, 2 ] ], 0 ], + [ [ [ -5, 6, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ], [ -4, 6, -1, 1, -3, 2 ], [ -4, 5, -1, 1, -3, 2 ] ], 1 ], + [ [ [ -5, 6, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ], [ -3, 5, -2, 1, -3, 2 ], [ -4, 5, -1, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 5, -2, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ], [ -3, 5, -2, 1, -3, 2 ], [ -4, 5, -1, 1, -3, 2 ] ], 0.875 ] + ], + [ + [ [ [ -3, 4, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ], [ -3, 5, -2, 1, -3, 2 ], [ -4, 5, -1, 1, -3, 2 ] ], 0.75 ], + [ [ [ -4, 6, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ], [ -3, 5, -2, 1, -3, 2 ], [ -4, 5, -1, 1, -3, 2 ] ], 1 ] + ], + [ + [ [ [ -4, 6, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ], [ -3, 5, -2, 1, -3, 2 ], [ -3, 4, -2, 1, -3, 2 ] ], 1 ], + [ [ [ -4, 6, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ], [ -3, 5, -2, 1, -3, 2 ], [ -4, 6, -2, 1, -3, 2 ] ], 0.75 ] + ] + ] +], +"last_changes": +[ + [ [ -4, 5, -2, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ], [ -3, 5, -2, 1, -3, 2 ], [ -4, 5, -1, 1, -3, 2 ] ], + [ [ -3, 4, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ], [ -3, 5, -2, 1, -3, 2 ], [ -4, 5, -1, 1, -3, 2 ] ], + [ [ -4, 6, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ], [ -3, 5, -2, 1, -3, 2 ], [ -4, 5, -1, 1, -3, 2 ] ], + [ [ -4, 6, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ], [ -3, 5, -2, 1, -3, 2 ], [ -3, 4, -2, 1, -3, 2 ] ], + [ [ -4, 6, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ], [ -3, 5, -2, 1, -3, 2 ], [ -4, 6, -2, 1, -3, 2 ] ] +], +"cur_uid": "62918688", +"ref_uid": "4f53a446", +"order_seed": 328536, +"dur_seed": 766600, +"motifs_seed": 515433, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 3, 0.0098039215686275, 0, 0.20915032679739, 0, 0.3202614379085, 0.78716216216216, 0.47712418300654, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 3, 0.0098039215686275, 0, 0.20915032679739, 0, 0.3202614379085, 0.78716216216216, 0.47712418300654, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 3, 0.0098039215686275, 0, 0.20915032679739, 0, 0.3202614379085, 0.78716216216216, 0.47712418300654, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 2, 1 ], [ 0, 3, 0 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 2, 0 ], [ ] ], + [ [ 2, 3, 1 ], [ 0, 0 ], [ ] ], + [ [ 1, 2, 0 ], [ 3, 3 ], [ ] ] +], +"sus_weights": [ 0.7, 0.48, 0.49 ], +"order_size": [ 4.030612244898, 4.030612244898 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6522664c/lilypond/part_I.ly b/resources/string_quartet_3_rise/6522664c/lilypond/part_I.ly index aa8c464..fa9b301 100644 --- a/resources/string_quartet_3_rise/6522664c/lilypond/part_I.ly +++ b/resources/string_quartet_3_rise/6522664c/lilypond/part_I.ly @@ -1,20 +1,20 @@ { - { g'1^\markup { \pad-markup #0.2 "-21"} ~ } + { a'1^\markup { \pad-markup #0.2 "-21"} ~ } \bar "|" - { g'1 } + { a'1 } \bar "|" - { fis1^\markup { \pad-markup #0.2 "+26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} } + { gis1^\markup { \pad-markup #0.2 "+26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} } \bar "|" - { c'1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + { d'1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } \bar "|" - { e'1^\markup { \pad-markup #0.2 "-36"} ~ } + { fis'1^\markup { \pad-markup #0.2 "-36"} ~ } \bar "|" - { e'1 ~ } + { fis'1 ~ } \bar "|" - { e'2 fis'2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { fis'2 gis'2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { fis'1 } + { gis'1 } \bar "|" - { g'1^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}} + { a'1^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6522664c/lilypond/part_II.ly b/resources/string_quartet_3_rise/6522664c/lilypond/part_II.ly index 9007135..d66bec2 100644 --- a/resources/string_quartet_3_rise/6522664c/lilypond/part_II.ly +++ b/resources/string_quartet_3_rise/6522664c/lilypond/part_II.ly @@ -1,20 +1,20 @@ { - { c''1^\markup { \pad-markup #0.2 "-23"} ~ } + { d''1^\markup { \pad-markup #0.2 "-23"} ~ } \bar "|" - { c''1 ~ } + { d''1 ~ } \bar "|" - { c''1 ~ } + { d''1 ~ } \bar "|" - { c''1 ~ } + { d''1 ~ } \bar "|" - { c''1 ~ } + { d''1 ~ } \bar "|" - { c''2 b2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } + { d''2 cis'2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b1} + { cis'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6522664c/lilypond/part_III.ly b/resources/string_quartet_3_rise/6522664c/lilypond/part_III.ly index 77f3a11..16895eb 100644 --- a/resources/string_quartet_3_rise/6522664c/lilypond/part_III.ly +++ b/resources/string_quartet_3_rise/6522664c/lilypond/part_III.ly @@ -1,20 +1,20 @@ { - { g2^\markup { \pad-markup #0.2 "-21"} e'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } + { a2^\markup { \pad-markup #0.2 "-21"} fis'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } \bar "|" - { a'1^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + { b'1^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } \bar "|" - { a'1 ~ } + { b'1 ~ } \bar "|" - { a'2 b'2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + { b'2 cis''2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } \bar "|" - { b'2 g'2^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} ~ } + { cis''2 a'2^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} ~ } \bar "|" - { g'1 ~ } + { a'1 ~ } \bar "|" - { g'1 } + { a'1 } \bar "|" - { d2^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} fis2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { e2^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} gis2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } \bar "|" - { fis1} + { gis1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6522664c/lilypond/part_IV.ly b/resources/string_quartet_3_rise/6522664c/lilypond/part_IV.ly index 49e5ac8..e79423d 100644 --- a/resources/string_quartet_3_rise/6522664c/lilypond/part_IV.ly +++ b/resources/string_quartet_3_rise/6522664c/lilypond/part_IV.ly @@ -1,20 +1,20 @@ { - { b1^\markup { \pad-markup #0.2 "-34"} ~ } + { cis'1^\markup { \pad-markup #0.2 "-34"} ~ } \bar "|" - { b2 c'2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + { cis'2 d'2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } \bar "|" - { c'2 g'2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + { d'2 a'2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } \bar "|" - { g'1 ~ } + { a'1 ~ } \bar "|" - { g'1 } + { a'1 } \bar "|" - { a'1^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} } + { b'1^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} } \bar "|" - { b'1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + { cis''1^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } \bar "|" - { b'1 ~ } + { cis''1 ~ } \bar "|" - { b'2 g2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}} + { cis''2 a2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6686d651/6686d651_code.scd b/resources/string_quartet_3_rise/6686d651/6686d651_code.scd new file mode 100644 index 0000000..e1a9d92 --- /dev/null +++ b/resources/string_quartet_3_rise/6686d651/6686d651_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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"], {(62.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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/6686d651/6686d651_mus_model.json b/resources/string_quartet_3_rise/6686d651/6686d651_mus_model.json new file mode 100644 index 0000000..148e511 --- /dev/null +++ b/resources/string_quartet_3_rise/6686d651/6686d651_mus_model.json @@ -0,0 +1,379 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -4, 5, 1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -6, 6, 0, 2, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, 1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 2, -2, 2 ], [ -5, 5, 1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, 1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 5, 1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 5, 0, 1, -1, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 5, 1, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 5, 0, 1, -1, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 5, 0, 1, -1, 2 ] ], 0 ], + [ [ [ -4, 5, 0, 1, -1, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 5, 0, 1, -1, 2 ] ], 0.25 ], + [ [ [ -4, 5, 0, 1, -1, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 1, -2, 3 ], [ -5, 5, 0, 1, -1, 2 ] ], 0 ], + [ [ [ -4, 5, 0, 1, -1, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 1, -2, 3 ], [ -5, 6, 0, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 5, 0, 1, -1, 2 ], [ -4, 4, 0, 1, -2, 3 ], [ -5, 5, 0, 1, -2, 3 ], [ -5, 6, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, 0, 1, -1, 2 ], [ -5, 5, 0, 1, -1, 2 ], [ -5, 5, 0, 1, -2, 3 ], [ -5, 6, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, 0, 1, -1, 2 ], [ -6, 6, 0, 2, -2, 2 ], [ -5, 5, 0, 1, -2, 3 ], [ -5, 6, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, 0, 1, -1, 2 ], [ -5, 4, 0, 1, -1, 2 ], [ -5, 5, 0, 1, -2, 3 ], [ -5, 6, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, 0, 1, -1, 2 ], [ -5, 5, 0, 1, -2, 2 ], [ -5, 5, 0, 1, -2, 3 ], [ -5, 6, 0, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 5, 0, 1, -1, 2 ], [ -6, 6, 1, 1, -2, 2 ], [ -5, 5, 0, 1, -2, 3 ], [ -5, 6, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 5, 0, 1, -1, 2 ], [ -6, 6, 1, 1, -2, 2 ], [ -4, 6, 0, 1, -2, 1 ], [ -5, 6, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, 0, 1, -1, 2 ], [ -6, 6, 1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, 0, 1, -1, 2 ], [ -6, 6, 1, 1, -2, 2 ], [ -5, 6, 1, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 6, 0, 1, -2, 2 ], [ -6, 6, 1, 1, -2, 2 ], [ -5, 6, 1, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 6, 0, 1, -2, 2 ], [ -6, 6, 1, 1, -2, 2 ], [ -5, 6, 1, 1, -2, 2 ], [ -6, 7, 1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 6, 0, 1, -2, 2 ], [ -6, 6, 1, 1, -2, 2 ], [ -4, 6, 1, 0, -2, 2 ], [ -6, 7, 1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 6, 0, 1, -2, 2 ], [ -6, 6, 1, 1, -2, 2 ], [ -4, 6, 1, 0, -2, 2 ], [ -6, 6, 1, 1, -1, 2 ] ], 0.25 ], + [ [ [ -4, 6, 0, 1, -2, 2 ], [ -6, 6, 1, 1, -2, 2 ], [ -4, 6, 1, 0, -2, 2 ], [ -5, 5, 1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 6, 0, 1, -2, 2 ], [ -6, 6, 1, 1, -2, 2 ], [ -4, 6, 1, 0, -2, 2 ], [ -4, 5, 1, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 6, 0, 1, -2, 2 ], [ -6, 6, 1, 1, -2, 2 ], [ -4, 6, 1, 0, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 6, 0, 1, -2, 2 ], [ -6, 6, 1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 6, 0, 1, -2, 2 ], [ -5, 5, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 6, 0, 1, -2, 2 ], [ -6, 7, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -6, 7, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 5, 0, 1, -2, 2 ], [ -6, 7, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 5, 0, 1, -2, 2 ], [ -5, 5, 1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 5, 0, 1, -2, 2 ], [ -5, 5, 1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -3, 5, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 5, 0, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -3, 5, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 5, 0, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 5, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 5, 0, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 5, 0, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 5, 0, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 6, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 5, 0, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 5, 0, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 5, 1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -7, 5, 1, 1, -2, 3 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 5, 1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -7, 5, 1, 1, -2, 3 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 5, 1, 1, -2, 2 ], [ -5, 5, 1, 2, -2, 2 ] ], 0.25 ], + [ [ [ -7, 5, 1, 2, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 5, 1, 1, -2, 2 ], [ -5, 5, 1, 2, -2, 2 ] ], 0 ], + [ [ [ -7, 5, 1, 2, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 5, 1, 1, -2, 2 ], [ -4, 4, 0, 2, -2, 2 ] ], 0.25 ], + [ [ [ -6, 5, 1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 5, 1, 1, -2, 2 ], [ -4, 4, 0, 2, -2, 2 ] ], 0 ], + [ [ [ -6, 5, 1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 5, 1, 1, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 4, 0, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 5, 1, 1, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 4, 1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 5, 1, 1, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 3, 0, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 5, 1, 1, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, 0, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 5, 1, 1, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, 0, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 5, 1, 1, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 4, 1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 5, 1, 1, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 4, 1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -3, 3, 0, 1, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 4, 1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 4, 1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -3, 3, 1, 1, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 4, 1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 4, 0, 2, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -3, 3, 0, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 4, 0, 2, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -3, 3, 0, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 4, 0, 2, -2, 2 ], [ -3, 4, 0, 2, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 4, 0, 1, -2, 1 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 4, 0, 2, -2, 2 ], [ -3, 4, 0, 2, -2, 2 ] ], 0 ], + [ [ [ -3, 4, 0, 1, -2, 1 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 4, 0, 2, -2, 2 ], [ -2, 4, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -3, 4, 0, 1, -2, 1 ], [ -4, 4, 0, 1, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ], [ -2, 4, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -3, 4, 0, 1, -2, 1 ], [ -4, 4, 0, 1, -2, 2 ], [ -3, 4, 1, 1, -2, 2 ], [ -2, 4, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 4, 1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -3, 4, 1, 1, -2, 2 ], [ -2, 4, 0, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 4, 1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -3, 4, 1, 1, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 4, 1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -3, 4, 1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 4, 1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -4, 6, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 4, 1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 4, 1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -3, 4, 0, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 4, 1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -2, 3, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 5, -1, 1, -2, 2 ], [ -4, 4, 0, 1, -2, 2 ], [ -2, 3, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 5, -1, 1, -2, 2 ], [ -3, 3, -1, 1, -2, 2 ], [ -2, 3, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, -1, 1, -2, 2 ], [ -4, 4, -1, 1, -2, 2 ], [ -2, 3, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 0, -2, 2 ], [ -2, 3, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 0, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -3, 4, -2, 1, -2, 2 ], [ -3, 4, -1, 0, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 4, -2, 1, -2, 2 ], [ -3, 4, -1, 0, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 1 ] ], 0 ], + [ [ [ -3, 5, -1, 0, -2, 2 ], [ -3, 4, -1, 0, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 1 ] ], 0.25 ], + [ [ [ -3, 5, -1, 0, -2, 2 ], [ -3, 4, -1, 0, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -3, 4, -1, 0, -1, 2 ], [ -3, 4, -1, 0, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 4, -1, 0, -1, 2 ], [ -3, 4, -1, 0, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -3, 4, -1, 0, -1, 2 ], [ -2, 3, -2, 0, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -2, 4, -3, 0, -2, 2 ], [ -2, 3, -2, 0, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -3, 5, -2, 0, -2, 2 ], [ -2, 3, -2, 0, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 4, -2, 0, -2, 2 ], [ -2, 3, -2, 0, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -3, 4, -2, 0, -2, 2 ], [ -2, 3, -2, 0, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 4, -2, 0, -2, 2 ], [ -2, 3, -2, 0, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ], [ -1, 3, -2, 0, -3, 2 ] ], 0.25 ], + [ [ [ -3, 4, -2, 0, -2, 2 ], [ -2, 3, -2, 0, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ], [ -1, 3, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -3, 4, -2, 0, -2, 2 ], [ -2, 3, -2, 0, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -3, 4, -2, 0, -2, 2 ], [ -2, 3, -2, 0, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ], [ -3, 6, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 4, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ], [ -3, 6, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ], [ -3, 6, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -3, 6, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 6, -2, 0, -2, 2 ], [ -3, 6, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ], [ -2, 6, -2, 0, -2, 2 ], [ -3, 6, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ], [ -4, 6, -1, 0, -2, 2 ], [ -3, 6, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -3, 6, -3, 0, -2, 2 ], [ -4, 6, -1, 0, -2, 2 ], [ -3, 6, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -4, 6, -1, 0, -2, 2 ], [ -3, 6, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 6, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 6, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 6, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 6, -2, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 6, -2, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -4, 6, -2, 2, -2, 2 ] ], 0.25 ], + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 6, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 6, -2, 0, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 5, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -3, 0, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 5, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -3, 0, -2, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 5, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -3, 5, -3, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 5, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, -2, 1, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 5, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -4, 5, -2, 1, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ] ], 0.25 ], + [ [ [ -3, 4, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 4, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -3, 4, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -1, 2 ] ], 0 ], + [ [ [ -4, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -2, 4, -2, 0, -1, 2 ] ], 0 ], + [ [ [ -4, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -1, 3, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -2, 5, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -3, 4, -2, 1, -1, 2 ] ], 0.25 ], + [ [ [ -4, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -3, 6, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -2, 5, -2, 0, -3, 2 ] ], 0.25 ], + [ [ [ -4, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -1, 4, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -1, 3, -2, 0, -1, 2 ] ], 0.25 ], + [ [ [ -4, 5, -2, 0, -2, 2 ], [ -2, 4, -2, 0, -2, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -2, 5, -2, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 5, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -2, 5, -2, 0, -1, 2 ] ], 0 ], + [ [ [ -4, 4, -2, 0, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -2, 5, -2, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 4, -2, 0, -1, 2 ], [ -2, 4, -3, 0, -1, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -2, 5, -2, 0, -1, 2 ] ], 0 ], + [ [ [ -4, 4, -2, 0, -1, 2 ], [ -2, 4, -3, 0, -1, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -1, 4, -3, 0, -1, 2 ] ], 0 ], + [ [ [ -3, 4, -3, 0, -1, 2 ], [ -2, 4, -3, 0, -1, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -1, 4, -3, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 4, -3, 0, -1, 2 ], [ -3, 4, -2, 1, -1, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -1, 4, -3, 0, -1, 2 ] ], 0.25 ], + [ [ [ -3, 4, -3, 0, -1, 2 ], [ -2, 4, -2, 0, -1, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -1, 4, -3, 0, -1, 2 ] ], 0.25 ], + [ [ [ -3, 4, -3, 0, -1, 2 ], [ -1, 3, -3, 0, -1, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -1, 4, -3, 0, -1, 2 ] ], 0.25 ], + [ [ [ -3, 4, -3, 0, -1, 2 ], [ -2, 4, -2, 0, -1, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -1, 4, -3, 0, -1, 2 ] ], 0.25 ], + [ [ [ -3, 4, -3, 0, -1, 2 ], [ -2, 3, -3, 0, -1, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -1, 4, -3, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 4, -3, 0, -1, 2 ], [ -2, 4, -3, 0, -2, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -1, 4, -3, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 4, -3, 0, -1, 2 ], [ -2, 4, -3, 0, -2, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -1, 5, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -3, 4, -3, 0, -1, 2 ], [ -2, 4, -3, 0, -2, 2 ], [ -2, 4, -4, 0, -2, 2 ], [ -1, 5, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -3, 0, -2, 2 ], [ -2, 4, -3, 0, -2, 2 ], [ -2, 4, -4, 0, -2, 2 ], [ -1, 5, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -3, 4, -3, 0, -2, 3 ], [ -2, 4, -3, 0, -2, 2 ], [ -2, 4, -4, 0, -2, 2 ], [ -1, 5, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -3, 4, -3, 0, -2, 3 ], [ -2, 4, -3, 0, -2, 2 ], [ -3, 5, -3, 0, -2, 2 ], [ -1, 5, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -2, 5, -3, 0, -2, 2 ], [ -2, 4, -3, 0, -2, 2 ], [ -3, 5, -3, 0, -2, 2 ], [ -1, 5, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -2, 5, -3, 0, -2, 2 ], [ -2, 4, -3, 0, -2, 2 ], [ -3, 5, -3, 0, -2, 2 ], [ -1, 4, -3, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 4, -3, 0, -2, 3 ], [ -2, 4, -3, 0, -2, 2 ], [ -3, 5, -3, 0, -2, 2 ], [ -1, 4, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -2, 4, -3, 0, -2, 3 ], [ -3, 6, -3, 0, -2, 2 ], [ -3, 5, -3, 0, -2, 2 ], [ -1, 4, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -2, 4, -3, 0, -2, 3 ], [ -1, 4, -3, 0, -2, 1 ], [ -3, 5, -3, 0, -2, 2 ], [ -1, 4, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -2, 4, -3, 0, -2, 3 ], [ -1, 3, -3, 0, -2, 2 ], [ -3, 5, -3, 0, -2, 2 ], [ -1, 4, -3, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 4, -3, 0, -2, 3 ], [ -2, 5, -3, 0, -2, 2 ], [ -3, 5, -3, 0, -2, 2 ], [ -1, 4, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -2, 4, -3, 0, -2, 3 ], [ -2, 5, -3, 0, -2, 2 ], [ -3, 5, -3, 0, -2, 2 ], [ -2, 6, -3, 0, -2, 2 ] ], 0.75 ], + [ [ [ -3, 6, -3, 0, -2, 2 ], [ -2, 5, -3, 0, -2, 2 ], [ -3, 5, -3, 0, -2, 2 ], [ -2, 6, -3, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -3, 0, -2, 2 ], [ -3, 7, -3, 0, -2, 2 ], [ -3, 5, -3, 0, -2, 2 ], [ -2, 6, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -3, 6, -3, 0, -2, 2 ], [ -2, 6, -4, 0, -2, 2 ], [ -3, 5, -3, 0, -2, 2 ], [ -2, 6, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -3, 6, -3, 0, -2, 2 ], [ -1, 4, -3, 0, -2, 2 ], [ -3, 5, -3, 0, -2, 2 ], [ -2, 6, -3, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -3, 0, -2, 2 ], [ -1, 4, -3, 0, -2, 2 ], [ -4, 7, -3, 0, -2, 2 ], [ -2, 6, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -3, 6, -3, 0, -2, 2 ], [ -4, 6, -3, 0, -2, 2 ], [ -4, 7, -3, 0, -2, 2 ], [ -2, 6, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -3, 6, -3, 0, -2, 2 ], [ -4, 6, -3, 0, -2, 2 ], [ -3, 6, -4, 0, -2, 2 ], [ -2, 6, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -3, 6, -3, 0, -2, 2 ], [ -3, 6, -3, -1, -2, 2 ], [ -3, 6, -4, 0, -2, 2 ], [ -2, 6, -3, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 6, -3, -1, -2, 2 ], [ -3, 6, -3, -1, -2, 2 ], [ -3, 6, -4, 0, -2, 2 ], [ -2, 6, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -2, 6, -3, -1, -2, 2 ], [ -4, 6, -2, 0, -2, 2 ], [ -3, 6, -4, 0, -2, 2 ], [ -2, 6, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -2, 6, -3, -1, -2, 2 ], [ -4, 6, -2, 0, -2, 2 ], [ -3, 6, -3, 0, -3, 2 ], [ -2, 6, -3, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 6, -3, -1, -2, 2 ], [ -4, 6, -2, 0, -2, 2 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 6, -3, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 6, -3, -1, -2, 2 ], [ -4, 6, -2, -1, -2, 3 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 6, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -2, 6, -3, -1, -2, 2 ], [ -4, 6, -2, -1, -2, 3 ], [ -3, 6, -2, -1, -2, 2 ], [ -1, 5, -2, -1, -2, 2 ] ], 0 ], + [ [ [ -3, 6, -2, 0, -2, 2 ], [ -4, 6, -2, -1, -2, 3 ], [ -3, 6, -2, -1, -2, 2 ], [ -1, 5, -2, -1, -2, 2 ] ], 0.25 ], + [ [ [ -3, 6, -2, 0, -2, 2 ], [ -4, 6, -2, -1, -2, 3 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 6, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -3, 6, -2, 0, -2, 2 ], [ -4, 6, -2, -1, -2, 3 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 6, -2, -1, -2, 3 ] ], 0.25 ], + [ [ [ -2, 6, -2, -1, -2, 2 ], [ -4, 6, -2, -1, -2, 3 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 6, -2, -1, -2, 3 ] ], 0 ], + [ [ [ -2, 6, -2, -1, -2, 2 ], [ -4, 6, -2, -1, -2, 3 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 7, -2, -1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -2, -1, -2, 3 ], [ -4, 6, -2, -1, -2, 3 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 7, -2, -1, -2, 2 ] ], 0 ], + [ [ [ -3, 6, -2, -1, -2, 3 ], [ -4, 6, -2, -1, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -2, 7, -2, -1, -2, 2 ] ], 0 ], + [ [ [ -3, 6, -2, -1, -2, 3 ], [ -4, 6, -2, -1, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -3, 6, -2, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -2, -1, -2, 3 ], [ -2, 7, -2, -2, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -3, 6, -2, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 6, -2, -1, -2, 3 ], [ -1, 6, -2, -2, -3, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -3, 6, -2, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 6, -2, -1, -2, 3 ], [ -1, 5, -2, -2, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -3, 6, -2, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 6, -2, -1, -2, 3 ], [ -2, 6, -2, -1, -3, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -3, 6, -2, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 6, -2, -1, -2, 3 ], [ -2, 5, -2, -1, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -3, 6, -2, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -2, 5, -3, -1, -2, 3 ], [ -2, 5, -2, -1, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -3, 6, -2, 0, -2, 3 ] ], 0.25 ], + [ [ [ -2, 4, -2, -1, -2, 3 ], [ -2, 5, -2, -1, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -3, 6, -2, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -2, -2, -2, 3 ], [ -2, 5, -2, -1, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -3, 6, -2, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 5, -1, -1, -2, 3 ], [ -2, 5, -2, -1, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -3, 6, -2, 0, -2, 3 ] ], 0.25 ], + [ [ [ -2, 6, -3, -2, -2, 3 ], [ -2, 5, -2, -1, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -3, 6, -2, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -2, 6, -3, -2, -2, 3 ], [ -2, 5, -2, -1, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -2, 6, -3, -1, -2, 3 ] ], 0 ], + [ [ [ -2, 6, -3, -2, -2, 3 ], [ -2, 6, -3, -2, -2, 4 ], [ -3, 6, -2, -2, -2, 3 ], [ -2, 6, -3, -1, -2, 3 ] ], 0.25 ], + [ [ [ -2, 6, -3, -2, -2, 3 ], [ -2, 6, -3, -2, -2, 4 ], [ -3, 6, -2, -2, -2, 3 ], [ -1, 6, -3, -2, -2, 3 ] ], 0.25 ], + [ [ [ -2, 6, -3, -2, -2, 3 ], [ -2, 6, -3, -2, -2, 4 ], [ -3, 6, -2, -2, -2, 3 ], [ -2, 7, -2, -2, -2, 3 ] ], 0 ], + [ [ [ -2, 6, -3, -2, -2, 3 ], [ -2, 7, -3, -2, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -2, 7, -2, -2, -2, 3 ] ], 0.25 ], + [ [ [ -2, 6, -3, -2, -2, 3 ], [ -2, 6, -2, -2, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -2, 7, -2, -2, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -2, 6, -3, -2, -2, 3 ], [ -2, 6, -2, -2, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -3, 6, -1, -2, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -2, 6, -3, -2, -2, 3 ], [ -2, 6, -2, -2, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -3, 7, -3, -2, -2, 3 ] ], 0 ], + [ [ [ -2, 6, -3, -2, -2, 3 ], [ -3, 6, -3, -2, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -3, 7, -3, -2, -2, 3 ] ], 0.25 ], + [ [ [ -2, 6, -3, -2, -2, 3 ], [ -3, 6, -3, -2, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -2, 5, -2, -2, -2, 3 ] ], 0.25 ], + [ [ [ -2, 6, -3, -2, -2, 3 ], [ -3, 6, -3, -2, -2, 3 ], [ -3, 6, -2, -2, -2, 3 ], [ -2, 6, -2, -2, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 6, -3, -2, -2, 3 ], [ -3, 6, -1, -2, -2, 2 ], [ -3, 6, -2, -2, -2, 3 ], [ -2, 6, -2, -2, -2, 2 ] ], 0 ], + [ [ [ -2, 6, -3, -2, -2, 3 ], [ -3, 6, -1, -2, -2, 2 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 6, -2, -2, -2, 2 ] ], 0 ], + [ [ [ -2, 6, -1, -2, -2, 2 ], [ -3, 6, -1, -2, -2, 2 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 6, -2, -2, -2, 2 ] ], 0.25 ], + [ [ [ -1, 5, -2, -2, -2, 2 ], [ -3, 6, -1, -2, -2, 2 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 6, -2, -2, -2, 2 ] ], 0 ], + [ [ [ -1, 5, -2, -2, -2, 2 ], [ -2, 5, -2, -2, -2, 2 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 6, -2, -2, -2, 2 ] ], 0.25 ], + [ [ [ -2, 7, -2, -2, -2, 2 ], [ -2, 5, -2, -2, -2, 2 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 6, -2, -2, -2, 2 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ -2, 6, -3, -2, -2, 3 ], [ -3, 6, -1, -2, -2, 2 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 6, -2, -2, -2, 2 ] ], + [ [ -2, 6, -1, -2, -2, 2 ], [ -3, 6, -1, -2, -2, 2 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 6, -2, -2, -2, 2 ] ], + [ [ -1, 5, -2, -2, -2, 2 ], [ -3, 6, -1, -2, -2, 2 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 6, -2, -2, -2, 2 ] ], + [ [ -1, 5, -2, -2, -2, 2 ], [ -2, 5, -2, -2, -2, 2 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 6, -2, -2, -2, 2 ] ], + [ [ -2, 7, -2, -2, -2, 2 ], [ -2, 5, -2, -2, -2, 2 ], [ -3, 6, -2, -1, -2, 2 ], [ -2, 6, -2, -2, -2, 2 ] ] +], +"cur_uid": "6686d651", +"ref_uid": "5f3f1c84", +"order_seed": 636846, +"dur_seed": 919323, +"motifs_seed": 543800, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 2, 3 ], [ ] ], + [ [ 3, 2, 0 ], [ 1, 1, 1, 1, 1 ], [ ] ], + [ [ 0, 3 ], [ 1, 2, 2, 2 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 0, 1, 2 ], [ 3, 3, 3, 3 ], [ ] ], + [ [ 3, 0 ], [ 2, 1 ], [ ] ], + [ [ 2, 3 ], [ 1, 0, 0, 1 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 3, 3, 2 ], [ ] ], + [ [ 0, 3, 1 ], [ 2, 2 ], [ ] ], + [ [ 2, 1 ], [ 0, 3, 0, 3, 0, 3 ], [ ] ], + [ [ 3, 2, 1 ], [ 0, 0, 0 ], [ ] ], + [ [ 3, 2, 1 ], [ 0, 0, 0 ], [ ] ], + [ [ 1, 3, 0 ], [ 2, 2, 2 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 2, 0, 3, 3 ], [ ] ], + [ [ 1, 3, 0 ], [ 2, 2 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 1, 1, 2, 0 ], [ ] ], + [ [ 2, 1 ], [ 3, 0, 3, 0 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 0, 0, 0 ], [ ] ], + [ [ 2, 0, 1 ], [ 3, 3, 3, 3 ], [ ] ], + [ [ 3 ], [ 1, 0, 2, 2, 1, 2, 1 ], [ ] ], + [ [ 0 ], [ 1, 2, 3, 3, 3, 3 ], [ ] ], + [ [ 2, 0, 1 ], [ 3, 3, 3 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 1, 0, 3, 0 ], [ ] ], + [ [ 2, 0, 1 ], [ 3, 3 ], [ ] ], + [ [ 1 ], [ 0, 2, 3 ], [ ] ], + [ [ 1, 2, 0 ], [ 3, 3, 3, 3 ], [ ] ], + [ [ 2, 1, 0 ], [ 3, 3, 3, 3 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 2 ], [ 1, 3, 0 ], [ ] ], + [ [ 2, 0, 3 ], [ 1, 1, 1, 1, 1 ], [ ] ], + [ [ 2, 0, 3 ], [ 1 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 0, 2, 0, 3 ], [ ] ], + [ [ 3, 2 ], [ 0, 1, 1, 1 ], [ ] ], + [ [ 2 ], [ 1, 3, 0 ], [ ] ], + [ [ 0, 2, 3 ], [ 1, 1, 1 ], [ ] ], + [ [ 3, 0 ], [ 2, 1, 2, 1 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 3, 0, 1 ], [ 2 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 3, 3, 0, 3 ], [ ] ], + [ [ 1 ], [ 0, 2, 3 ], [ ] ], + [ [ 2, 3, 0 ], [ 1, 1, 1, 1, 1 ], [ ] ], + [ [ 3, 1, 2 ], [ 0, 0, 0, 0, 0 ], [ ] ], + [ [ 0, 2 ], [ 3, 1, 3, 3, 1, 1 ], [ ] ], + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 0, 2 ], [ 3, 1, 3, 3 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 0, 1, 0 ], [ ] ] +], +"sus_weights": [ 0.7, 0.48, 0.49 ], +"order_size": [ 49, 49.489795918367 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6686d651/lilypond/part_I.ly b/resources/string_quartet_3_rise/6686d651/lilypond/part_I.ly new file mode 100644 index 0000000..0664736 --- /dev/null +++ b/resources/string_quartet_3_rise/6686d651/lilypond/part_I.ly @@ -0,0 +1,36 @@ +{ + { g8^\markup { \pad-markup #0.2 "+28"}[ fis8^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ fis8[ gis8^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ais2^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { ais2 ~ ais8[ gis8^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ gis8[ g8^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }}] } + \bar "|" + { fis8^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}[ a8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] ais2^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ ais8[ dis''8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] } + \bar "|" + { ais'8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ dis'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ dis'4 e'8^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }}[ f'8^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}] gis'4^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { gis'1 } + \bar "|" + { f''8^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ gis''8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ gis''8[ gis'8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] dis'4^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ dis'8[ e'8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] ~ } + \bar "|" + { e'4 ~ e'8[ d'8^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }}] d'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + \bar "|" + { d'4 ~ d'8[ d'8^\markup { \pad-markup #0.2 "-40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }}] dis'8^\markup { \pad-markup #0.2 "+25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}[ d'8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] e'4^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + \bar "|" + { e'4 ~ e'8[ e''8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] b'8^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ c''8^\markup { \pad-markup #0.2 "+31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] d''8^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ cis''8^\markup { \pad-markup #0.2 "-42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}] } + \bar "|" + { c''8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}[ e'8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] f'4^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} g'4^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} a'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ gis'8^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] } + \bar "|" + { g'8^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}[ f'8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] f'8^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }}[ e'8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] dis'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}[ e'8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] d''8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ cis''8^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] } + \bar "|" + { dis''4^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} e''2.^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { e''8[ f''8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ f''4 ais'2^\markup { \pad-markup #0.2 "+27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { ais'8[ c''8^\markup { \pad-markup #0.2 "+31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ c''2. ~ } + \bar "|" + { c''2 ~ c''8[ b'8^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] e''8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ dis''8^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] } + \bar "|" + { d''8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ cis''8^\markup { \pad-markup #0.2 "-42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ cis''2. ~ } + \bar "|" + { cis''2 b'8^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}[ cis''8^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] c''4^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6686d651/lilypond/part_II.ly b/resources/string_quartet_3_rise/6686d651/lilypond/part_II.ly new file mode 100644 index 0000000..d781e20 --- /dev/null +++ b/resources/string_quartet_3_rise/6686d651/lilypond/part_II.ly @@ -0,0 +1,36 @@ +{ + { c'4^\markup { \pad-markup #0.2 "+26"} b8^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}[ ais8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] b2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }} ~ } + \bar "|" + { b4 cis'8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }}[ dis'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] cis'4^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} e'4^\markup { \pad-markup #0.2 "-24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + \bar "|" + { e'4 ~ e'8[ dis'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ dis'4 ~ dis'8[ b'8^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ } + \bar "|" + { b'8[ ais'8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] gis'8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ fis'8^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ fis'2 ~ } + \bar "|" + { fis'2 ~ fis'8[ cis'8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] dis'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}[ e'8^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] } + \bar "|" + { f'4^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} gis'8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ b'8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}] ~ b'8[ ais'8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}] gis'4^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} } + \bar "|" + { a'4^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} b'2^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} a'4^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } + \bar "|" + { a'1 } + \bar "|" + { b'8^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ e''8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] gis8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}[ a8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ a2 ~ } + \bar "|" + { a1 } + \bar "|" + { gis1^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { gis1 ~ } + \bar "|" + { gis4 fis8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}[ f8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ f2 ~ } + \bar "|" + { f1 } + \bar "|" + { g8^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ gis8^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ gis8[ g8^\markup { \pad-markup #0.2 "-20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }}] fis2^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { fis8[ f8^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}] ~ f2. ~ } + \bar "|" + { f1} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6686d651/lilypond/part_III.ly b/resources/string_quartet_3_rise/6686d651/lilypond/part_III.ly new file mode 100644 index 0000000..e14c200 --- /dev/null +++ b/resources/string_quartet_3_rise/6686d651/lilypond/part_III.ly @@ -0,0 +1,36 @@ +{ + { dis'2^\markup { \pad-markup #0.2 "-43"} ~ dis'8[ e'8^\markup { \pad-markup #0.2 "-4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] gis8^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ g8^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}] } + \bar "|" + { cis8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}[ dis8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] cis2.^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} ~ } + \bar "|" + { cis4 ~ cis8[ dis8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] f4^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} fis8^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}[ gis8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { gis1 ~ } + \bar "|" + { gis1 ~ } + \bar "|" + { gis1 } + \bar "|" + { a8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ e8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] fis2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} ~ fis8[ g8^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { g2. ~ g8[ a8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { a8[ b8^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] c'8^\markup { \pad-markup #0.2 "+31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}[ d'8^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ d'2 ~ } + \bar "|" + { d'4 cis'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }}[ d'8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] ~ d'2 ~ } + \bar "|" + { d'1 ~ } + \bar "|" + { d'8[ dis'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] e'8^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}[ f'8^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }}] gis'8^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ a'8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] gis'8^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ a8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] } + \bar "|" + { ais2^\markup { \pad-markup #0.2 "+27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ ais8[ c'8^\markup { \pad-markup #0.2 "+31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] d'8^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }}[ dis'8^\markup { \pad-markup #0.2 "+25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}] } + \bar "|" + { f'2^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ f'8[ g'8^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] gis'8^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}[ ais'8^\markup { \pad-markup #0.2 "+27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] } + \bar "|" + { c4^\markup { \pad-markup #0.2 "+31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} dis8^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}[ e8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }}] ~ e8[ dis8^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }}] ~ dis4 ~ } + \bar "|" + { dis4 c''8^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}[ c''8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }}] ais'8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}[ a'8^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] gis'4^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { gis'2 ais'4^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} gis'8^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ f'8^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}]} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6686d651/lilypond/part_IV.ly b/resources/string_quartet_3_rise/6686d651/lilypond/part_IV.ly new file mode 100644 index 0000000..4d2dc9c --- /dev/null +++ b/resources/string_quartet_3_rise/6686d651/lilypond/part_IV.ly @@ -0,0 +1,36 @@ +{ + { fis'4^\markup { \pad-markup #0.2 "+43"} ~ fis'8[ gis'8^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }}] ~ gis'2 ~ } + \bar "|" + { gis'2 ~ gis'8[ ais'8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ ais'4 ~ } + \bar "|" + { ais'2 ~ ais'8[ b'8^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] dis,4^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { dis,2 dis,8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }}[ e,8^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] fis,8^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ gis,8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] } + \bar "|" + { b,8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}[ cis8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] dis8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}[ dis'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] b2^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} } + \bar "|" + { cis'8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}[ b8^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }}] ~ b8[ b8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ b2 } + \bar "|" + { b4^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} c'8^\markup { \pad-markup #0.2 "-18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}[ cis'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ cis'8[ c'8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }}] ~ c'8[ ais8^\markup { \pad-markup #0.2 "+27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}] } + \bar "|" + { a8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ d,8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] d2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ d8[ e8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { e1 ~ } + \bar "|" + { e4 f4^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} g8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }}[ d8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ d4 } + \bar "|" + { a,1^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a,8[ gis,8^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] e2.^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { e4 f8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ g8^\markup { \pad-markup #0.2 "-32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}] f'8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ g'8^\markup { \pad-markup #0.2 "-32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}] ~ g'4 ~ } + \bar "|" + { g'2 c'2^\markup { \pad-markup #0.2 "+31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c'4 ~ c'8[ dis'8^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ dis'8[ e'8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }}] ~ e'4 } + \bar "|" + { fis'8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ dis'8^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ dis'2 ~ dis'8[ e'8^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] } + \bar "|" + { cis'8^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}[ c'8^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] c'8^\markup { \pad-markup #0.2 "-26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}[ cis'8^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] ~ cis'2} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/668ed417/668ed417_code.scd b/resources/string_quartet_3_rise/668ed417/668ed417_code.scd new file mode 100644 index 0000000..e1a9d92 --- /dev/null +++ b/resources/string_quartet_3_rise/668ed417/668ed417_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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"], {(62.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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/668ed417/668ed417_mus_model.json b/resources/string_quartet_3_rise/668ed417/668ed417_mus_model.json new file mode 100644 index 0000000..507e47a --- /dev/null +++ b/resources/string_quartet_3_rise/668ed417/668ed417_mus_model.json @@ -0,0 +1,384 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -2, 7, -3, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0 ], + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 7, -4, 0, -2, 2 ], [ -2, 7, -3, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 7, -3, 0, -3, 2 ], [ -2, 7, -3, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -4, 0, -3, 2 ], [ -3, 7, -3, 0, -3, 2 ], [ -2, 7, -4, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -3, 2 ], [ -3, 7, -3, 0, -3, 2 ], [ -2, 7, -4, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -3, 2 ], [ -2, 7, -4, -1, -3, 2 ], [ -2, 7, -4, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -3, 2 ], [ -2, 7, -4, 0, -3, 1 ], [ -2, 7, -4, 0, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -3, 2 ], [ -2, 7, -4, 0, -3, 1 ], [ -1, 7, -4, -1, -3, 2 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -3, 2 ], [ -2, 7, -4, 0, -3, 1 ], [ -1, 7, -4, 0, -3, 1 ], [ -3, 7, -4, 0, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, -1, -3, 2 ], [ -2, 7, -4, 0, -3, 1 ], [ -1, 7, -4, 0, -3, 1 ], [ -3, 8, -4, 0, -3, 1 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -3, 2 ], [ -2, 7, -4, 0, -3, 1 ], [ -1, 7, -4, 0, -3, 1 ], [ -3, 7, -3, 0, -3, 1 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -3, 2 ], [ -2, 7, -4, 0, -3, 1 ], [ -1, 7, -4, 0, -3, 1 ], [ -3, 7, -4, 0, -2, 1 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, -1, -3, 2 ], [ -1, 7, -4, -1, -3, 1 ], [ -1, 7, -4, 0, -3, 1 ], [ -3, 7, -4, 0, -2, 1 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -3, 2 ], [ -2, 7, -3, 0, -3, 1 ], [ -1, 7, -4, 0, -3, 1 ], [ -3, 7, -4, 0, -2, 1 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -3, 2 ], [ -1, 6, -4, 0, -3, 1 ], [ -1, 7, -4, 0, -3, 1 ], [ -3, 7, -4, 0, -2, 1 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -3, 2 ], [ -2, 7, -4, 0, -2, 1 ], [ -1, 7, -4, 0, -3, 1 ], [ -3, 7, -4, 0, -2, 1 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -3, 2 ], [ -2, 7, -4, -1, -3, 3 ], [ -1, 7, -4, 0, -3, 1 ], [ -3, 7, -4, 0, -2, 1 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, -1, -3, 2 ], [ -2, 7, -4, -1, -3, 3 ], [ -2, 7, -3, -1, -3, 3 ], [ -3, 7, -4, 0, -2, 1 ] ], 0 ], + [ [ [ -3, 6, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -2, 7, -3, -1, -3, 3 ], [ -3, 7, -4, 0, -2, 1 ] ], 0.25 ], + [ [ [ -3, 6, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -3, 7, -4, 0, -2, 1 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -1, 7, -4, -1, -4, 3 ], [ -3, 7, -4, 0, -2, 1 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -4, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -1, 7, -4, -1, -4, 3 ], [ -3, 7, -4, 0, -2, 1 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -4, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -1, 7, -4, -1, -4, 3 ], [ -3, 7, -4, -1, -3, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -5, -1, -3, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -1, 7, -4, -1, -4, 3 ], [ -3, 7, -4, -1, -3, 3 ] ], 0 ], + [ [ [ -3, 7, -5, -1, -3, 3 ], [ -2, 8, -4, -1, -4, 3 ], [ -1, 7, -4, -1, -4, 3 ], [ -3, 7, -4, -1, -3, 3 ] ], 0.25 ], + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -2, 8, -4, -1, -4, 3 ], [ -1, 7, -4, -1, -4, 3 ], [ -3, 7, -4, -1, -3, 3 ] ], 0.25 ], + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -1, 7, -4, -1, -4, 3 ], [ -3, 7, -4, -1, -3, 3 ] ], 0.25 ], + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -2, 7, -3, -1, -4, 3 ], [ -1, 7, -4, -1, -4, 3 ], [ -3, 7, -4, -1, -3, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -2, 7, -3, -1, -4, 3 ], [ -3, 8, -3, -1, -3, 3 ], [ -3, 7, -4, -1, -3, 3 ] ], 0 ], + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -3, 8, -4, -1, -3, 3 ], [ -3, 8, -3, -1, -3, 3 ], [ -3, 7, -4, -1, -3, 3 ] ], 0 ], + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -3, 8, -4, -1, -3, 3 ], [ -3, 8, -3, -1, -3, 3 ], [ -4, 8, -3, -1, -3, 3 ] ], 0.25 ], + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -3, 8, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -4, 8, -3, -1, -3, 3 ] ], 0.25 ], + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -3, 8, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -2, 8, -4, -1, -3, 3 ] ], 0 ], + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -3, 8, -4, -1, -3, 3 ], [ -3, 9, -4, -1, -3, 3 ], [ -2, 8, -4, -1, -3, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -3, 8, -4, -1, -3, 3 ], [ -3, 9, -4, -1, -3, 3 ], [ -3, 9, -3, -1, -3, 3 ] ], 0.25 ], + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -3, 8, -4, -1, -3, 3 ], [ -3, 9, -4, -1, -3, 3 ], [ -2, 8, -4, -1, -3, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -3, 8, -4, -1, -3, 3 ], [ -3, 9, -4, -1, -3, 3 ], [ -1, 8, -4, -2, -3, 3 ] ], 0 ], + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -4, 10, -4, -1, -3, 3 ], [ -3, 9, -4, -1, -3, 3 ], [ -1, 8, -4, -2, -3, 3 ] ], 0.25 ], + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -2, 8, -4, -2, -3, 3 ], [ -3, 9, -4, -1, -3, 3 ], [ -1, 8, -4, -2, -3, 3 ] ], 0.25 ], + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -3, 8, -3, -1, -3, 3 ], [ -3, 9, -4, -1, -3, 3 ], [ -1, 8, -4, -2, -3, 3 ] ], 0.25 ], + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -3, 9, -4, -1, -3, 3 ], [ -1, 8, -4, -2, -3, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -3, 9, -4, -1, -3, 3 ], [ -2, 8, -4, -1, -3, 3 ] ], 0 ], + [ [ [ -4, 8, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -3, 8, -4, -1, -3, 3 ], [ -2, 8, -4, -1, -3, 3 ] ], 0 ], + [ [ [ -3, 7, -5, -1, -3, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -3, 8, -4, -1, -3, 3 ], [ -2, 8, -4, -1, -3, 3 ] ], 0.25 ], + [ [ [ -3, 7, -5, -1, -3, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -3, 8, -4, -1, -3, 3 ], [ -1, 7, -5, -1, -3, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -5, -1, -3, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -3, 8, -4, -1, -3, 3 ], [ -2, 7, -4, 0, -3, 3 ] ], 0 ], + [ [ [ -4, 7, -4, 0, -3, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -3, 8, -4, -1, -3, 3 ], [ -2, 7, -4, 0, -3, 3 ] ], 0 ], + [ [ [ -4, 7, -4, 0, -3, 3 ], [ -2, 7, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -4, 3 ], [ -2, 7, -4, 0, -3, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -4, 0, -3, 3 ], [ -3, 7, -3, 0, -3, 3 ], [ -2, 7, -4, -1, -4, 3 ], [ -2, 7, -4, 0, -3, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -3, 3 ], [ -2, 6, -4, 0, -3, 3 ], [ -2, 7, -4, -1, -4, 3 ], [ -2, 7, -4, 0, -3, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -4, 0, -3, 3 ], [ -2, 6, -4, 0, -3, 3 ], [ -2, 7, -4, -1, -4, 3 ], [ -3, 7, -4, 0, -3, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -3, 3 ], [ -2, 6, -4, 0, -3, 3 ], [ -2, 7, -4, -1, -4, 3 ], [ -2, 6, -4, 0, -4, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -4, 0, -3, 3 ], [ -2, 6, -4, 0, -3, 3 ], [ -2, 7, -4, -1, -4, 3 ], [ -2, 7, -3, -1, -4, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -3, 3 ], [ -2, 6, -4, 0, -3, 3 ], [ -2, 7, -4, -1, -4, 3 ], [ -2, 7, -4, -1, -3, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -3, 3 ], [ -2, 6, -4, 0, -3, 3 ], [ -2, 7, -4, -1, -4, 3 ], [ -2, 8, -4, -1, -4, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -3, 3 ], [ -2, 6, -4, 0, -3, 3 ], [ -2, 7, -4, -1, -4, 3 ], [ -3, 7, -3, 0, -3, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -4, 0, -3, 3 ], [ -2, 6, -4, 0, -3, 3 ], [ -2, 7, -4, -1, -4, 3 ], [ -2, 6, -4, -1, -3, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -3, 3 ], [ -2, 6, -4, 0, -3, 3 ], [ -2, 7, -4, -1, -4, 3 ], [ -3, 7, -4, 0, -4, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -3, 3 ], [ -2, 6, -4, 0, -3, 3 ], [ -2, 7, -4, -1, -4, 3 ], [ -4, 7, -4, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -4, 0, -3, 3 ], [ -4, 7, -4, 1, -2, 3 ], [ -2, 7, -4, -1, -4, 3 ], [ -4, 7, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -4, 7, -4, 0, -3, 3 ], [ -4, 7, -4, 1, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -4, 7, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -4, 6, -4, 0, -2, 3 ], [ -4, 7, -4, 1, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -4, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 6, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -4, 7, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -5, 7, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -4, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -5, 7, -4, 0, -2, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -4, 7, -4, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -5, 7, -4, 0, -2, 3 ], [ -3, 6, -4, -1, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -4, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -5, 6, -4, 0, -2, 4 ], [ -3, 6, -4, -1, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -4, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -5, 6, -4, 0, -2, 4 ], [ -3, 6, -4, -1, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -4, 6, -4, 0, -2, 4 ] ], 0.25 ], + [ [ [ -5, 6, -4, 0, -2, 4 ], [ -3, 6, -4, -1, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -3, 6, -5, 0, -2, 3 ] ], 0 ], + [ [ [ -4, 6, -5, 0, -2, 3 ], [ -3, 6, -4, -1, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -3, 6, -5, 0, -2, 3 ] ], 0 ], + [ [ [ -4, 6, -5, 0, -2, 3 ], [ -2, 6, -5, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -3, 6, -5, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 6, -5, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -3, 6, -5, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 6, -5, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -2, 5, -5, 0, -2, 3 ], [ -3, 6, -5, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 6, -5, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 7, -5, 0, -2, 3 ], [ -3, 6, -5, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 7, -5, 0, -2, 3 ], [ -3, 6, -5, 0, -2, 3 ] ], 0 ], + [ [ [ -3, 6, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 7, -5, 0, -2, 3 ], [ -4, 7, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -3, 6, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -4, 8, -4, 0, -2, 3 ], [ -4, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 6, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -4, 8, -4, 0, -2, 3 ], [ -3, 8, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -4, 8, -4, 0, -2, 3 ], [ -3, 8, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -3, 8, -4, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -2, 6, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -4, 6, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -2, 6, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 6, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -3, 7, -3, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 6, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -2, 6, -4, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -5, 6, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -2, 6, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, -1, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -2, 6, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 6, -5, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -2, 6, -4, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -5, 7, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -2, 6, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -5, 7, -4, 0, -2, 3 ], [ -2, 6, -5, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -2, 6, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -5, 7, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -2, 6, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -5, 6, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -2, 6, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -5, 6, -4, 0, -2, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -2, 6, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -2, 5, -4, 0, -2, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ], [ -2, 6, -4, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -2, 5, -4, 0, -2, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -3, 5, -4, 0, -2, 3 ], [ -2, 6, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -2, 5, -4, 0, -2, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -3, 5, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, 0, -2, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -3, 5, -4, 0, -2, 3 ], [ -3, 6, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -3, 7, -4, 0, -2, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -3, 5, -4, 0, -2, 3 ], [ -4, 7, -4, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -4, 0, -1, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -3, 5, -4, 0, -2, 3 ], [ -4, 7, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -3, 6, -4, 0, -1, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -4, 7, -4, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -4, 0, -1, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -4, 6, -4, 0, -1, 3 ] ], 0 ], + [ [ [ -2, 5, -4, 0, -2, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -4, 6, -4, 0, -1, 3 ] ], 0.25 ], + [ [ [ -2, 5, -4, 0, -2, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 5, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -2, 5, -4, 0, -2, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 6, -4, 0, -3, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -3, 0, -2, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 6, -4, 0, -3, 3 ] ], 0.25 ], + [ [ [ -3, 7, -5, 0, -2, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 6, -4, 0, -3, 3 ] ], 0.25 ], + [ [ [ -2, 6, -5, 0, -3, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 6, -4, 0, -3, 3 ] ], 0.25 ], + [ [ [ -3, 6, -5, 0, -2, 3 ], [ -4, 6, -4, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 6, -4, 0, -3, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -5, 0, -2, 3 ], [ -3, 6, -5, -1, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 6, -4, 0, -3, 3 ] ], 0.25 ], + [ [ [ -3, 6, -5, 0, -2, 3 ], [ -4, 7, -5, 0, -3, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 6, -4, 0, -3, 3 ] ], 0.25 ], + [ [ [ -3, 6, -5, 0, -2, 3 ], [ -4, 6, -5, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 6, -4, 0, -3, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -5, 0, -2, 3 ], [ -4, 6, -5, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 7, -5, -1, -2, 3 ] ], 0 ], + [ [ [ -3, 6, -5, 0, -2, 3 ], [ -5, 8, -5, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 7, -5, -1, -2, 3 ] ], 0.25 ], + [ [ [ -3, 6, -5, 0, -2, 3 ], [ -5, 8, -5, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -4, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 6, -5, 0, -2, 3 ], [ -5, 8, -5, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 8, -5, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 6, -5, 0, -2, 3 ], [ -5, 8, -5, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -2, 6, -5, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 6, -5, 0, -2, 3 ], [ -5, 8, -5, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 7, -5, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 8, -5, 0, -2, 3 ], [ -5, 8, -5, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 7, -5, 0, -2, 3 ] ], 0 ], + [ [ [ -4, 8, -5, 0, -2, 3 ], [ -5, 8, -5, 0, -2, 3 ], [ -5, 8, -4, 0, -2, 3 ], [ -3, 7, -5, 0, -2, 3 ] ], 0.25 ], + [ [ [ -5, 8, -5, 1, -2, 3 ], [ -5, 8, -5, 0, -2, 3 ], [ -5, 8, -4, 0, -2, 3 ], [ -3, 7, -5, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -5, 8, -5, 0, -2, 3 ], [ -5, 8, -4, 0, -2, 3 ], [ -3, 7, -5, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -5, 8, -5, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 7, -5, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -5, 8, -5, 0, -2, 3 ], [ -4, 8, -5, 0, -3, 3 ], [ -3, 7, -5, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -5, 8, -5, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 7, -5, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -5, 8, -5, 0, -2, 3 ], [ -4, 7, -4, 0, -3, 3 ], [ -3, 7, -5, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 7, -5, 0, -3, 3 ], [ -4, 7, -4, 0, -3, 3 ], [ -3, 7, -5, 0, -2, 3 ] ], 0 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 7, -5, 0, -3, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 7, -5, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 6, -5, 0, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 7, -5, 0, -2, 3 ] ], 0 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 6, -5, 0, -2, 3 ], [ -3, 7, -5, -1, -2, 3 ], [ -3, 7, -5, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 6, -5, 0, -2, 3 ], [ -3, 7, -5, -1, -2, 3 ], [ -4, 8, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 6, -5, 0, -2, 3 ], [ -5, 7, -4, 1, -2, 3 ], [ -4, 8, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -5, 7, -4, 1, -2, 3 ], [ -4, 8, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -5, 7, -4, 1, -2, 3 ], [ -4, 7, -4, 0, -2, 4 ] ], 0 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -4, 7, -4, 0, -2, 4 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -4, 7, -5, 0, -2, 3 ], [ -3, 7, -5, 0, -2, 3 ] ], 0 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -5, 8, -4, 0, -2, 3 ], [ -3, 7, -5, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -5, 8, -4, 0, -2, 3 ], [ -3, 8, -4, -1, -2, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -5, 8, -4, 0, -2, 3 ], [ -4, 8, -3, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -5, 8, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -5, 8, -4, 0, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -5, 8, -4, 0, -2, 3 ], [ -4, 7, -3, -1, -2, 3 ] ], 0.25 ], + [ [ [ -4, 7, -4, 0, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -4, 7, -4, -1, -1, 3 ], [ -4, 7, -3, -1, -2, 3 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -4, 7, -4, -1, -1, 3 ], [ -4, 7, -3, -1, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -4, 7, -4, -1, -1, 3 ], [ -3, 6, -4, -1, -2, 3 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -4, 8, -4, -1, -2, 3 ], [ -3, 6, -4, -1, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -4, 8, -4, -1, -2, 3 ], [ -3, 8, -4, -1, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -4, 8, -4, -1, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -4, 8, -4, -1, -2, 3 ], [ -3, 7, -4, -1, -2, 4 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -3, 7, -4, -2, -2, 3 ], [ -4, 8, -4, -1, -2, 3 ], [ -3, 7, -4, -1, -2, 4 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -3, 7, -4, -2, -2, 3 ], [ -4, 8, -4, -1, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -3, 7, -4, -2, -2, 3 ], [ -3, 7, -4, -1, -3, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -5, 7, -3, 0, -2, 3 ], [ -3, 7, -4, -1, -3, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -3, 7, -4, 0, -2, 2 ], [ -5, 7, -3, 0, -2, 3 ], [ -3, 7, -4, -1, -3, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -3, 7, -4, 0, -2, 2 ], [ -5, 7, -3, 0, -2, 3 ], [ -5, 8, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, 0, -2, 2 ], [ -4, 6, -4, 0, -2, 3 ], [ -5, 8, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, 0, -2, 2 ], [ -4, 7, -4, 0, -2, 2 ], [ -5, 8, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, 0, -2, 2 ], [ -4, 7, -4, 0, -2, 2 ], [ -2, 7, -4, 0, -2, 2 ], [ -3, 7, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -3, 7, -4, 0, -2, 2 ], [ -4, 7, -4, -1, -2, 3 ], [ -2, 7, -4, 0, -2, 2 ], [ -3, 7, -4, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, 0, -2, 2 ], [ -4, 7, -4, -1, -2, 3 ], [ -2, 6, -4, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, 0, -2, 2 ], [ -4, 7, -4, -1, -2, 3 ], [ -3, 7, -3, 0, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, 0, -2, 2 ], [ -4, 7, -4, -1, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -3, 7, -4, -2, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -3, 7, -4, -2, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -1, 6, -4, -1, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -4, 7, -3, -1, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -1, 6, -4, -1, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -3, 6, -4, -1, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -1, 6, -4, -1, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -4, 8, -4, -1, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -1, 6, -4, -1, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -4, 8, -4, -1, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -3, 8, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -4, 8, -4, -1, -2, 3 ], [ -3, 9, -4, -1, -2, 3 ], [ -3, 8, -4, 0, -2, 3 ] ], 0 ], + [ [ [ -4, 8, -3, -1, -2, 3 ], [ -4, 8, -4, -1, -2, 3 ], [ -3, 9, -4, -1, -2, 3 ], [ -3, 8, -4, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 8, -3, -1, -2, 3 ], [ -4, 8, -4, -1, -2, 3 ], [ -3, 9, -4, -1, -2, 3 ], [ -3, 8, -4, -1, -2, 3 ] ], 0 ], + [ [ [ -4, 8, -3, -1, -2, 3 ], [ -4, 8, -4, -1, -2, 3 ], [ -3, 8, -3, -1, -2, 3 ], [ -3, 8, -4, -1, -2, 3 ] ], 0 ], + [ [ [ -3, 8, -4, -2, -2, 3 ], [ -4, 8, -4, -1, -2, 3 ], [ -3, 8, -3, -1, -2, 3 ], [ -3, 8, -4, -1, -2, 3 ] ], 0.25 ], + [ [ [ -3, 8, -4, -2, -2, 3 ], [ -4, 8, -4, -1, -2, 3 ], [ -3, 8, -3, -1, -2, 3 ], [ -2, 8, -4, -2, -2, 3 ] ], 0 ], + [ [ [ -3, 8, -4, -2, -2, 3 ], [ -4, 8, -4, -1, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -2, 8, -4, -2, -2, 3 ] ], 0 ], + [ [ [ -3, 8, -4, -1, -2, 2 ], [ -4, 8, -4, -1, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -2, 8, -4, -2, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 8, -4, -1, -2, 2 ], [ -3, 7, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -2, 8, -4, -2, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -3, 7, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -2, 8, -4, -2, -2, 3 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -3, 7, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -2, 7, -5, -1, -2, 3 ] ], 0.25 ], + [ [ [ -2, 7, -4, -2, -2, 3 ], [ -3, 7, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -2, 7, -5, -1, -2, 3 ] ], 0 ], + [ [ [ -2, 7, -4, -2, -2, 3 ], [ -3, 7, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -2, 7, -4, -1, -3, 3 ] ], 0.25 ], + [ [ [ -2, 7, -4, -2, -2, 3 ], [ -3, 7, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -3, 7, -4, -1, -1, 3 ] ], 0.25 ] + ], + [ + [ [ [ -4, 8, -4, -1, -1, 3 ], [ -3, 7, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -3, 7, -4, -1, -1, 3 ] ], 0 ], + [ [ [ -4, 8, -4, -1, -1, 3 ], [ -3, 7, -4, -1, -3, 3 ], [ -2, 6, -4, -1, -1, 3 ], [ -3, 7, -4, -1, -1, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -3, 7, -4, -1, -3, 3 ], [ -2, 6, -4, -1, -1, 3 ], [ -3, 7, -4, -1, -1, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -3, 7, -4, -1, -3, 3 ], [ -2, 6, -4, -1, -1, 3 ], [ -2, 6, -4, -1, -2, 3 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -3, 7, -4, -1, -3, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -2, 6, -4, -1, -2, 3 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -3, 6, -4, -1, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -2, 6, -4, -1, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -2, 6, -4, -1, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -4, 7, -4, -1, -2, 3 ], [ -3, 6, -4, -1, -2, 3 ], [ -2, 6, -4, -1, -2, 3 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -3, 6, -4, -1, -2, 3 ], [ -2, 6, -4, -1, -2, 3 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -3, 6, -4, -1, -2, 3 ], [ -3, 8, -4, -1, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -3, 6, -4, -1, -2, 3 ], [ -2, 7, -5, -1, -2, 3 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -2, 6, -4, -2, -2, 3 ], [ -3, 6, -4, -1, -2, 3 ], [ -2, 7, -5, -1, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -2, 6, -4, -2, -2, 3 ], [ -2, 6, -5, -2, -2, 3 ], [ -2, 7, -5, -1, -2, 3 ] ], 0 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -2, 6, -4, -2, -2, 3 ], [ -2, 6, -5, -2, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -2, 6, -4, -2, -2, 3 ], [ -2, 7, -4, -1, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0.25 ], + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -2, 6, -4, -2, -2, 3 ], [ -1, 7, -4, -2, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, -1, -2, 3 ], [ -2, 6, -4, -2, -2, 3 ], [ -1, 7, -4, -2, -2, 3 ], [ -2, 8, -4, -2, -2, 3 ] ], 0 ], + [ [ [ -2, 7, -4, -2, -2, 3 ], [ -2, 6, -4, -2, -2, 3 ], [ -1, 7, -4, -2, -2, 3 ], [ -2, 8, -4, -2, -2, 3 ] ], 0.25 ], + [ [ [ -1, 5, -4, -2, -2, 3 ], [ -2, 6, -4, -2, -2, 3 ], [ -1, 7, -4, -2, -2, 3 ], [ -2, 8, -4, -2, -2, 3 ] ], 0.25 ], + [ [ [ -2, 7, -5, -2, -2, 3 ], [ -2, 6, -4, -2, -2, 3 ], [ -1, 7, -4, -2, -2, 3 ], [ -2, 8, -4, -2, -2, 3 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ -3, 7, -4, -1, -2, 3 ], [ -2, 6, -4, -2, -2, 3 ], [ -1, 7, -4, -2, -2, 3 ], [ -3, 7, -4, 0, -2, 3 ] ], + [ [ -3, 7, -4, -1, -2, 3 ], [ -2, 6, -4, -2, -2, 3 ], [ -1, 7, -4, -2, -2, 3 ], [ -2, 8, -4, -2, -2, 3 ] ], + [ [ -2, 7, -4, -2, -2, 3 ], [ -2, 6, -4, -2, -2, 3 ], [ -1, 7, -4, -2, -2, 3 ], [ -2, 8, -4, -2, -2, 3 ] ], + [ [ -1, 5, -4, -2, -2, 3 ], [ -2, 6, -4, -2, -2, 3 ], [ -1, 7, -4, -2, -2, 3 ], [ -2, 8, -4, -2, -2, 3 ] ], + [ [ -2, 7, -5, -2, -2, 3 ], [ -2, 6, -4, -2, -2, 3 ], [ -1, 7, -4, -2, -2, 3 ], [ -2, 8, -4, -2, -2, 3 ] ] +], +"cur_uid": "668ed417", +"ref_uid": "4cb92563", +"order_seed": 184148, +"dur_seed": 726356, +"motifs_seed": 697521, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 0, 3 ], [ 2, 1, 1 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 1, 2, 2 ], [ ] ], + [ [ 0, 1, 2 ], [ 3, 3, 3 ], [ ] ], + [ [ 2, 3, 0 ], [ 1, 1, 1, 1, 1 ], [ ] ], + [ [ 3, 1 ], [ 2, 0, 2 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 3, 2 ], [ 0, 1, 0, 1, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3, 2, 3, 2 ], [ ] ], + [ [ 1, 2, 0 ], [ 3, 3 ], [ ] ], + [ [ 2, 0 ], [ 3, 1, 1, 1, 1 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 3 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 2, 3, 0 ], [ 1, 1 ], [ ] ], + [ [ 2, 0, 1 ], [ 3, 3 ], [ ] ], + [ [ 0, 2, 1 ], [ 3, 3, 3, 3 ], [ ] ], + [ [ 0, 2, 1 ], [ 3, 3, 3 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 1, 0, 1 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 3, 0, 1, 1 ], [ ] ], + [ [ 0, 3, 1 ], [ 2, 2 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 3, 0, 2 ], [ ] ], + [ [ 1, 2 ], [ 3, 0, 3, 3 ], [ ] ], + [ [ 1, 2, 3 ], [ 0, 0, 0 ], [ ] ], + [ [ 3, 2 ], [ 0, 1, 1, 0, 1, 0 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 3 ], [ ] ], + [ [ 3, 1 ], [ 0, 2 ], [ ] ], + [ [ 1, 2 ], [ 3, 0, 3, 3 ], [ ] ], + [ [ 2, 1, 3 ], [ 0, 0, 0, 0 ], [ ] ], + [ [ 2, 3, 0 ], [ 1, 1, 1 ], [ ] ], + [ [ 0, 2 ], [ 3, 1, 3, 3, 3, 3 ], [ ] ], + [ [ 1, 3 ], [ 0, 2, 0, 0 ], [ ] ], + [ [ 1, 0, 3 ], [ 2, 2, 2, 2 ], [ ] ], + [ [ 0, 3 ], [ 1, 2, 1, 2 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 3, 2, 3, 2 ], [ ] ], + [ [ 1, 0, 2 ], [ 3, 3, 3, 3 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 1, 0 ], [ 3, 2, 3, 3, 3 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 3 ], [ 1, 0, 2, 1, 1, 2, 1 ], [ ] ], + [ [ 1, 3, 0 ], [ 2, 2, 2 ], [ ] ], + [ [ 2 ], [ 0, 1, 3, 1 ], [ ] ], + [ [ 2, 3, 0 ], [ 1, 1 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 3, 2, 0 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 0, 3, 3 ], [ ] ], + [ [ 3, 1 ], [ 0, 2, 0 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 1, 2, 1, 3 ], [ ] ], + [ [ 0, 2 ], [ 3, 1 ], [ ] ], + [ [ 1, 0 ], [ 2, 3, 2, 2 ], [ ] ], + [ [ 2, 1 ], [ 3, 0, 0, 0 ], [ ] ] +], +"sus_weights": [ 0.7, 0.48, 0.49 ], +"order_size": [ 49, 49.489795918367 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/690ef677/690ef677_code.scd b/resources/string_quartet_3_rise/690ef677/690ef677_code.scd new file mode 100644 index 0000000..e1a9d92 --- /dev/null +++ b/resources/string_quartet_3_rise/690ef677/690ef677_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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"], {(62.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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/690ef677/690ef677_mus_model.json b/resources/string_quartet_3_rise/690ef677/690ef677_mus_model.json new file mode 100644 index 0000000..6e0eed5 --- /dev/null +++ b/resources/string_quartet_3_rise/690ef677/690ef677_mus_model.json @@ -0,0 +1,438 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 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, -1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 2, -1, 0, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 2, -1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 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 ], + [ [ [ 0, 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, 0, 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, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 1, 1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 1, 1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 1, 1, 0, 0, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 1, 1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 1, 1, 0, 0, 0, -1 ], [ 0, 1, 0, 0, -1, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 1, 1, 0, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 1, 0, 0, 0, -1 ], [ 0, 1, 0, 0, -1, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 2, 0, 0, 0, -1, 0 ] ], 0 ], + [ [ [ 1, 1, 0, 0, 0, -1 ], [ 0, 1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 2, 0, 0, 0, -1, 0 ] ], 0 ], + [ [ [ 1, 0, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 2, 0, 0, 0, -1, 0 ] ], 0.25 ], + [ [ [ 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.25 ] + ], + [ + [ [ [ 1, 0, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 1, 0, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 1, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, -1, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 0, 0, 0, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ] ], 0.25 ], + [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 1 ] ], 0 ], + [ [ [ 0, 2, 0, 0, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 1 ] ], 0.25 ] + ], + [ + [ [ [ 0, 2, 0, 0, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 0, 2, 1, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 1 ] ], 0 ], + [ [ [ 0, 2, 0, 0, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 0, 2, 1, 0, -1, 0 ], [ 1, 2, 0, -1, -1, 0 ] ], 0.25 ], + [ [ [ -1, 3, 0, 0, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 0, 2, 1, 0, -1, 0 ], [ 1, 2, 0, -1, -1, 0 ] ], 0 ], + [ [ [ -1, 3, 0, 0, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 1, 2, 0, 0, -1, -1 ], [ 1, 2, 0, -1, -1, 0 ] ], 0.25 ], + [ [ [ -1, 3, 0, 0, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 1, 2, 0, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 3, 0, 0, -1, 0 ], [ 0, 2, 0, -1, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 1, 2, 0, -1, -1, 0 ] ], 0.25 ], + [ [ [ -1, 2, 0, 0, 0, 0 ], [ 0, 2, 0, -1, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 1, 2, 0, -1, -1, 0 ] ], 0 ], + [ [ [ -1, 2, 0, 0, 0, 0 ], [ 0, 2, 0, -1, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 1, 2, 0, 0, -1, -1 ] ], 0.25 ], + [ [ [ -1, 2, 0, 0, 0, 0 ], [ 0, 2, 0, -1, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 1, 1, 0, 0, -1, 0 ] ], 0.25 ], + [ [ [ -1, 2, 0, 0, 0, 0 ], [ 0, 2, 0, -1, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 0, 3, 0, 0, -1, 0 ] ], 0.25 ], + [ [ [ -1, 2, 0, 0, 0, 0 ], [ 0, 2, 0, -1, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 0, 2, 0, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 2, 0, 0, 0, 0 ], [ 0, 2, 0, -1, -1, 0 ], [ 0, 2, 0, -1, -1, 1 ], [ 0, 2, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 0, 2, 0, -1, -1, 0 ], [ 0, 2, 0, -1, -1, 1 ], [ 0, 2, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 0, 2, 0, -1, -1, 0 ], [ 0, 2, 0, -1, -1, 1 ], [ 2, 1, 0, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 0, 2, 0, -1, -1, 0 ], [ 0, 2, 0, -1, -1, 1 ], [ 2, 2, 1, -2, -1, 0 ] ], 0 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 1 ], [ 0, 2, 0, -1, -1, 1 ], [ 2, 2, 1, -2, -1, 0 ] ], 0 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 1 ], [ 1, 2, 0, -2, -1, 1 ], [ 2, 2, 1, -2, -1, 0 ] ], 0.25 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 1 ], [ 2, 2, -1, -2, -1, 0 ], [ 2, 2, 1, -2, -1, 0 ] ], 0.25 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 1 ], [ 1, 3, 0, -2, -1, 0 ], [ 2, 2, 1, -2, -1, 0 ] ], 0 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 1 ], [ 1, 3, 0, -2, -1, 0 ], [ 3, 1, 0, -2, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 1 ], [ 2, 1, 0, -2, -1, 0 ], [ 3, 1, 0, -2, -1, 0 ] ], 0 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 1, 1, 0, -2, -1, 0 ], [ 2, 1, 0, -2, -1, 0 ], [ 3, 1, 0, -2, -1, 0 ] ], 0 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 1, 1, 0, -2, -1, 0 ], [ 2, 1, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0.25 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 1, 1, 0, -2, -1, 0 ], [ 2, 1, 0, -2, -1, 0 ], [ 1, 2, 0, -1, -1, 0 ] ], 0.25 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 0, 2, 0, -2, -1, 0 ], [ 2, 1, 0, -2, -1, 0 ], [ 1, 2, 0, -1, -1, 0 ] ], 0.25 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 1, 2, 0, -3, -1, 0 ], [ 2, 1, 0, -2, -1, 0 ], [ 1, 2, 0, -1, -1, 0 ] ], 0 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 1, 2, 0, -3, -1, 0 ], [ 1, 3, 0, -2, -1, 0 ], [ 1, 2, 0, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 1, 2, 0, -3, -1, 0 ], [ 2, 2, 0, -2, -2, 0 ], [ 1, 2, 0, -1, -1, 0 ] ], 0 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 1, 2, 0, -3, -1, 0 ], [ 2, 2, 0, -2, -2, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0.25 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 0, 2, 1, -2, -1, 0 ], [ 2, 2, 0, -2, -2, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0.25 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 1, 1, 0, -2, -1, 0 ], [ 2, 2, 0, -2, -2, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 1, 2, 0, -2, -2, 0 ], [ 2, 2, 0, -2, -2, 0 ], [ 2, 2, 0, -2, -1, 0 ] ], 0 ], + [ [ [ 1, 2, 0, -2, -1, 0 ], [ 1, 2, 0, -2, -2, 0 ], [ 2, 2, 0, -2, -2, 0 ], [ 3, 2, 0, -2, -2, 0 ] ], 0 ], + [ [ [ 1, 3, 0, -2, -2, 0 ], [ 1, 2, 0, -2, -2, 0 ], [ 2, 2, 0, -2, -2, 0 ], [ 3, 2, 0, -2, -2, 0 ] ], 0.25 ], + [ [ [ 1, 3, 0, -2, -2, 0 ], [ 2, 2, 0, -3, -2, 0 ], [ 2, 2, 0, -2, -2, 0 ], [ 3, 2, 0, -2, -2, 0 ] ], 0 ], + [ [ [ 2, 2, -1, -2, -2, 0 ], [ 2, 2, 0, -3, -2, 0 ], [ 2, 2, 0, -2, -2, 0 ], [ 3, 2, 0, -2, -2, 0 ] ], 0.25 ], + [ [ [ 2, 2, -1, -2, -2, 0 ], [ 2, 2, 0, -2, -2, -1 ], [ 2, 2, 0, -2, -2, 0 ], [ 3, 2, 0, -2, -2, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 2, 0, -1, -2, 0 ], [ 2, 2, 0, -2, -2, -1 ], [ 2, 2, 0, -2, -2, 0 ], [ 3, 2, 0, -2, -2, 0 ] ], 0 ], + [ [ [ 1, 2, 0, -1, -2, 0 ], [ 2, 1, 0, -2, -2, 0 ], [ 2, 2, 0, -2, -2, 0 ], [ 3, 2, 0, -2, -2, 0 ] ], 0 ], + [ [ [ 1, 2, 0, -1, -2, 0 ], [ 2, 1, 0, -2, -2, 0 ], [ 3, 2, 0, -3, -2, 0 ], [ 3, 2, 0, -2, -2, 0 ] ], 0.25 ], + [ [ [ 2, 2, 0, -2, -2, 0 ], [ 2, 1, 0, -2, -2, 0 ], [ 3, 2, 0, -3, -2, 0 ], [ 3, 2, 0, -2, -2, 0 ] ], 0.25 ] + ], + [ + [ [ [ 2, 2, 0, -2, -2, 0 ], [ 2, 1, 0, -2, -2, 0 ], [ 3, 2, 0, -3, -2, 0 ], [ 1, 2, 0, -2, -2, 0 ] ], 0 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 2, 1, 0, -2, -2, 0 ], [ 3, 2, 0, -3, -2, 0 ], [ 1, 2, 0, -2, -2, 0 ] ], 0 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 2, 1, 0, -2, -2, 0 ], [ 2, 1, -1, -2, -2, 0 ], [ 1, 2, 0, -2, -2, 0 ] ], 0.25 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 2, 1, 0, -2, -2, 0 ], [ 1, 1, 0, -1, -2, 0 ], [ 1, 2, 0, -2, -2, 0 ] ], 0.25 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 2, 1, 0, -2, -2, 0 ], [ 2, 0, 0, -2, -2, 0 ], [ 1, 2, 0, -2, -2, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 2, 1, 0, -2, -2, 0 ], [ 2, 0, 0, -2, -2, 0 ], [ 2, 1, -1, -2, -2, 0 ] ], 0 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 2, 1, 0, -2, -2, 0 ], [ 1, 1, -1, -2, -2, 1 ], [ 2, 1, -1, -2, -2, 0 ] ], 0 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 3, 0, -1, -2, -2, 0 ], [ 1, 1, -1, -2, -2, 1 ], [ 2, 1, -1, -2, -2, 0 ] ], 0.25 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 2, 2, -1, -2, -2, 0 ], [ 1, 1, -1, -2, -2, 1 ], [ 2, 1, -1, -2, -2, 0 ] ], 0 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 2, 2, -1, -2, -2, 0 ], [ 1, 1, -1, -1, -2, 0 ], [ 2, 1, -1, -2, -2, 0 ] ], 0 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 2, 2, -1, -2, -2, 0 ], [ 1, 1, -1, -1, -2, 0 ], [ 3, 1, -1, -3, -2, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 3, 1, -2, -2, -2, 0 ], [ 1, 1, -1, -1, -2, 0 ], [ 3, 1, -1, -3, -2, 0 ] ], 0.25 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 3, 1, -2, -2, -2, 0 ], [ 1, 1, -1, -1, -2, 0 ], [ 2, 1, 0, -2, -2, 0 ] ], 0.25 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 3, 1, -2, -2, -2, 0 ], [ 2, 1, -1, -2, -2, 0 ], [ 2, 1, 0, -2, -2, 0 ] ], 0 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 3, 1, -2, -2, -2, 0 ], [ 2, 1, -1, -2, -2, 0 ], [ 3, 0, -1, -2, -2, 0 ] ], 0.25 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 3, 1, -2, -2, -2, 0 ], [ 4, 0, -1, -2, -2, 0 ], [ 3, 0, -1, -2, -2, 0 ] ], 0 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 3, 1, -2, -2, -2, 0 ], [ 4, 0, -1, -2, -2, 0 ], [ 2, 2, -1, -2, -2, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 3, 1, -2, -2, -2, 0 ], [ 3, 2, -1, -2, -2, 0 ], [ 2, 2, -1, -2, -2, 0 ] ], 0.25 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 3, 1, -2, -2, -2, 0 ], [ 3, 2, -1, -2, -2, 0 ], [ 3, 1, -1, -2, -3, 0 ] ], 0 ], + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 2, 2, -1, -2, -2, 0 ], [ 3, 2, -1, -2, -2, 0 ], [ 3, 1, -1, -2, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, 1, -1, -2, -2, 0 ], [ 2, 1, -1, -2, -2, 0 ], [ 3, 2, -1, -2, -2, 0 ], [ 3, 1, -1, -2, -3, 0 ] ], 0 ], + [ [ [ 3, 2, -1, -2, -3, 0 ], [ 2, 1, -1, -2, -2, 0 ], [ 3, 2, -1, -2, -2, 0 ], [ 3, 1, -1, -2, -3, 0 ] ], 0 ], + [ [ [ 3, 2, -1, -2, -3, 0 ], [ 2, 1, -1, -2, -2, 0 ], [ 4, 1, -1, -2, -3, 0 ], [ 3, 1, -1, -2, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, 2, -1, -2, -3, 0 ], [ 2, 1, -1, -2, -2, 0 ], [ 4, 1, -1, -2, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 3, 1, -1, -2, -3, 1 ], [ 2, 1, -1, -2, -2, 0 ], [ 4, 1, -1, -2, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 3, 1, -1, -2, -3, 1 ], [ 2, 2, -1, -2, -3, 0 ], [ 4, 1, -1, -2, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, 2, -1, -2, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 4, 1, -1, -2, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 3, 2, -1, -2, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 3, 2, 0, -2, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 3, 2, -1, -2, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 3, 2, 0, -2, -3, 0 ], [ 3, 2, -2, -2, -3, 0 ] ], 0.25 ], + [ [ [ 3, 2, -1, -2, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 3, 2, -1, -2, -2, 0 ], [ 3, 2, -2, -2, -3, 0 ] ], 0 ], + [ [ [ 2, 3, -1, -2, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 3, 2, -1, -2, -2, 0 ], [ 3, 2, -2, -2, -3, 0 ] ], 0.25 ], + [ [ [ 2, 2, -1, -2, -3, 1 ], [ 2, 2, -1, -2, -3, 0 ], [ 3, 2, -1, -2, -2, 0 ], [ 3, 2, -2, -2, -3, 0 ] ], 0.25 ], + [ [ [ 2, 2, -1, -1, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 3, 2, -1, -2, -2, 0 ], [ 3, 2, -2, -2, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 2, 2, -1, -1, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 4, 1, -1, -2, -3, 0 ], [ 3, 2, -2, -2, -3, 0 ] ], 0 ], + [ [ [ 2, 2, -1, -1, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 4, 1, -1, -2, -3, 0 ], [ 2, 3, -1, -2, -3, 0 ] ], 0 ], + [ [ [ 3, 2, -1, -2, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 4, 1, -1, -2, -3, 0 ], [ 2, 3, -1, -2, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 3, -1, -2, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 4, 1, -1, -2, -3, 0 ], [ 2, 3, -1, -2, -3, 0 ] ], 0 ], + [ [ [ 1, 3, -1, -2, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 3, 2, -1, -2, -3, 0 ], [ 2, 3, -1, -2, -3, 0 ] ], 0.25 ], + [ [ [ 1, 3, -1, -2, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 3, 2, -1, -2, -3, 0 ], [ 3, 1, -1, -2, -3, 0 ] ], 0.25 ], + [ [ [ 1, 3, -1, -2, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 3, 2, -1, -2, -3, 0 ], [ 2, 2, 0, -2, -3, 0 ] ], 0.25 ], + [ [ [ 1, 3, -1, -2, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 3, 2, -1, -2, -3, 0 ], [ 3, 3, -1, -2, -3, 0 ] ], 0 ], + [ [ [ 2, 2, -2, -2, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 3, 2, -1, -2, -3, 0 ], [ 3, 3, -1, -2, -3, 0 ] ], 0.25 ], + [ [ [ 2, 2, -2, -2, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 3, 2, -1, -2, -3, 0 ], [ 4, 2, -2, -2, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 2, 2, -2, -2, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 4, 1, -2, -2, -3, 0 ], [ 4, 2, -2, -2, -3, 0 ] ], 0 ], + [ [ [ 2, 1, -2, -2, -3, 0 ], [ 2, 2, -1, -2, -3, 0 ], [ 4, 1, -2, -2, -3, 0 ], [ 4, 2, -2, -2, -3, 0 ] ], 0 ], + [ [ [ 2, 1, -2, -2, -3, 0 ], [ 3, 1, -2, -2, -3, 0 ], [ 4, 1, -2, -2, -3, 0 ], [ 4, 2, -2, -2, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 2, 1, -2, -2, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 4, 1, -2, -2, -3, 0 ], [ 4, 2, -2, -2, -3, 0 ] ], 0 ], + [ [ [ 2, 1, -2, -2, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 4, 1, -2, -2, -3, 0 ], [ 5, 1, -3, -2, -3, 0 ] ], 0 ], + [ [ [ 2, 1, -3, -2, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 4, 1, -2, -2, -3, 0 ], [ 5, 1, -3, -2, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, 1, -3, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 4, 1, -2, -2, -3, 0 ], [ 5, 1, -3, -2, -3, 0 ] ], 0 ], + [ [ [ 3, 1, -3, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 4, 1, -2, -2, -3, 0 ], [ 6, 0, -2, -3, -3, 0 ] ], 0 ], + [ [ [ 3, 1, -3, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ], [ 6, 0, -2, -3, -3, 0 ] ], 0.25 ], + [ [ [ 5, 0, -2, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ], [ 6, 0, -2, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, 0, -2, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ], [ 6, 0, -2, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -2, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ], [ 6, 0, -2, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -2, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 0 ], [ 6, 0, -2, -4, -3, 0 ], [ 6, 0, -2, -3, -3, 0 ] ], 0.25 ], + [ [ [ 5, 0, -2, -4, -3, 0 ], [ 5, 0, -3, -3, -3, 0 ], [ 6, 0, -2, -4, -3, 0 ], [ 6, 0, -2, -3, -3, 0 ] ], 0.25 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 0 ], [ 6, 0, -2, -4, -3, 0 ], [ 6, 0, -2, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 0 ], [ 5, 0, -2, -3, -3, 0 ], [ 6, 0, -2, -3, -3, 0 ] ], 0.25 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 0 ], [ 5, 0, -1, -3, -3, 0 ], [ 6, 0, -2, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 0 ], [ 5, 0, -1, -3, -3, 0 ], [ 5, 1, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -1, -2, -3, 0 ], [ 5, 1, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 4, 0, -1, -3, -2, 0 ], [ 4, 0, -1, -2, -3, 0 ], [ 5, 1, -1, -3, -3, 0 ] ], 0.25 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ], [ 4, 0, -1, -2, -3, 0 ], [ 5, 1, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ], [ 4, 0, -1, -2, -3, 0 ], [ 5, 0, -1, -3, -2, 0 ] ], 0.25 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ], [ 5, 0, -2, -3, -3, 0 ], [ 5, 0, -1, -3, -2, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ], [ 5, 0, -2, -3, -3, 0 ], [ 6, -1, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 5, -1, -1, -3, -3, 0 ], [ 5, 0, -2, -3, -3, 0 ], [ 6, -1, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 5, -1, -1, -3, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ], [ 6, -1, -1, -3, -3, 0 ] ], 0.25 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 4, 0, 0, -3, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ], [ 6, -1, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 4, 0, 0, -3, -3, 0 ], [ 5, -1, -1, -3, -3, 0 ], [ 6, -1, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 4, 0, 0, -3, -3, 0 ], [ 5, -1, -1, -3, -3, 0 ], [ 5, 1, -1, -3, -3, 0 ] ], 0.25 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 4, 0, 0, -3, -3, 0 ], [ 5, -1, -1, -3, -3, 0 ], [ 6, 0, -2, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 4, 0, 0, -3, -3, 0 ], [ 5, -1, -1, -3, -3, 0 ], [ 5, 0, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 4, -1, -1, -3, -3, 0 ], [ 5, -1, -1, -3, -3, 0 ], [ 5, 0, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 4, -1, -1, -3, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ], [ 5, 0, -1, -3, -3, 0 ] ], 0.25 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 3, 1, -1, -3, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ], [ 5, 0, -1, -3, -3, 0 ] ], 0.25 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ], [ 5, 0, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ], [ 5, 0, -2, -3, -3, 0 ], [ 5, 0, -1, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, 0, -1, -3, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 5, 0, -1, -3, -3, 0 ] ], 0.25 ], + [ [ [ 5, 0, -2, -3, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 5, 0, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 5, 0, -2, -3, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 6, 0, -2, -4, -3, 0 ] ], 0.25 ], + [ [ [ 4, 0, -2, -4, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 6, 0, -2, -4, -3, 0 ] ], 0.25 ], + [ [ [ 4, 0, -2, -4, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 5, 0, -2, -3, -3, 0 ] ], 0 ], + [ [ [ 3, 0, -2, -3, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 5, 0, -2, -3, -3, 0 ] ], 0.25 ], + [ [ [ 2, 1, -2, -3, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 5, 0, -2, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, 1, -2, -3, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 5, 0, -2, -3, -3, 0 ] ], 0 ], + [ [ [ 3, 1, -2, -3, -3, 0 ], [ 3, 1, -1, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 5, 0, -2, -3, -3, 0 ] ], 0 ], + [ [ [ 3, 1, -2, -3, -3, 0 ], [ 3, 1, -1, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ] ], 0.25 ], + [ [ [ 2, 1, -1, -3, -3, 0 ], [ 3, 1, -1, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ] ], 0.25 ], + [ [ [ 2, 1, -1, -3, -3, 0 ], [ 3, 1, -2, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ] ], 0 ], + [ [ [ 3, 0, -2, -3, -3, 0 ], [ 3, 1, -2, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 4, 1, -1, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, 0, -2, -3, -3, 0 ], [ 3, 1, -2, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ] ], 0 ], + [ [ [ 3, 0, -2, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 4, 1, -2, -3, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ] ], 0 ], + [ [ [ 3, 0, -2, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ] ], 0.25 ], + [ [ [ 3, 0, -2, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 3, 0, -2, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 0 ], [ 5, 1, -2, -3, -3, 0 ] ], 0 ], + [ [ [ 3, 0, -2, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 4, 0, -2, -2, -3, 0 ], [ 5, 1, -2, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, 0, -2, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 4, 0, -2, -2, -3, 0 ], [ 5, 0, -3, -2, -3, 0 ] ], 0 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 4, 0, -2, -2, -3, 0 ], [ 5, 0, -3, -2, -3, 0 ] ], 0 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 0, -2, -3, -3, 0 ], [ 5, 0, -3, -2, -3, 0 ] ], 0.25 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ], [ 5, 0, -3, -2, -3, 0 ] ], 0 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 5, -1, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 4, 1, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, 1, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 5, 0, -4, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 5, 0, -4, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 5, 0, -4, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ], [ 4, 1, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ], [ 4, 1, -3, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 1 ] ], 0.25 ], + [ [ [ 3, 1, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 1 ] ], 0.25 ], + [ [ [ 3, 1, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 1 ], [ 4, 0, -3, -3, -3, 1 ] ], 0 ], + [ [ [ 3, 0, -3, -3, -3, 1 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 1 ], [ 4, 0, -3, -3, -3, 1 ] ], 0 ], + [ [ [ 3, 0, -3, -3, -3, 1 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 1 ], [ 4, 0, -3, -2, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, 0, -3, -3, -3, 1 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 1 ], [ 4, 0, -3, -3, -3, 1 ] ], 0 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 1 ], [ 4, 0, -3, -3, -3, 1 ] ], 0 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 1 ] ], 0.25 ] + ], + [ + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ], [ 4, 1, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ], [ 4, 1, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 5, 0, -3, -4, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ], [ 4, 1, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ], [ 4, 1, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 5, -1, -3, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ], [ 4, 1, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 5, -1, -3, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ], [ 4, 1, -3, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 5, -1, -3, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 6, -2, -3, -3, -3, 0 ], [ 5, -1, -3, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 6, -2, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 4, 1, -3, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 0, -4, -3, -3, 0 ], [ 5, 1, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 0, -4, -3, -3, 0 ], [ 6, 0, -4, -3, -3, 0 ] ], 0.25 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, -1, -3, -3, -3, 0 ], [ 6, 0, -4, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ], [ 6, 0, -4, -3, -3, 0 ] ], 0 ], + [ [ [ 5, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ], [ 5, 0, -3, -2, -3, 0 ] ], 0.25 ], + [ [ [ 4, 0, -3, -2, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 4, 0, -2, -3, -3, 0 ], [ 5, 0, -3, -2, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -3, -2, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 4, 0, -3, -3, -2, 0 ], [ 5, 0, -3, -2, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, 0, -3, -2, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 4, 1, -3, -3, -3, 0 ], [ 5, 0, -3, -2, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -3, -2, -3, 0 ], [ 4, 0, -3, -3, -3, 0 ], [ 4, 1, -3, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -3, -3, -3, 1 ], [ 4, 0, -3, -3, -3, 0 ], [ 4, 1, -3, -3, -3, 0 ], [ 6, 0, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 4, 0, -3, -3, -3, 1 ], [ 4, 0, -3, -3, -3, 0 ], [ 4, 1, -3, -3, -3, 0 ], [ 6, 0, -3, -4, -3, 0 ] ], 0.25 ], + [ [ [ 4, 0, -3, -3, -3, 1 ], [ 4, 0, -3, -3, -3, 0 ], [ 4, 1, -3, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -3, -3, -3, 1 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 0, -4, -3, -3, 0 ], [ 5, 0, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 4, 0, -3, -3, -3, 1 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, 0, -4, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, 0, -3, -3, -3, 1 ], [ 4, 0, -3, -3, -3, 0 ], [ 5, -1, -2, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 4, 0, -3, -3, -3, 1 ], [ 4, -1, -3, -3, -3, 1 ], [ 5, -1, -2, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 6, -2, -3, -3, -3, 0 ], [ 4, -1, -3, -3, -3, 1 ], [ 5, -1, -2, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 6, -2, -3, -3, -3, 0 ], [ 4, -1, -3, -2, -3, 0 ], [ 5, -1, -2, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 6, -2, -3, -3, -3, 0 ], [ 5, -2, -3, -3, -3, 0 ], [ 5, -1, -2, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 6, -2, -3, -3, -3, 0 ], [ 5, -2, -3, -3, -3, 0 ], [ 7, -2, -3, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 6, -2, -3, -3, -3, 0 ], [ 5, -2, -3, -3, -3, 0 ], [ 5, -1, -3, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 4, -1, -3, -3, -3, 0 ], [ 5, -2, -3, -3, -3, 0 ], [ 5, -1, -3, -3, -3, 0 ], [ 6, -1, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 4, -1, -3, -3, -3, 0 ], [ 5, -2, -3, -3, -3, 0 ], [ 5, -1, -3, -3, -3, 0 ], [ 7, -2, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 4, -1, -3, -3, -3, 0 ], [ 5, -2, -3, -3, -3, 0 ], [ 6, -2, -4, -3, -3, 0 ], [ 7, -2, -3, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, -1, -3, -3, -3, 0 ], [ 5, -2, -3, -3, -3, 0 ], [ 6, -2, -3, -3, -3, 0 ], [ 7, -2, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 4, -2, -3, -3, -3, 0 ], [ 5, -2, -3, -3, -3, 0 ], [ 6, -2, -3, -3, -3, 0 ], [ 7, -2, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 4, -2, -3, -3, -3, 0 ], [ 6, -2, -3, -4, -3, 0 ], [ 6, -2, -3, -3, -3, 0 ], [ 7, -2, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 4, -2, -3, -3, -3, 0 ], [ 5, -2, -2, -3, -3, 0 ], [ 6, -2, -3, -3, -3, 0 ], [ 7, -2, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 4, -2, -3, -3, -3, 0 ], [ 5, -2, -2, -3, -3, 0 ], [ 7, -2, -3, -4, -3, 0 ], [ 7, -2, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 4, -2, -3, -3, -3, 0 ], [ 6, -3, -3, -3, -3, 0 ], [ 7, -2, -3, -4, -3, 0 ], [ 7, -2, -3, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, -2, -3, -3, -3, 0 ], [ 6, -2, -3, -3, -4, 0 ], [ 7, -2, -3, -4, -3, 0 ], [ 7, -2, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 4, -2, -3, -3, -3, 0 ], [ 6, -2, -3, -3, -4, 0 ], [ 6, -2, -2, -3, -3, 0 ], [ 7, -2, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 5, -2, -4, -3, -3, 0 ], [ 6, -2, -3, -3, -4, 0 ], [ 6, -2, -2, -3, -3, 0 ], [ 7, -2, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 5, -2, -4, -3, -3, 0 ], [ 6, -2, -3, -3, -4, 0 ], [ 7, -3, -3, -3, -3, 0 ], [ 7, -2, -3, -3, -3, 0 ] ], 0 ], + [ [ [ 5, -2, -3, -3, -4, 0 ], [ 6, -2, -3, -3, -4, 0 ], [ 7, -3, -3, -3, -3, 0 ], [ 7, -2, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 5, -2, -3, -3, -4, 0 ], [ 6, -2, -3, -3, -4, 0 ], [ 7, -2, -3, -3, -4, 0 ], [ 7, -2, -3, -3, -3, 0 ] ], 0.25 ] + ], + [ + [ [ [ 5, -2, -3, -3, -4, 0 ], [ 6, -2, -3, -3, -4, 0 ], [ 8, -2, -3, -4, -4, 0 ], [ 7, -2, -3, -3, -3, 0 ] ], 0.25 ], + [ [ [ 5, -2, -3, -3, -4, 0 ], [ 6, -2, -3, -3, -4, 0 ], [ 8, -2, -3, -4, -4, 0 ], [ 7, -2, -3, -3, -4, 0 ] ], 0 ], + [ [ [ 5, -2, -3, -3, -4, 0 ], [ 7, -2, -3, -4, -4, 0 ], [ 8, -2, -3, -4, -4, 0 ], [ 7, -2, -3, -3, -4, 0 ] ], 0 ], + [ [ [ 5, -2, -3, -3, -4, 0 ], [ 7, -2, -3, -4, -4, 0 ], [ 7, -2, -2, -3, -4, 0 ], [ 7, -2, -3, -3, -4, 0 ] ], 0.25 ], + [ [ [ 5, -2, -3, -3, -4, 0 ], [ 7, -2, -3, -4, -4, 0 ], [ 7, -2, -2, -3, -4, 0 ], [ 8, -2, -3, -4, -4, 0 ] ], 0 ], + [ [ [ 5, -2, -3, -3, -4, 0 ], [ 6, -2, -2, -3, -4, 0 ], [ 7, -2, -2, -3, -4, 0 ], [ 8, -2, -3, -4, -4, 0 ] ], 0.25 ] + ], + [ + [ [ [ 5, -2, -3, -3, -4, 0 ], [ 8, -2, -3, -4, -4, -1 ], [ 7, -2, -2, -3, -4, 0 ], [ 8, -2, -3, -4, -4, 0 ] ], 0 ], + [ [ [ 5, -2, -3, -3, -4, 0 ], [ 8, -2, -3, -4, -4, -1 ], [ 9, -2, -3, -4, -4, -1 ], [ 8, -2, -3, -4, -4, 0 ] ], 0 ], + [ [ [ 6, -2, -3, -4, -4, -1 ], [ 8, -2, -3, -4, -4, -1 ], [ 9, -2, -3, -4, -4, -1 ], [ 8, -2, -3, -4, -4, 0 ] ], 0.25 ], + [ [ [ 6, -2, -3, -4, -4, -1 ], [ 8, -3, -3, -4, -4, 0 ], [ 9, -2, -3, -4, -4, -1 ], [ 8, -2, -3, -4, -4, 0 ] ], 0.25 ], + [ [ [ 6, -2, -3, -4, -4, -1 ], [ 8, -3, -3, -4, -4, 0 ], [ 9, -3, -3, -4, -4, 0 ], [ 8, -2, -3, -4, -4, 0 ] ], 0 ], + [ [ [ 6, -2, -3, -4, -4, -1 ], [ 7, -2, -3, -4, -4, 0 ], [ 9, -3, -3, -4, -4, 0 ], [ 8, -2, -3, -4, -4, 0 ] ], 0.25 ] + ], + [ + [ [ [ 6, -2, -3, -4, -4, -1 ], [ 7, -2, -3, -4, -4, -1 ], [ 9, -3, -3, -4, -4, 0 ], [ 8, -2, -3, -4, -4, 0 ] ], 0 ], + [ [ [ 6, -2, -3, -4, -4, -1 ], [ 7, -2, -3, -4, -4, -1 ], [ 8, -2, -3, -4, -4, -1 ], [ 8, -2, -3, -4, -4, 0 ] ], 0 ], + [ [ [ 6, -2, -3, -4, -4, -1 ], [ 7, -2, -3, -4, -4, -1 ], [ 8, -2, -3, -4, -4, -1 ], [ 8, -1, -3, -4, -4, -1 ] ], 0.25 ], + [ [ [ 6, -2, -3, -4, -4, -1 ], [ 7, -2, -3, -4, -4, -1 ], [ 8, -2, -3, -4, -4, -1 ], [ 9, -2, -3, -4, -4, -1 ] ], 0.25 ], + [ [ [ 6, -2, -3, -4, -4, -1 ], [ 7, -2, -3, -4, -4, -1 ], [ 8, -2, -3, -4, -4, -1 ], [ 7, -1, -3, -4, -4, -1 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ 6, -2, -3, -4, -4, -1 ], [ 7, -2, -3, -4, -4, -1 ], [ 9, -3, -3, -4, -4, 0 ], [ 8, -2, -3, -4, -4, 0 ] ], + [ [ 6, -2, -3, -4, -4, -1 ], [ 7, -2, -3, -4, -4, -1 ], [ 8, -2, -3, -4, -4, -1 ], [ 8, -2, -3, -4, -4, 0 ] ], + [ [ 6, -2, -3, -4, -4, -1 ], [ 7, -2, -3, -4, -4, -1 ], [ 8, -2, -3, -4, -4, -1 ], [ 8, -1, -3, -4, -4, -1 ] ], + [ [ 6, -2, -3, -4, -4, -1 ], [ 7, -2, -3, -4, -4, -1 ], [ 8, -2, -3, -4, -4, -1 ], [ 9, -2, -3, -4, -4, -1 ] ], + [ [ 6, -2, -3, -4, -4, -1 ], [ 7, -2, -3, -4, -4, -1 ], [ 8, -2, -3, -4, -4, -1 ], [ 7, -1, -3, -4, -4, -1 ] ] +], +"cur_uid": "690ef677", +"ref_uid": "nil", +"order_seed": 889455, +"dur_seed": 788568, +"motifs_seed": 231761, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 1 ], [ 2, 3, 0, 0, 0, 3, 3 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 0, 0 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 3 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 1, 1, 1 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 3, 0 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 2, 2 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 3, 3, 3 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 2, 2, 3 ], [ ] ], + [ [ 0 ], [ 2, 1, 3, 3, 1, 1, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1, 1 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 1, 0, 1 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 0 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 2, 2 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 1, 2, 3 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 3, 2, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 2, 0, 0, 0 ], [ ] ], + [ [ 1 ], [ 2, 3, 0 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 3, 3, 0, 3 ], [ ] ], + [ [ 3 ], [ 2, 0, 1 ], [ ] ], + [ [ 2 ], [ 1, 3, 0 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 0 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 0, 0, 2, 2 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 1, 3, 2 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 1, 2, 3, 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 1, 1, 2 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 0, 3, 0, 0 ], [ ] ], + [ [ 2 ], [ 0, 1, 3, 0, 1, 0 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 3, 3, 2 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 2, 3, 0, 0 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 3, 0 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 0, 3 ], [ ] ], + [ [ 1 ], [ 3, 0, 2 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 1, 1, 2 ], [ ] ], + [ [ 2 ], [ 3, 0, 1 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 2, 2, 3, 2 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 2 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 3, 3, 2, 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 1, 1, 2 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 2 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 1, 2, 1 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 2, 0, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1, 2, 3, 1 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 1, 2, 1 ], [ ] ], + [ [ 0 ], [ 1, 2, 3, 3, 3 ], [ ] ] +], +"sus_weights": [ 0.69, 0, 0 ], +"order_size": [ 49.489795918367, 49.489795918367 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/690ef677/lilypond/part_I.ly b/resources/string_quartet_3_rise/690ef677/lilypond/part_I.ly new file mode 100644 index 0000000..dc8ef0e --- /dev/null +++ b/resources/string_quartet_3_rise/690ef677/lilypond/part_I.ly @@ -0,0 +1,36 @@ +{ + { g4^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} a8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}[ g''8^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] a''2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { a''8[ gis''8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] e''8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ d''8^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ d''2 ~ } + \bar "|" + { d''4 b'8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ c''8^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }}] cis''2^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} } + \bar "|" + { d''8^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }}[ e''8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] fis''8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}[ e''8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ e''8[ fis''8^\markup { \pad-markup #0.2 "-18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] g''4^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} } + \bar "|" + { gis''8^\markup { \pad-markup #0.2 "+13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}[ dis''8^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] cis''4^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ cis''8[ dis''8^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ dis''4 } + \bar "|" + { ais''2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ ais''8[ ais8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ ais4 } + \bar "|" + { b8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ cis'8^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}] ~ cis'8[ dis'8^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] e'8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}[ fis'8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ fis'8[ f'8^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] ~ } + \bar "|" + { f'8[ gis'8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }}] gis'2^\markup { \pad-markup #0.2 "+40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} g'4^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} } + \bar "|" + { f'8^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}[ e'8^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}] g''8^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ gis''8^\markup { \pad-markup #0.2 "+40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ gis''8[ ais''8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] a''4^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { a''2 gis''8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ fis''8^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ fis''8[ fis''8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] } + \bar "|" + { gis''8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ a''8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] cis''2^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} b'4^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} } + \bar "|" + { a'4^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} gis'4^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ gis'8[ a8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] f''8^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ e''8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] } + \bar "|" + { d''8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}[ f''8^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ f''4 ~ f''8[ f'8^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] c'8^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ cis'8^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}] ~ } + \bar "|" + { cis'8[ d'8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}] cis'8^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ c'8^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ c'4 ~ c'8[ f''8^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] } + \bar "|" + { c''4^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} cis''4^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} d''4^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} f''8^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ g'8^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }}] } + \bar "|" + { f'8^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ ais'8^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] ~ ais'4 ~ ais'8[ dis''8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ dis''4 ~ } + \bar "|" + { dis''2. a'8^\markup { \pad-markup #0.2 "+25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ c''8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}]} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/690ef677/lilypond/part_II.ly b/resources/string_quartet_3_rise/690ef677/lilypond/part_II.ly new file mode 100644 index 0000000..511e09c --- /dev/null +++ b/resources/string_quartet_3_rise/690ef677/lilypond/part_II.ly @@ -0,0 +1,36 @@ +{ + { d''2^\markup { \pad-markup #0.2 "+0"} g4^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} a4^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a8[ gis8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ gis4 e''2^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { e''2 d''8^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}[ d''8^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }}] b'4^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b'2 a'4^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }} c''8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ b'8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] } + \bar "|" + { ais'8^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ gis'8^\markup { \pad-markup #0.2 "+13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ gis'4 ais'8^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ ais'8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] ~ ais'4 ~ } + \bar "|" + { ais'4 ~ ais'8[ c''8^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}] ~ c''8[ b8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] c'8^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}[ gis8^\markup { \pad-markup #0.2 "-40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] } + \bar "|" + { g8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}[ gis8^\markup { \pad-markup #0.2 "+44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ gis4 b8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ e''8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] fis''4^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} } + \bar "|" + { f''4^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} e''8^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}[ fis''8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ fis''4 f''8^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}[ c''8^\markup { \pad-markup #0.2 "+26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { c''2 cis''4^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} c''4^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } + \bar "|" + { b'4^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} a'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ cis''8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ais'4^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} a'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}[ gis'8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] } + \bar "|" + { fis'4^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} gis'4^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} a'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ e'8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ e'4 ~ } + \bar "|" + { e'2 ~ e'8[ f'8^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ f'8[ fis'8^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] } + \bar "|" + { a'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}[ ais'8^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ ais'4 c''2^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c''8[ cis''8^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] c''4^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} f''4^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ais'4^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} } + \bar "|" + { f''8^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ c'8^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] cis'8^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}[ ais8^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] a8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}[ ais8^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }}] c'4^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} } + \bar "|" + { cis'4^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} d'4^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} dis''8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ ais8^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] b8^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}[ dis'8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] } + \bar "|" + { f'4^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} g'8^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}[ gis'8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}] a'8^\markup { \pad-markup #0.2 "+25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ c''8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}] cis''4^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/690ef677/lilypond/part_III.ly b/resources/string_quartet_3_rise/690ef677/lilypond/part_III.ly new file mode 100644 index 0000000..4ae3c21 --- /dev/null +++ b/resources/string_quartet_3_rise/690ef677/lilypond/part_III.ly @@ -0,0 +1,36 @@ +{ + { d'2.^\markup { \pad-markup #0.2 "+0"} e'4^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }} ~ } + \bar "|" + { e'2 d'8^\markup { \pad-markup #0.2 "+0"}[ cis'8^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] c'8^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}[ gis8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] } + \bar "|" + { b2.^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ b8[ cis'8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { cis'2. c'4^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} ~ } + \bar "|" + { c'8[ gis8^\markup { \pad-markup #0.2 "+13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ gis8[ dis8^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] f4^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} g8^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}[ gis8^\markup { \pad-markup #0.2 "+13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] } + \bar "|" + { ais8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ c'8^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }}] cis'8^\markup { \pad-markup #0.2 "+23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }}[ dis'8^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }}] ~ dis'2 } + \bar "|" + { e'8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}[ fis'8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] g'2^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ g'8[ fis'8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] } + \bar "|" + { b8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ c'8^\markup { \pad-markup #0.2 "+26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] ~ c'2. ~ } + \bar "|" + { c'2 cis'8^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ e'8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}] ~ e'4 } + \bar "|" + { f'2^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} fis'8^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}[ gis'8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ gis'8[ fis'8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] } + \bar "|" + { e'4^\markup { \pad-markup #0.2 "+40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} fis8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ gis8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] a2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { a4 gis4^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} e8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ f8^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ f4 ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f2 g8^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}[ a8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ais8^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}[ f8^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f4 fis8^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}[ g8^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}] dis4^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ dis8[ f8^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}] } + \bar "|" + { g8^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}[ gis8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] a2^\markup { \pad-markup #0.2 "+25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} c'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ cis'8^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}]} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/690ef677/lilypond/part_IV.ly b/resources/string_quartet_3_rise/690ef677/lilypond/part_IV.ly new file mode 100644 index 0000000..9d9f361 --- /dev/null +++ b/resources/string_quartet_3_rise/690ef677/lilypond/part_IV.ly @@ -0,0 +1,36 @@ +{ + { e'8^\markup { \pad-markup #0.2 "+31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }}[ fis'8^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}] g'4^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} a'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ d''8^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ d''8[ cis''8^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }}] } + \bar "|" + { cis''8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }}[ gis'8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ gis'2. ~ } + \bar "|" + { gis'8[ a'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↑" }}] ~ a'8[ b'8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ b'8[ fis'8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ fis'4 } + \bar "|" + { e'2^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↑" }} ~ e'8[ dis'8^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }}] ~ dis'4 ~ } + \bar "|" + { dis'1 } + \bar "|" + { f'8^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}[ fis'8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] ~ fis'8[ g'8^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }}] ais'8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ b'8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] ~ b'4 ~ } + \bar "|" + { b'1 } + \bar "|" + { c''8^\markup { \pad-markup #0.2 "+26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }}[ d''8^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }}] c''8^\markup { \pad-markup #0.2 "+26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ g'8^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] a'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}[ ais'8^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}] c''8^\markup { \pad-markup #0.2 "+26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ g8^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { g4 gis4^\markup { \pad-markup #0.2 "+40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} cis8^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ ais,8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] c8^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}[ a'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] } + \bar "|" + { a8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ b8^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] cis'2.^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} ~ } + \bar "|" + { cis'2. a'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ b,8^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] } + \bar "|" + { a,8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ e,8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] e8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ gis,8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] a,2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} } + \bar "|" + { f'4^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ais8^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ c'8^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] cis'4^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} f'4^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} } + \bar "|" + { c8^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ cis8^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] f'2^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ f'8[ dis'8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] } + \bar "|" + { f'2^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ f'8[ d'8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] cis'4^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }} ~ } + \bar "|" + { cis'4 ~ cis'8[ dis'8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}] ~ dis'8[ ais,8^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ ais,8[ dis,8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { dis,4 b,8^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}[ a,8^\markup { \pad-markup #0.2 "+25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ a,2} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6db2efcc/lilypond/part_I.ly b/resources/string_quartet_3_rise/6db2efcc/lilypond/part_I.ly index 90f111c..aa0857d 100644 --- a/resources/string_quartet_3_rise/6db2efcc/lilypond/part_I.ly +++ b/resources/string_quartet_3_rise/6db2efcc/lilypond/part_I.ly @@ -1,22 +1,22 @@ { - { ais1^\markup { \pad-markup #0.2 "-11"} ~ } + { c'1^\markup { \pad-markup #0.2 "-11"} ~ } \bar "|" - { ais2 g'2^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} } + { c'2 a'2^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} } \bar "|" - { gis'1^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + { ais'1^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } \bar "|" - { gis'1 ~ } + { ais'1 ~ } \bar "|" - { gis'1 ~ } + { ais'1 ~ } \bar "|" - { gis'1 ~ } + { ais'1 ~ } \bar "|" - { gis'1 } + { ais'1 } \bar "|" - { a'1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + { b'1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } \bar "|" - { a'1 ~ } + { b'1 ~ } \bar "|" - { a'1} + { b'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6db2efcc/lilypond/part_II.ly b/resources/string_quartet_3_rise/6db2efcc/lilypond/part_II.ly index 88a941a..a4955d2 100644 --- a/resources/string_quartet_3_rise/6db2efcc/lilypond/part_II.ly +++ b/resources/string_quartet_3_rise/6db2efcc/lilypond/part_II.ly @@ -1,22 +1,22 @@ { - { f'1^\markup { \pad-markup #0.2 "-9"} } + { g'1^\markup { \pad-markup #0.2 "-9"} } \bar "|" - { f'1^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + { g'1^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } \bar "|" - { f'1 } + { g'1 } \bar "|" - { fis'2^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} cis'2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } + { gis'2^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} dis'2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } \bar "|" - { cis'1 ~ } + { dis'1 ~ } \bar "|" - { cis'2 ais'2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + { dis'2 c''2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } \bar "|" - { ais'2 c''2^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }} ~ } + { c''2 d''2^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }} ~ } \bar "|" - { c''2 fis2^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } + { d''2 gis2^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } \bar "|" - { fis1 } + { gis1 } \bar "|" - { dis'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}} + { f'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6db2efcc/lilypond/part_III.ly b/resources/string_quartet_3_rise/6db2efcc/lilypond/part_III.ly index 898501b..ef75055 100644 --- a/resources/string_quartet_3_rise/6db2efcc/lilypond/part_III.ly +++ b/resources/string_quartet_3_rise/6db2efcc/lilypond/part_III.ly @@ -1,22 +1,22 @@ { - { e2^\markup { \pad-markup #0.2 "+7"} fis2^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + { fis2^\markup { \pad-markup #0.2 "+7"} gis2^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } \bar "|" - { fis1 ~ } + { gis1 ~ } \bar "|" - { fis1 ~ } + { gis1 ~ } \bar "|" - { fis1 ~ } + { gis1 ~ } \bar "|" - { fis2 gis2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { gis2 ais2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } \bar "|" - { gis1 ~ } + { ais1 ~ } \bar "|" - { gis1 ~ } + { ais1 ~ } \bar "|" - { gis1 } + { ais1 } \bar "|" - { b1^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} ~ } + { cis'1^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} ~ } \bar "|" - { b2 fis'2^\markup { \pad-markup #0.2 "+11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }}} + { cis'2 gis'2^\markup { \pad-markup #0.2 "+11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6db2efcc/lilypond/part_IV.ly b/resources/string_quartet_3_rise/6db2efcc/lilypond/part_IV.ly index 6098652..9a82eee 100644 --- a/resources/string_quartet_3_rise/6db2efcc/lilypond/part_IV.ly +++ b/resources/string_quartet_3_rise/6db2efcc/lilypond/part_IV.ly @@ -1,22 +1,22 @@ { - { c'1^\markup { \pad-markup #0.2 "+21"} ~ } + { d'1^\markup { \pad-markup #0.2 "+21"} ~ } \bar "|" - { c'1 ~ } + { d'1 ~ } \bar "|" - { c'2 dis'2^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + { d'2 f'2^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } \bar "|" - { dis'1 } + { f'1 } \bar "|" - { e'1^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} } + { fis'1^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} } \bar "|" - { e'1^\markup { \pad-markup #0.2 "+44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }} } + { fis'1^\markup { \pad-markup #0.2 "+44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }} } \bar "|" - { f'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } + { g'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } \bar "|" - { f'1 ~ } + { g'1 ~ } \bar "|" - { f'2 fis'2^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + { g'2 gis'2^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } \bar "|" - { fis'1} + { gis'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6dcb2cc5/6dcb2cc5_code.scd b/resources/string_quartet_3_rise/6dcb2cc5/6dcb2cc5_code.scd new file mode 100644 index 0000000..e1a9d92 --- /dev/null +++ b/resources/string_quartet_3_rise/6dcb2cc5/6dcb2cc5_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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"], {(62.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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/6dcb2cc5/6dcb2cc5_mus_model.json b/resources/string_quartet_3_rise/6dcb2cc5/6dcb2cc5_mus_model.json new file mode 100644 index 0000000..ab2a123 --- /dev/null +++ b/resources/string_quartet_3_rise/6dcb2cc5/6dcb2cc5_mus_model.json @@ -0,0 +1,61 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -5, 8, -3, 1, -3, 2 ], [ -4, 8, -2, 1, -4, 2 ], [ -4, 8, -2, 1, -3, 2 ], [ -5, 8, -2, 1, -3, 2 ] ], 0.375 ] + ], + [ + [ [ [ -5, 8, -3, 1, -3, 2 ], [ -4, 8, -2, 1, -4, 2 ], [ -3, 8, -2, 0, -3, 2 ], [ -5, 8, -2, 1, -3, 2 ] ], 0 ], + [ [ [ -5, 8, -3, 1, -3, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -3, 8, -2, 0, -3, 2 ], [ -5, 8, -2, 1, -3, 2 ] ], 0.375 ], + [ [ [ -6, 8, -2, 1, -3, 3 ], [ -4, 8, -2, 0, -3, 2 ], [ -3, 8, -2, 0, -3, 2 ], [ -5, 8, -2, 1, -3, 2 ] ], 0.25 ], + [ [ [ -6, 8, -2, 1, -3, 3 ], [ -4, 8, -2, 0, -3, 2 ], [ -3, 8, -2, 1, -3, 1 ], [ -5, 8, -2, 1, -3, 2 ] ], 0.5 ] + ], + [ + [ [ [ -6, 8, -2, 1, -3, 3 ], [ -4, 8, -2, 0, -3, 2 ], [ -5, 8, -2, 1, -2, 3 ], [ -5, 8, -2, 1, -3, 2 ] ], 0.25 ], + [ [ [ -6, 8, -2, 1, -3, 3 ], [ -4, 8, -2, 0, -3, 2 ], [ -4, 8, -2, 1, -3, 2 ], [ -5, 8, -2, 1, -3, 2 ] ], 0.625 ], + [ [ [ -6, 8, -2, 1, -3, 3 ], [ -4, 8, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 3 ], [ -5, 8, -2, 1, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 3 ], [ -5, 8, -2, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 7, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 3 ], [ -5, 8, -2, 0, -3, 3 ] ], 0.375 ], + [ [ [ -4, 8, -2, 0, -4, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 3 ], [ -5, 8, -2, 0, -3, 3 ] ], 0 ], + [ [ [ -4, 8, -2, 0, -4, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 3 ], [ -5, 9, -2, 0, -3, 2 ] ], 0.375 ], + [ [ [ -4, 8, -3, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 3 ], [ -5, 9, -2, 0, -3, 2 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ -4, 7, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 3 ], [ -5, 8, -2, 1, -3, 2 ] ], + [ [ -4, 7, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 3 ], [ -5, 8, -2, 0, -3, 3 ] ], + [ [ -4, 8, -2, 0, -4, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 3 ], [ -5, 8, -2, 0, -3, 3 ] ], + [ [ -4, 8, -2, 0, -4, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 3 ], [ -5, 9, -2, 0, -3, 2 ] ], + [ [ -4, 8, -3, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 3 ], [ -5, 9, -2, 0, -3, 2 ] ] +], +"cur_uid": "6dcb2cc5", +"ref_uid": "766771df", +"order_seed": 676209, +"dur_seed": 338713, +"motifs_seed": 923476, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 3, 0.0098039215686275, 0, 0.065359477124183, 0, 0.11111111111111, 0.79391891891892, 0.21895424836601, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 3, 0.0098039215686275, 0, 0.065359477124183, 0, 0.11111111111111, 0.79391891891892, 0.21895424836601, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 3, 0.0098039215686275, 0, 0.065359477124183, 0, 0.11111111111111, 0.79391891891892, 0.21895424836601, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 2, 0, 1 ], [ 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 2 ], [ ] ], + [ [ 1, 3, 0 ], [ 2, 2, 2 ], [ ] ], + [ [ 2, 1 ], [ 0, 3, 0, 3, 0 ], [ ] ] +], +"sus_weights": [ 0.7, 0.48, 0.49 ], +"order_size": [ 4.030612244898, 4.030612244898 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/6e464fbc/6e464fbc_code.scd b/resources/string_quartet_3_rise/6e464fbc/6e464fbc_code.scd new file mode 100644 index 0000000..070e09d --- /dev/null +++ b/resources/string_quartet_3_rise/6e464fbc/6e464fbc_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/6e464fbc/6e464fbc_mus_model.json b/resources/string_quartet_3_rise/6e464fbc/6e464fbc_mus_model.json new file mode 100644 index 0000000..b5784be --- /dev/null +++ b/resources/string_quartet_3_rise/6e464fbc/6e464fbc_mus_model.json @@ -0,0 +1,164 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -2, 2 ], [ -7, 5, 1, 4, 0, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 1 ], + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, 0, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 1 ], + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, 0, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, 0, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -8, 5, 1, 4, 0, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -8, 6, 1, 5, -1, 2 ], [ -8, 5, 1, 4, 0, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -8, 6, 1, 5, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -8, 6, 1, 5, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -8, 5, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -8, 5, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -7, 6, 0, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 6, 1, 3, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -8, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -8, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 5, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 7, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 7, 1, 3, -1, 2 ], [ -8, 6, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 1, 2, -1, 2 ], [ -8, 6, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ], + [ [ [ -7, 6, 1, 2, -1, 2 ], [ -7, 6, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ], + [ [ [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 8, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -6, 6, 1, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -6, 6, 1, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ], + [ [ [ -7, 6, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -8, 8, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -7, 7, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -8, 8, 2, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 7, 1, 3, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -8, 8, 2, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 7, 1, 3, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -8, 8, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -7, 7, 1, 3, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ], [ -6, 7, 1, 2, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 7, 1, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ], [ -6, 7, 1, 2, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -9, 7, 1, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -6, 7, 1, 2, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -9, 7, 1, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 7, 1, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -8, 8, 2, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -8, 8, 2, 2, -2, 2 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -9, 10, -3, 4, -1, 3 ], [ -9, 10, -3, 4, -2, 3 ], [ -10, 11, -3, 4, -2, 3 ], [ -8, 10, -3, 4, -2, 3 ] ], + [ [ -9, 10, -3, 4, -1, 3 ], [ -9, 10, -3, 4, -2, 3 ], [ -9, 10, -4, 4, -2, 3 ], [ -8, 10, -3, 4, -2, 3 ] ], + [ [ -9, 10, -3, 4, -1, 3 ], [ -9, 10, -3, 4, -2, 3 ], [ -9, 11, -3, 4, -2, 3 ], [ -8, 10, -3, 4, -2, 3 ] ], + [ [ -10, 11, -3, 4, -2, 3 ], [ -9, 10, -3, 4, -2, 3 ], [ -9, 11, -3, 4, -2, 3 ], [ -8, 10, -3, 4, -2, 3 ] ], + [ [ -10, 11, -3, 4, -2, 3 ], [ -9, 10, -3, 4, -2, 3 ], [ -8, 10, -4, 4, -2, 3 ], [ -8, 10, -3, 4, -2, 3 ] ] +], +"cur_uid": "6e464fbc", +"ref_uid": "7276dc78", +"order_seed": 286104, +"dur_seed": 321617, +"motifs_seed": 324532, +"entrances_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"passages_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"exits_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0.0041152263374486, 0.0056818181818179, 0.080246913580247, 0.02840909090909, 0.20781893004115, 0.028409090909091, 0.41152263374486, 0, 0.44650205761317, 0.16477272727273, 0.47736625514403, 0, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 0.58, 1, 0.43, 1, 0.82 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 3 ], [ 1, 0, 2 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 0, 2, 2 ], [ ] ], + [ [ 3 ], [ 1, 0, 2, 0, 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 3, 3 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 2, 3 ], [ ] ], + [ [ 1 ], [ 0, 2, 3 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 2, 0, 2, 0 ], [ ] ], + [ [ 0, 1 ], [ 3, 2, 2, 2, 3, 2, 3 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 0, 2 ], [ ] ], + [ [ 1 ], [ 0, 2, 3 ], [ ] ], + [ [ 2 ], [ 3, 1, 0, 1, 0, 3, 3, 0 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 1, 0 ], [ ] ], + [ [ 2 ], [ 0, 3, 1, 1, 1, 3, 0 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 2, 2 ], [ ] ], + [ [ 0 ], [ 2, 1, 3, 1, 1, 2 ], [ ] ], + [ [ 0 ], [ 2, 3, 1 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 1, 2, 0, 1, 2 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 1, 0 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 0 ], [ ] ], + [ [ 1, 0 ], [ 3, 2, 2 ], [ ] ], + [ [ 0 ], [ 2, 1, 3, 3, 2, 3, 3, 3 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 3 ], [ ] ], + [ [ 1, 2 ], [ 3, 0, 0 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 3, 0, 0, 0 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 1, 0, 1, 1, 2 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 0 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 0, 2, 0, 2, 3 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 2, 2, 2, 0, 2 ], [ ] ] +], +"sus_weights": [ 0.69, 0.17, 0 ], +"order_size": [ 28, 28.275510204082 ], +"passages_size": [ 0, 6 ], +"motif_edited": "true", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/72570de5/72570de5_code.scd b/resources/string_quartet_3_rise/72570de5/72570de5_code.scd new file mode 100644 index 0000000..e1a9d92 --- /dev/null +++ b/resources/string_quartet_3_rise/72570de5/72570de5_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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"], {(62.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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/72570de5/72570de5_mus_model.json b/resources/string_quartet_3_rise/72570de5/72570de5_mus_model.json new file mode 100644 index 0000000..b503a7e --- /dev/null +++ b/resources/string_quartet_3_rise/72570de5/72570de5_mus_model.json @@ -0,0 +1,383 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 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 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 1, 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, 1, 0, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ -1, -1, 0, 0, 0, 1 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, -1, 0, 0, 0, 1 ], [ -1, -1, 0, 0, 0, 1 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, -1, 0, 0, 0, 1 ], [ -2, 1, 0, 0, 0, 1 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, -1, 0, 0, 0, 1 ], [ -2, 2, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, -1, 0, 0, 0, 1 ], [ 0, -1, -1, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, -1, 0, 0, 0, 1 ], [ 0, -1, -1, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, 0, 0, 0 ], [ 0, -1, -1, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 1, -1, -1, 0, 0, 0 ], [ 0, -1, -1, 0, 0, 0 ], [ 1, -2, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ 0, -1, -1, 0, 0, 0 ], [ 1, -2, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ 0, -1, -1, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, -1, -1, 0, 0, 0 ], [ 0, -1, -1, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, -1, -1, 0, 0, 0 ], [ 0, -1, -1, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ], [ 2, -1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ -1, -1, -1, 0, 0, 0 ], [ 0, -1, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 2, -1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ -1, -1, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 2, -1, -1, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, -1, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, -1, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ] ], 0 ], + [ [ [ -1, -1, -1, 0, 0, 0 ], [ 2, -1, -2, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, -1, -1, 0, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 0, -1, -1, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ] ], 0.25 ], + [ [ [ 0, 0, -1, -1, 0, 0 ], [ 2, 0, -1, -1, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 0, -1, -1, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 2, -2, -1, -1, 0, 0 ], [ 2, -1, -1, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 2, -2, -1, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 2, -2, -1, -1, 0, 0 ], [ 2, -2, -1, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 2, -2, -1, -1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 2, -2, -1, -1, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 2, -2, -1, -1, 0, 0 ], [ 3, -2, -1, -1, 0, 0 ] ], 0 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 4, -3, -1, -1, 0, 0 ], [ 2, -2, -1, -1, 0, 0 ], [ 3, -2, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -2, -1, -1, 0, 0 ], [ 4, -3, -1, -1, 0, 0 ], [ 2, -2, -1, -1, 0, 0 ], [ 3, -2, -1, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, -2, -1, -1, 0, 0 ], [ 4, -3, -1, -1, 0, 0 ], [ 3, -3, -2, -1, 0, 0 ], [ 3, -2, -1, -1, 0, 0 ] ], 0.25 ], + [ [ [ 1, -2, -1, -1, 0, 0 ], [ 4, -3, -1, -1, 0, 0 ], [ 2, -2, -1, -1, 0, 0 ], [ 3, -2, -1, -1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, -2, -1, -1, 0, 0 ], [ 3, -2, 0, -1, 0, 0 ], [ 2, -2, -1, -1, 0, 0 ], [ 3, -2, -1, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -2, -1, -1, 0, 0 ], [ 3, -2, 0, -1, 0, 0 ], [ 2, -2, -1, -1, 0, 0 ], [ 2, -2, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 1, -2, -1, -1, 0, 0 ], [ 3, -2, 0, -1, 0, 0 ], [ 3, -2, -1, -2, 0, 0 ], [ 2, -2, -1, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, -2, -1, -1, 0, 0 ], [ 4, -2, -1, -2, 0, 0 ], [ 3, -2, -1, -2, 0, 0 ], [ 2, -2, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 1, -2, -1, -1, 0, 0 ], [ 4, -2, -1, -2, 0, 0 ], [ 3, -2, -1, -2, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ] ], 0 ], + [ [ [ 2, -2, -1, -2, 0, 0 ], [ 4, -2, -1, -2, 0, 0 ], [ 3, -2, -1, -2, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ] ], 0.25 ], + [ [ [ 3, -2, -1, -3, 0, 0 ], [ 4, -2, -1, -2, 0, 0 ], [ 3, -2, -1, -2, 0, 0 ], [ 3, -1, -1, -2, 0, 0 ] ], 0.25 ], + [ [ [ 3, -2, -1, -3, 0, 0 ], [ 4, -2, -1, -2, 0, 0 ], [ 3, -2, -1, -2, 0, 0 ], [ 4, -3, -1, -2, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, -2, -1, -3, 0, 0 ], [ 4, -2, -1, -2, 0, 0 ], [ 3, -2, -1, -2, 0, 0 ], [ 4, -2, -1, -3, 0, 0 ] ], 0 ], + [ [ [ 3, -2, -1, -3, 0, 0 ], [ 5, -2, -1, -3, 0, 0 ], [ 3, -2, -1, -2, 0, 0 ], [ 4, -2, -1, -3, 0, 0 ] ], 0 ], + [ [ [ 2, -2, 0, -2, 0, 0 ], [ 5, -2, -1, -3, 0, 0 ], [ 3, -2, -1, -2, 0, 0 ], [ 4, -2, -1, -3, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 2, -2, 0, -2, 0, 0 ], [ 5, -2, -1, -3, 0, 0 ], [ 4, -2, -2, -3, 0, 0 ], [ 4, -2, -1, -3, 0, 0 ] ], 0.25 ], + [ [ [ 2, -2, 0, -2, 0, 0 ], [ 4, -1, -1, -3, 0, 0 ], [ 4, -2, -2, -3, 0, 0 ], [ 4, -2, -1, -3, 0, 0 ] ], 0 ], + [ [ [ 2, -2, 0, -2, 0, 0 ], [ 4, -1, -1, -3, 0, 0 ], [ 2, -2, 0, -2, 0, 1 ], [ 4, -2, -1, -3, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 2, -2, 0, -2, 0, 0 ], [ 4, -1, -1, -3, 0, 0 ], [ 2, -2, 0, -2, 0, 1 ], [ 3, -2, 0, -2, 0, 0 ] ], 0 ], + [ [ [ 2, -2, 0, -2, 0, 0 ], [ 3, -2, -1, -2, 0, 1 ], [ 2, -2, 0, -2, 0, 1 ], [ 3, -2, 0, -2, 0, 0 ] ], 0 ], + [ [ [ 2, -3, 0, -2, 0, 1 ], [ 3, -2, -1, -2, 0, 1 ], [ 2, -2, 0, -2, 0, 1 ], [ 3, -2, 0, -2, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 3, -2, -1, -2, 0, 1 ], [ 2, -2, 0, -2, 0, 1 ], [ 3, -2, 0, -2, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 3, -2, -1, -2, 0, 1 ], [ 1, 0, 0, -2, 0, 1 ], [ 3, -2, 0, -2, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 3, -2, -1, -2, 0, 1 ], [ 3, -3, -1, -2, 0, 1 ], [ 3, -2, 0, -2, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 2, -1, 0, -2, 0, 1 ], [ 3, -3, -1, -2, 0, 1 ], [ 3, -2, 0, -2, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 4, -3, 0, -2, 0, 0 ], [ 3, -3, -1, -2, 0, 1 ], [ 3, -2, 0, -2, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 4, -3, 0, -2, 0, 0 ], [ 3, -3, -1, -2, 0, 1 ], [ 4, -3, 0, -2, -1, 0 ] ], 0.25 ], + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 4, -3, 0, -2, 0, 0 ], [ 3, -3, -1, -2, 0, 1 ], [ 3, -3, 0, -2, 0, 1 ] ], 0.25 ], + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 4, -3, 0, -2, 0, 0 ], [ 3, -3, -1, -2, 0, 1 ], [ 2, -1, -1, -2, 0, 1 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 4, -3, 0, -2, 0, 0 ], [ 3, -3, -1, -2, 0, 1 ], [ 3, -3, 0, -2, 1, 0 ] ], 0.25 ], + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 4, -3, 0, -2, 0, 0 ], [ 3, -3, -1, -2, 0, 1 ], [ 4, -4, 0, -2, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 4, -3, 0, -2, 0, 0 ], [ 3, -3, -1, -2, 0, 1 ], [ 4, -3, -1, -3, 0, 1 ] ], 0.25 ], + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 4, -3, 0, -2, 0, 0 ], [ 3, -3, -1, -2, 0, 1 ], [ 4, -3, -1, -2, 0, 0 ] ], 0.25 ], + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 4, -3, 0, -2, 0, 0 ], [ 3, -3, -1, -2, 0, 1 ], [ 3, -3, 0, -2, 0, 1 ] ], 0.25 ] + ], + [ + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 3, -2, -1, -2, 0, 1 ], [ 3, -3, -1, -2, 0, 1 ], [ 3, -3, 0, -2, 0, 1 ] ], 0.25 ], + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 3, -3, 1, -2, 0, 1 ], [ 3, -3, -1, -2, 0, 1 ], [ 3, -3, 0, -2, 0, 1 ] ], 0.25 ], + [ [ [ 1, -1, 0, -2, 0, 1 ], [ 4, -4, 0, -2, 0, 1 ], [ 3, -3, -1, -2, 0, 1 ], [ 3, -3, 0, -2, 0, 1 ] ], 0.25 ] + ], + [ + [ [ [ 3, -4, -1, -2, 0, 1 ], [ 4, -4, 0, -2, 0, 1 ], [ 3, -3, -1, -2, 0, 1 ], [ 3, -3, 0, -2, 0, 1 ] ], 0.25 ], + [ [ [ 2, -3, 0, -2, 0, 1 ], [ 4, -4, 0, -2, 0, 1 ], [ 3, -3, -1, -2, 0, 1 ], [ 3, -3, 0, -2, 0, 1 ] ], 0.25 ] + ], + [ + [ [ [ 2, -3, 0, -2, 0, 1 ], [ 4, -4, 0, -2, 0, 1 ], [ 4, -5, 0, -2, 0, 1 ], [ 3, -3, 0, -2, 0, 1 ] ], 0 ], + [ [ [ 3, -5, 0, -2, 0, 1 ], [ 4, -4, 0, -2, 0, 1 ], [ 4, -5, 0, -2, 0, 1 ], [ 3, -3, 0, -2, 0, 1 ] ], 0.25 ], + [ [ [ 3, -5, 0, -2, 0, 1 ], [ 4, -4, 0, -2, 0, 1 ], [ 4, -5, 0, -2, 0, 1 ], [ 4, -4, -1, -2, 0, 1 ] ], 0 ], + [ [ [ 3, -5, 0, -2, 0, 1 ], [ 4, -4, 0, -2, 0, 1 ], [ 3, -3, 0, -2, 0, 1 ], [ 4, -4, -1, -2, 0, 1 ] ], 0.25 ], + [ [ [ 3, -5, 0, -2, 0, 1 ], [ 4, -4, 0, -2, 0, 1 ], [ 3, -4, 0, -2, 0, 2 ], [ 4, -4, -1, -2, 0, 1 ] ], 0 ], + [ [ [ 3, -5, 0, -2, 0, 1 ], [ 4, -4, 0, -2, 0, 1 ], [ 3, -4, 0, -2, 0, 2 ], [ 3, -4, 0, -1, 0, 1 ] ], 0.25 ] + ], + [ + [ [ [ 3, -5, 0, -2, 0, 1 ], [ 4, -4, 0, -2, 0, 1 ], [ 3, -4, 0, -2, 0, 2 ], [ 3, -4, 0, -2, 0, 1 ] ], 0.25 ], + [ [ [ 2, -4, 0, -2, 0, 2 ], [ 4, -4, 0, -2, 0, 1 ], [ 3, -4, 0, -2, 0, 2 ], [ 3, -4, 0, -2, 0, 1 ] ], 0.25 ], + [ [ [ 2, -4, 0, -1, 0, 1 ], [ 4, -4, 0, -2, 0, 1 ], [ 3, -4, 0, -2, 0, 2 ], [ 3, -4, 0, -2, 0, 1 ] ], 0.25 ], + [ [ [ 3, -4, -1, -2, 0, 1 ], [ 4, -4, 0, -2, 0, 1 ], [ 3, -4, 0, -2, 0, 2 ], [ 3, -4, 0, -2, 0, 1 ] ], 0.25 ] + ], + [ + [ [ [ 3, -4, -1, -2, 0, 1 ], [ 4, -4, 0, -2, 0, 1 ], [ 4, -4, -1, -2, 0, 1 ], [ 3, -4, 0, -2, 0, 1 ] ], 0.25 ], + [ [ [ 3, -4, -1, -2, 0, 1 ], [ 5, -5, -1, -2, 0, 1 ], [ 4, -4, -1, -2, 0, 1 ], [ 3, -4, 0, -2, 0, 1 ] ], 0.25 ], + [ [ [ 3, -4, -1, -2, 0, 1 ], [ 5, -5, -1, -2, 0, 1 ], [ 4, -4, -1, -2, 0, 1 ], [ 4, -5, -1, -2, 0, 1 ] ], 0 ], + [ [ [ 3, -4, -1, -2, 0, 1 ], [ 4, -3, -1, -2, 0, 1 ], [ 4, -4, -1, -2, 0, 1 ], [ 4, -5, -1, -2, 0, 1 ] ], 0.25 ], + [ [ [ 3, -4, -1, -2, 0, 1 ], [ 4, -3, -1, -2, 0, 1 ], [ 4, -4, -1, -2, 0, 1 ], [ 3, -3, -1, -2, 0, 1 ] ], 0.25 ], + [ [ [ 3, -4, -1, -2, 0, 1 ], [ 4, -3, -1, -2, 0, 1 ], [ 4, -4, -1, -2, 0, 1 ], [ 4, -4, -2, -2, 0, 1 ] ], 0 ], + [ [ [ 3, -4, -1, -2, 0, 1 ], [ 4, -3, -1, -2, 0, 1 ], [ 4, -4, -1, -2, -1, 1 ], [ 4, -4, -2, -2, 0, 1 ] ], 0.25 ] + ], + [ + [ [ [ 4, -4, -2, -2, 0, 0 ], [ 4, -3, -1, -2, 0, 1 ], [ 4, -4, -1, -2, -1, 1 ], [ 4, -4, -2, -2, 0, 1 ] ], 0.25 ], + [ [ [ 3, -4, 0, -2, -1, 1 ], [ 4, -3, -1, -2, 0, 1 ], [ 4, -4, -1, -2, -1, 1 ], [ 4, -4, -2, -2, 0, 1 ] ], 0.25 ], + [ [ [ 4, -4, -1, -2, 0, 1 ], [ 4, -3, -1, -2, 0, 1 ], [ 4, -4, -1, -2, -1, 1 ], [ 4, -4, -2, -2, 0, 1 ] ], 0.25 ], + [ [ [ 5, -5, -2, -2, 0, 1 ], [ 4, -3, -1, -2, 0, 1 ], [ 4, -4, -1, -2, -1, 1 ], [ 4, -4, -2, -2, 0, 1 ] ], 0.25 ], + [ [ [ 5, -4, -2, -2, -1, 1 ], [ 4, -3, -1, -2, 0, 1 ], [ 4, -4, -1, -2, -1, 1 ], [ 4, -4, -2, -2, 0, 1 ] ], 0.25 ] + ], + [ + [ [ [ 5, -4, -2, -2, -1, 1 ], [ 4, -3, -1, -2, 0, 1 ], [ 4, -4, -1, -2, -1, 1 ], [ 4, -3, -2, -2, -1, 1 ] ], 0 ], + [ [ [ 5, -4, -2, -2, -1, 1 ], [ 5, -4, -1, -2, -1, 1 ], [ 4, -4, -1, -2, -1, 1 ], [ 4, -3, -2, -2, -1, 1 ] ], 0.25 ], + [ [ [ 5, -4, -2, -2, -1, 1 ], [ 5, -4, -1, -2, -1, 1 ], [ 5, -5, -2, -2, -1, 1 ], [ 4, -3, -2, -2, -1, 1 ] ], 0.25 ], + [ [ [ 5, -4, -2, -2, -1, 1 ], [ 5, -4, -1, -2, -1, 1 ], [ 5, -4, -2, -2, -1, 0 ], [ 4, -3, -2, -2, -1, 1 ] ], 0 ], + [ [ [ 5, -4, -2, -2, -1, 1 ], [ 6, -4, -2, -2, -1, 0 ], [ 5, -4, -2, -2, -1, 0 ], [ 4, -3, -2, -2, -1, 1 ] ], 0.25 ] + ], + [ + [ [ [ 5, -4, -2, -2, -1, 1 ], [ 6, -4, -2, -2, -1, 0 ], [ 4, -4, -2, -2, -1, 1 ], [ 4, -3, -2, -2, -1, 1 ] ], 0 ], + [ [ [ 5, -4, -2, -2, -1, 1 ], [ 6, -4, -2, -2, -1, 0 ], [ 4, -4, -2, -2, -1, 1 ], [ 6, -5, -2, -2, -1, 0 ] ], 0 ], + [ [ [ 6, -4, -3, -2, -1, 0 ], [ 6, -4, -2, -2, -1, 0 ], [ 4, -4, -2, -2, -1, 1 ], [ 6, -5, -2, -2, -1, 0 ] ], 0.25 ], + [ [ [ 6, -4, -3, -2, -1, 0 ], [ 6, -4, -2, -2, -1, 0 ], [ 5, -4, -3, -2, -1, 0 ], [ 6, -5, -2, -2, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 7, -6, -2, -2, -1, 0 ], [ 6, -4, -2, -2, -1, 0 ], [ 5, -4, -3, -2, -1, 0 ], [ 6, -5, -2, -2, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 7, -6, -2, -2, -1, 0 ], [ 7, -5, -3, -2, -1, 0 ], [ 5, -4, -3, -2, -1, 0 ], [ 6, -5, -2, -2, -1, 0 ] ], 0.25 ], + [ [ [ 6, -4, -2, -2, -1, 0 ], [ 7, -5, -3, -2, -1, 0 ], [ 5, -4, -3, -2, -1, 0 ], [ 6, -5, -2, -2, -1, 0 ] ], 0 ], + [ [ [ 6, -4, -2, -2, -1, 0 ], [ 6, -4, -3, -2, -1, 0 ], [ 5, -4, -3, -2, -1, 0 ], [ 6, -5, -2, -2, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 6, -4, -2, -2, -1, 0 ], [ 6, -4, -3, -2, -1, 0 ], [ 5, -4, -3, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0 ], + [ [ [ 7, -4, -3, -2, -1, -1 ], [ 6, -4, -3, -2, -1, 0 ], [ 5, -4, -3, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0.25 ], + [ [ [ 4, -4, -3, -2, -1, 0 ], [ 6, -4, -3, -2, -1, 0 ], [ 5, -4, -3, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0.25 ], + [ [ [ 5, -4, -4, -2, -1, 0 ], [ 6, -4, -3, -2, -1, 0 ], [ 5, -4, -3, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 5, -4, -4, -2, -1, 0 ], [ 7, -5, -4, -2, -1, 0 ], [ 5, -4, -3, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0 ], + [ [ [ 5, -4, -4, -2, -1, 0 ], [ 7, -5, -4, -2, -1, 0 ], [ 6, -5, -4, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0 ], + [ [ [ 5, -5, -4, -2, -1, 0 ], [ 7, -5, -4, -2, -1, 0 ], [ 6, -5, -4, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, -3, -4, -2, -1, 0 ], [ 7, -5, -4, -2, -1, 0 ], [ 6, -5, -4, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0.25 ], + [ [ [ 5, -5, -3, -2, -1, 0 ], [ 7, -5, -4, -2, -1, 0 ], [ 6, -5, -4, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0.25 ], + [ [ [ 6, -6, -4, -2, -1, 0 ], [ 7, -5, -4, -2, -1, 0 ], [ 6, -5, -4, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0.25 ], + [ [ [ 6, -5, -4, -2, -2, 0 ], [ 7, -5, -4, -2, -1, 0 ], [ 6, -5, -4, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0.25 ], + [ [ [ 5, -4, -4, -2, -1, 0 ], [ 7, -5, -4, -2, -1, 0 ], [ 6, -5, -4, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 5, -4, -4, -2, -1, 0 ], [ 6, -3, -4, -2, -1, 0 ], [ 6, -5, -4, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0.25 ], + [ [ [ 5, -4, -4, -2, -1, 0 ], [ 6, -3, -4, -2, -1, 0 ], [ 5, -3, -4, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0 ], + [ [ [ 5, -4, -4, -2, -1, 0 ], [ 7, -4, -5, -2, -1, 0 ], [ 5, -3, -4, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0.25 ], + [ [ [ 5, -4, -4, -2, -1, 0 ], [ 7, -4, -5, -2, -1, 0 ], [ 6, -4, -5, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0.25 ], + [ [ [ 5, -4, -4, -2, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ], [ 6, -4, -5, -2, -1, 0 ], [ 6, -4, -4, -2, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 5, -4, -4, -2, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ], [ 6, -4, -5, -2, -1, 0 ], [ 5, -4, -3, -1, -1, 0 ] ], 0.25 ], + [ [ [ 5, -4, -4, -1, -1, -1 ], [ 6, -4, -4, -1, -1, 0 ], [ 6, -4, -5, -2, -1, 0 ], [ 5, -4, -3, -1, -1, 0 ] ], 0 ], + [ [ [ 5, -4, -4, -1, -1, -1 ], [ 6, -4, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 5, -4, -3, -1, -1, 0 ] ], 0 ], + [ [ [ 5, -4, -4, -1, -1, -1 ], [ 6, -4, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 6, -5, -4, -1, -1, 0 ] ], 0.25 ], + [ [ [ 5, -5, -4, -1, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 6, -5, -4, -1, -1, 0 ] ], 0 ], + [ [ [ 5, -5, -4, -1, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 5, -3, -4, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, -3, -4, -1, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 5, -3, -4, -1, -1, 0 ] ], 0 ], + [ [ [ 4, -3, -4, -1, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 1 ] ], 0.25 ], + [ [ [ 4, -4, -4, -1, -1, 1 ], [ 6, -4, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 1 ] ], 0.25 ], + [ [ [ 5, -4, -5, -1, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 1 ] ], 0.25 ], + [ [ [ 4, -4, -4, 0, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 1 ] ], 0.25 ] + ], + [ + [ [ [ 4, -4, -4, 0, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ], [ 4, -4, -3, 0, -1, 0 ], [ 5, -4, -4, -1, -1, 1 ] ], 0 ], + [ [ [ 4, -4, -4, 0, -1, 0 ], [ 4, -4, -4, 0, -1, -1 ], [ 4, -4, -3, 0, -1, 0 ], [ 5, -4, -4, -1, -1, 1 ] ], 0 ], + [ [ [ 4, -4, -4, 0, -1, 0 ], [ 4, -4, -4, 0, -1, -1 ], [ 4, -4, -3, 0, -1, 0 ], [ 5, -4, -4, 0, -1, 0 ] ], 0.25 ], + [ [ [ 4, -4, -4, 0, -1, 0 ], [ 4, -4, -4, -1, -1, 0 ], [ 4, -4, -3, 0, -1, 0 ], [ 5, -4, -4, 0, -1, 0 ] ], 0 ], + [ [ [ 4, -4, -4, 0, -1, 0 ], [ 4, -4, -4, -1, -1, 0 ], [ 4, -4, -3, 0, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ] ], 0 ], + [ [ [ 4, -4, -4, 0, -1, 0 ], [ 4, -4, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, -4, -4, 0, -1, 0 ], [ 5, -4, -4, -2, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ] ], 0.25 ], + [ [ [ 4, -4, -4, 0, -1, 0 ], [ 4, -4, -3, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ] ], 0.25 ], + [ [ [ 4, -4, -4, 0, -1, 0 ], [ 4, -5, -4, 0, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ] ], 0.25 ], + [ [ [ 4, -4, -4, 0, -1, 0 ], [ 5, -5, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, -4, -4, -1, -1, 0 ], [ 5, -5, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 6, -4, -4, -1, -1, 0 ] ], 0 ], + [ [ [ 4, -4, -4, -1, -1, 0 ], [ 5, -5, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 7, -5, -4, -1, -1, 0 ] ], 0.25 ], + [ [ [ 4, -4, -4, -1, -1, 0 ], [ 5, -5, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 6, -4, -3, -1, -1, 0 ] ], 0 ], + [ [ [ 5, -5, -5, -1, -1, 0 ], [ 5, -5, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 6, -4, -3, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 5, -5, -5, -1, -1, 0 ], [ 5, -5, -4, -1, -1, 0 ], [ 5, -5, -4, -1, -1, 1 ], [ 6, -4, -3, -1, -1, 0 ] ], 0 ], + [ [ [ 5, -5, -5, -1, -1, 0 ], [ 5, -5, -4, -1, -1, 0 ], [ 5, -5, -4, -1, -1, 1 ], [ 6, -5, -4, 0, -1, 0 ] ], 0.25 ], + [ [ [ 5, -5, -5, -1, -1, 0 ], [ 5, -5, -4, -1, -1, 0 ], [ 5, -5, -4, 0, -1, 0 ], [ 6, -5, -4, 0, -1, 0 ] ], 0.25 ], + [ [ [ 5, -5, -5, -1, -1, 0 ], [ 5, -5, -4, -1, -1, 0 ], [ 6, -5, -5, -1, -1, 0 ], [ 6, -5, -4, 0, -1, 0 ] ], 0.25 ], + [ [ [ 5, -5, -5, -1, -1, 0 ], [ 5, -5, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 6, -5, -4, 0, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 5, -5, -5, -1, -1, 0 ], [ 5, -5, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 7, -5, -4, -1, -1, 0 ] ], 0.25 ], + [ [ [ 5, -5, -5, -1, -1, 0 ], [ 5, -5, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 6, -4, -3, -1, -1, 0 ] ], 0.25 ], + [ [ [ 5, -5, -5, -1, -1, 0 ], [ 5, -5, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 6, -4, -4, -1, 0, 0 ] ], 0.25 ], + [ [ [ 5, -5, -5, -1, -1, 0 ], [ 5, -5, -4, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 7, -5, -5, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 5, -5, -5, -1, -1, 0 ], [ 6, -6, -5, -1, -1, 0 ], [ 5, -4, -4, -1, -1, 0 ], [ 7, -5, -5, -1, -1, 0 ] ], 0 ], + [ [ [ 5, -5, -5, -1, -1, 0 ], [ 6, -6, -5, -1, -1, 0 ], [ 6, -5, -5, -1, -1, 0 ], [ 7, -5, -5, -1, -1, 0 ] ], 0.25 ], + [ [ [ 5, -5, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 6, -5, -5, -1, -1, 0 ], [ 7, -5, -5, -1, -1, 0 ] ], 0.25 ], + [ [ [ 5, -5, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 6, -4, -5, -1, -1, 0 ], [ 7, -5, -5, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, -3, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 6, -4, -5, -1, -1, 0 ], [ 7, -5, -5, -1, -1, 0 ] ], 0.25 ], + [ [ [ 4, -3, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 5, -3, -5, -1, -1, 0 ], [ 7, -5, -5, -1, -1, 0 ] ], 0 ], + [ [ [ 4, -3, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 5, -3, -5, -1, -1, 0 ], [ 6, -3, -5, -1, -1, 0 ] ], 0 ], + [ [ [ 4, -4, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 5, -3, -5, -1, -1, 0 ], [ 6, -3, -5, -1, -1, 0 ] ], 0.5 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 5, -3, -5, -1, -1, 0 ], [ 6, -3, -5, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 6, -5, -5, -1, -1, 0 ], [ 6, -3, -5, -1, -1, 0 ] ], 0.25 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 5, -3, -6, -1, -1, 0 ], [ 6, -3, -5, -1, -1, 0 ] ], 0.25 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 4, -3, -5, 0, -1, 0 ], [ 6, -3, -5, -1, -1, 0 ] ], 0.25 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 5, -3, -5, -1, -1, 0 ], [ 6, -3, -5, -1, -1, 0 ] ], 0.25 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 6, -4, -5, -1, -1, 0 ], [ 6, -3, -5, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 4, -3, -5, -1, -1, 0 ], [ 6, -4, -5, -1, -1, 0 ], [ 6, -3, -5, -1, -1, 0 ] ], 0 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 4, -3, -5, -1, -1, 0 ], [ 6, -4, -5, -1, -1, 0 ], [ 4, -2, -5, -1, -1, 0 ] ], 0 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 4, -3, -5, -1, -1, 0 ], [ 5, -2, -5, -1, -1, 0 ], [ 4, -2, -5, -1, -1, 0 ] ], 0.25 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 5, -3, -5, -1, -1, 0 ], [ 5, -2, -5, -1, -1, 0 ], [ 4, -2, -5, -1, -1, 0 ] ], 0.25 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 6, -3, -5, -2, -1, 0 ], [ 5, -2, -5, -1, -1, 0 ], [ 4, -2, -5, -1, -1, 0 ] ], 0 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 6, -3, -5, -2, -1, 0 ], [ 5, -3, -5, -1, 0, 0 ], [ 4, -2, -5, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 6, -3, -5, -2, -1, 0 ], [ 7, -3, -5, -3, -1, 0 ], [ 4, -2, -5, -1, -1, 0 ] ], 0 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 6, -3, -5, -2, -1, 0 ], [ 7, -3, -5, -3, -1, 0 ], [ 5, -2, -5, -2, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 5, -3, -4, -1, -1, 0 ], [ 7, -3, -5, -3, -1, 0 ], [ 5, -2, -5, -2, -1, 0 ] ], 0 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 5, -3, -4, -1, -1, 0 ], [ 7, -3, -5, -3, -1, 0 ], [ 5, -3, -6, -1, -1, 0 ] ], 0 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 5, -3, -4, -1, -1, 0 ], [ 5, -3, -5, -1, -1, 0 ], [ 5, -3, -6, -1, -1, 0 ] ], 0.25 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 6, -4, -5, -1, -1, 0 ], [ 5, -3, -5, -1, -1, 0 ], [ 5, -3, -6, -1, -1, 0 ] ], 0.25 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 6, -4, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 5, -3, -6, -1, -1, 0 ] ], 0 ], + [ [ [ 3, -3, -5, -1, -1, 0 ], [ 6, -4, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 4, -2, -5, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, -5, -5, -1, -1, 0 ], [ 6, -4, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 4, -2, -5, -1, -1, 0 ] ], 0.25 ], + [ [ [ 4, -4, -5, -1, -2, 0 ], [ 6, -4, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 4, -2, -5, -1, -1, 0 ] ], 0.25 ], + [ [ [ 4, -4, -6, -1, -1, 0 ], [ 6, -4, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 4, -2, -5, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, -4, -6, -1, -1, 0 ], [ 6, -4, -5, -1, -1, 0 ], [ 5, -4, -5, -1, -1, 0 ], [ 6, -5, -6, -1, -1, 0 ] ], 0 ], + [ [ [ 4, -4, -6, -1, -1, 0 ], [ 6, -4, -5, -1, -1, 0 ], [ 5, -4, -6, -1, -1, 0 ], [ 6, -5, -6, -1, -1, 0 ] ], 0 ], + [ [ [ 4, -4, -6, -1, -1, 0 ], [ 7, -5, -6, -1, -1, 0 ], [ 5, -4, -6, -1, -1, 0 ], [ 6, -5, -6, -1, -1, 0 ] ], 0.25 ], + [ [ [ 4, -4, -6, -1, -1, 0 ], [ 7, -5, -6, -1, -1, 0 ], [ 6, -4, -6, -1, -1, 0 ], [ 6, -5, -6, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 4, -4, -6, -1, -1, 0 ], [ 7, -5, -6, -1, -1, 0 ], [ 6, -3, -6, -1, -1, 0 ], [ 6, -5, -6, -1, -1, 0 ] ], 0 ], + [ [ [ 4, -4, -6, -1, -1, 0 ], [ 6, -4, -6, -1, -1, 0 ], [ 6, -3, -6, -1, -1, 0 ], [ 6, -5, -6, -1, -1, 0 ] ], 0.25 ], + [ [ [ 4, -4, -6, -1, -1, 0 ], [ 6, -4, -6, -1, -1, 0 ], [ 6, -3, -6, -1, -1, 0 ], [ 5, -3, -6, -1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 5, -4, -6, -1, -1, 0 ], [ 6, -4, -6, -1, -1, 0 ], [ 6, -3, -6, -1, -1, 0 ], [ 5, -3, -6, -1, -1, 0 ] ], 0.25 ], + [ [ [ 5, -4, -6, -1, -1, 0 ], [ 5, -2, -6, -1, -1, 0 ], [ 6, -3, -6, -1, -1, 0 ], [ 5, -3, -6, -1, -1, 0 ] ], 0 ], + [ [ [ 5, -4, -6, -1, -1, 0 ], [ 5, -2, -6, -1, -1, 0 ], [ 4, -2, -6, -1, -1, 0 ], [ 5, -3, -6, -1, -1, 0 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ 4, -4, -6, -1, -1, 0 ], [ 6, -4, -6, -1, -1, 0 ], [ 6, -3, -6, -1, -1, 0 ], [ 6, -5, -6, -1, -1, 0 ] ], + [ [ 4, -4, -6, -1, -1, 0 ], [ 6, -4, -6, -1, -1, 0 ], [ 6, -3, -6, -1, -1, 0 ], [ 5, -3, -6, -1, -1, 0 ] ], + [ [ 5, -4, -6, -1, -1, 0 ], [ 6, -4, -6, -1, -1, 0 ], [ 6, -3, -6, -1, -1, 0 ], [ 5, -3, -6, -1, -1, 0 ] ], + [ [ 5, -4, -6, -1, -1, 0 ], [ 5, -2, -6, -1, -1, 0 ], [ 6, -3, -6, -1, -1, 0 ], [ 5, -3, -6, -1, -1, 0 ] ], + [ [ 5, -4, -6, -1, -1, 0 ], [ 5, -2, -6, -1, -1, 0 ], [ 4, -2, -6, -1, -1, 0 ], [ 5, -3, -6, -1, -1, 0 ] ] +], +"cur_uid": "72570de5", +"ref_uid": "nil", +"order_seed": 452681, +"dur_seed": 334488, +"motifs_seed": 928090, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 0 ], [ 3, 1, 2, 2, 3 ], [ ] ], + [ [ 2, 3 ], [ 1, 0, 1, 1, 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 0, 2, 0 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 3, 3, 1 ], [ ] ], + [ [ 3, 2 ], [ 1, 0, 0, 1, 0 ], [ ] ], + [ [ 1, 3, 0 ], [ 2, 2 ], [ ] ], + [ [ 2, 0, 1 ], [ 3, 3, 3, 3 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 0, 3, 1 ], [ 2, 2 ], [ ] ], + [ [ 0 ], [ 1, 3, 2 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 0, 3 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 3, 0 ], [ 2, 1, 2 ], [ ] ], + [ [ 2 ], [ 3, 1, 0, 0 ], [ ] ], + [ [ 1, 0, 3 ], [ 2, 2 ], [ ] ], + [ [ 3, 0, 2 ], [ 1, 1 ], [ ] ], + [ [ 0, 2, 1 ], [ 3, 3, 3 ], [ ] ], + [ [ 2, 1, 0 ], [ 3, 3, 3, 3, 3 ], [ ] ], + [ [ 2, 3, 0 ], [ 1, 1, 1 ], [ ] ], + [ [ 1, 3, 2 ], [ 0, 0 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 2, 2, 3 ], [ ] ], + [ [ 1, 2 ], [ 3, 0, 0, 0 ], [ ] ], + [ [ 0 ], [ 2, 1, 3, 1, 3, 3, 2 ], [ ] ], + [ [ 3, 2, 1 ], [ 0, 0, 0, 0, 0 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 2, 1 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 2 ], [ ] ], + [ [ 3, 1, 2 ], [ 0 ], [ ] ], + [ [ 2, 3 ], [ 1, 0, 1 ], [ ] ], + [ [ 2, 1 ], [ 3, 0, 0, 0 ], [ ] ], + [ [ 3 ], [ 1, 2, 0 ], [ ] ], + [ [ 1, 2, 3 ], [ 0, 0, 0, 0, 0 ], [ ] ], + [ [ 0, 3 ], [ 1, 2, 1, 2, 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 3, 0, 3 ], [ ] ], + [ [ 2, 1 ], [ 0, 3, 0, 0, 0 ], [ ] ], + [ [ 0 ], [ 2, 1, 3, 1, 3, 2 ], [ ] ], + [ [ 0, 2, 3 ], [ 1, 1, 1, 1 ], [ ] ], + [ [ 2, 1 ], [ 0, 3, 3, 0 ], [ ] ], + [ [ 0, 1 ], [ 2, 3, 2, 2, 2 ], [ ] ], + [ [ 2, 1, 0 ], [ 3, 3, 3, 3 ], [ ] ], + [ [ 0, 3 ], [ 1, 2, 1, 2 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 0, 0 ], [ ] ], + [ [ 1, 3, 0 ], [ 2, 2, 2, 2, 2 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 1, 1, 2 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 1, 2, 3 ], [ ] ], + [ [ 3, 1, 2 ], [ 0, 0, 0 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 2 ], [ ] ], + [ [ 0 ], [ 2, 1, 3 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ] +], +"sus_weights": [ 0.7, 0.48, 0.49 ], +"order_size": [ 49, 49.489795918367 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7276dc78/lilypond/part_I.ly b/resources/string_quartet_3_rise/7276dc78/lilypond/part_I.ly index af7f26d..180336b 100644 --- a/resources/string_quartet_3_rise/7276dc78/lilypond/part_I.ly +++ b/resources/string_quartet_3_rise/7276dc78/lilypond/part_I.ly @@ -1,48 +1,48 @@ { - { gis'1^\markup { \pad-markup #0.2 "-11"} } + { ais'1^\markup { \pad-markup #0.2 "-11"} } \bar "|" - { fis1^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} } + { gis1^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} } \bar "|" - { c'1^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + { d'1^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } \bar "|" - { c'2 fis'2^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { d'2 gis'2^\markup { \pad-markup #0.2 "-46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { fis'1 ~ } + { gis'1 ~ } \bar "|" - { fis'1 } + { gis'1 } \bar "|" - { b'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + { cis''1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } \bar "|" - { b'2 g2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + { cis''2 a2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g2 cis'2^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } + { a2 dis'2^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } \bar "|" - { a'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { b'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { a'2 ais'2^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { b'2 c''2^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { ais'1 ~ } + { c''1 ~ } \bar "|" - { ais'1 } + { c''1 } \bar "|" - { ais1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { c'1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { ais1 ~ } + { c'1 ~ } \bar "|" - { ais1 ~ } + { c'1 ~ } \bar "|" - { ais1 ~ } + { c'1 ~ } \bar "|" - { ais2 d'2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + { c'2 e'2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" - { d'2 g'2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { e'2 a'2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { g'2 b'2^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}} + { a'2 cis''2^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7276dc78/lilypond/part_II.ly b/resources/string_quartet_3_rise/7276dc78/lilypond/part_II.ly index b3e65e4..70474f1 100644 --- a/resources/string_quartet_3_rise/7276dc78/lilypond/part_II.ly +++ b/resources/string_quartet_3_rise/7276dc78/lilypond/part_II.ly @@ -1,48 +1,48 @@ { - { d'1^\markup { \pad-markup #0.2 "+38"} ~ } + { e'1^\markup { \pad-markup #0.2 "+38"} ~ } \bar "|" - { d'1 ~ } + { e'1 ~ } \bar "|" - { d'1 } + { e'1 } \bar "|" - { g'1^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + { a'1^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } \bar "|" - { g'1 } + { a'1 } \bar "|" - { b'1^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { cis''1^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { b'2 d'2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }} } + { cis''2 e'2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }} } \bar "|" - { a'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} } + { b'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} } \bar "|" - { f'1^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } + { g'1^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } \bar "|" - { f'1 } + { g'1 } \bar "|" - { f'1^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + { g'1^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } \bar "|" - { f'1 ~ } + { g'1 ~ } \bar "|" - { f'1 } + { g'1 } \bar "|" - { b'1^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} } + { cis''1^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} } \bar "|" - { d'1^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} } + { e'1^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} } \bar "|" - { g1^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { a1^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g2 c'2^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + { a2 d'2^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } \bar "|" - { c'1 ~ } + { d'1 ~ } \bar "|" - { c'2 f'2^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } + { d'2 g'2^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} ~ } \bar "|" - { f'1 ~ } + { g'1 ~ } \bar "|" - { f'1 ~ } + { g'1 ~ } \bar "|" - { f'1} + { g'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7276dc78/lilypond/part_III.ly b/resources/string_quartet_3_rise/7276dc78/lilypond/part_III.ly index 192a5db..e7f6e42 100644 --- a/resources/string_quartet_3_rise/7276dc78/lilypond/part_III.ly +++ b/resources/string_quartet_3_rise/7276dc78/lilypond/part_III.ly @@ -1,48 +1,48 @@ { - { g'1^\markup { \pad-markup #0.2 "+36"} ~ } + { a'1^\markup { \pad-markup #0.2 "+36"} ~ } \bar "|" - { g'2 b'2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + { a'2 cis''2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } \bar "|" - { b'1 ~ } + { cis''1 ~ } \bar "|" - { b'1 } + { cis''1 } \bar "|" - { a1^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } + { b1^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } \bar "|" - { a2 d'2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + { b2 e'2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } \bar "|" - { d'1 ~ } + { e'1 ~ } \bar "|" - { d'1 ~ } + { e'1 ~ } \bar "|" - { d'1 } + { e'1 } \bar "|" - { cis1^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }} ~ } + { dis1^\markup { \pad-markup #0.2 "+50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }} ~ } \bar "|" - { cis2 dis'2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} } + { dis2 f'2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} } \bar "|" - { ais'1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + { c''1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } \bar "|" - { ais'1 ~ } + { c''1 ~ } \bar "|" - { ais'1 ~ } + { c''1 ~ } \bar "|" - { ais'1 ~ } + { c''1 ~ } \bar "|" - { ais'1 ~ } + { c''1 ~ } \bar "|" - { ais'2 d2^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + { c''2 e2^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } \bar "|" - { d1 ~ } + { e1 ~ } \bar "|" - { d2 g2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } + { e2 a2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g1 ~ } + { a1 ~ } \bar "|" - { g1} + { a1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7276dc78/lilypond/part_IV.ly b/resources/string_quartet_3_rise/7276dc78/lilypond/part_IV.ly index 5fd805f..f291f2f 100644 --- a/resources/string_quartet_3_rise/7276dc78/lilypond/part_IV.ly +++ b/resources/string_quartet_3_rise/7276dc78/lilypond/part_IV.ly @@ -1,48 +1,48 @@ { - { ais,2^\markup { \pad-markup #0.2 "+21"} f2^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } + { c2^\markup { \pad-markup #0.2 "+21"} g2^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } \bar "|" - { f1 ~ } + { g1 ~ } \bar "|" - { f2 b2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { g2 cis'2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b2 e'2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + { cis'2 fis'2^\markup { \pad-markup #0.2 "+34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } \bar "|" - { e'1 ~ } + { fis'1 ~ } \bar "|" - { e'1 ~ } + { fis'1 ~ } \bar "|" - { e'1 ~ } + { fis'1 ~ } \bar "|" - { e'2 d2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { fis'2 e2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { d2 a2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + { e2 b2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" - { a1 ~ } + { b1 ~ } \bar "|" - { a1 ~ } + { b1 ~ } \bar "|" - { a2 dis'2^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } + { b2 f'2^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } \bar "|" - { dis'1 ~ } + { f'1 ~ } \bar "|" - { dis'2 g'2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + { f'2 a'2^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } \bar "|" - { g'2 e,2^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } + { a'2 fis,2^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } \bar "|" - { e,1 } + { fis,1 } \bar "|" - { ais,1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} } + { c1^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} } \bar "|" - { e1^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} } + { fis1^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} } \bar "|" - { dis,1^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} } + { f,1^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} } \bar "|" - { b,1^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} } + { cis1^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} } \bar "|" - { c,1^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} } + { d,1^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} } \bar "|" - { f,1^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}} + { g,1^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/731cf7ae/731cf7ae_code.scd b/resources/string_quartet_3_rise/731cf7ae/731cf7ae_code.scd new file mode 100644 index 0000000..e1a9d92 --- /dev/null +++ b/resources/string_quartet_3_rise/731cf7ae/731cf7ae_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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"], {(62.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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/731cf7ae/731cf7ae_mus_model.json b/resources/string_quartet_3_rise/731cf7ae/731cf7ae_mus_model.json new file mode 100644 index 0000000..c595b8a --- /dev/null +++ b/resources/string_quartet_3_rise/731cf7ae/731cf7ae_mus_model.json @@ -0,0 +1,395 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -6, 6, -1, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 3 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -3, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -3, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ], [ -3, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 6, -1, 0, -2, 2 ], [ -3, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -3, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -3, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -5, 7, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 6, -1, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -4, 6, -1, 1, -3, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 7, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 6, -1, 1, -1, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 7, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 7, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -4, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 7, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -5, 7, -1, 1, -2, 2 ], [ -4, 7, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -5, 7, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 2, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 6, -1, 1, -1, 2 ], [ -5, 6, -1, 2, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 7, -1, 1, -2, 2 ], [ -5, 6, -1, 2, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 7, -1, 1, -2, 2 ], [ -5, 7, 0, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 7, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -5, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ], [ -5, 6, 0, 1, -2, 2 ], [ -4, 5, -2, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -4, 5, -2, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 5, -2, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -4, 5, -1, 2, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -4, 5, -1, 2, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -3, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 2, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -3, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 5, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 5, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -3, 5, -1, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 5, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, -2, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 6, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -3, 5, -2, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 6, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 5, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 4, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, 0, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -3, 4, -1, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 6, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 1, -2, 2 ], [ -4, 6, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -4, 6, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -3, 5, 0, 1, -3, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -3, 6, -1, 0, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -4, 6, 0, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -3, 6, 0, 0, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, 0, 1, -2, 2 ], [ -3, 6, 0, 0, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -3, 5, 0, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -3, 6, 0, 0, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -3, 5, 0, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -3, 6, 0, 0, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 6, 1, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -3, 6, 0, 0, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 7, 0, 0, -2, 2 ] ], 0 ], + [ [ [ -6, 7, 0, 0, -2, 2 ], [ -3, 6, 0, 0, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -4, 7, 0, 0, -2, 2 ] ], 0.25 ], + [ [ [ -6, 7, 0, 0, -2, 2 ], [ -3, 6, 0, 0, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -3, 6, 0, 0, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 6, 0, 0, -3, 2 ], [ -3, 6, 0, 0, -2, 2 ], [ -4, 5, 0, 1, -2, 2 ], [ -3, 6, 0, 0, -3, 2 ] ], 0 ], + [ [ [ -5, 6, 0, 0, -3, 2 ], [ -3, 6, 0, 0, -2, 2 ], [ -4, 6, 0, 0, -3, 2 ], [ -3, 6, 0, 0, -3, 2 ] ], 0 ], + [ [ [ -5, 6, 0, 0, -3, 2 ], [ -3, 6, 0, 0, -2, 2 ], [ -4, 6, 0, 0, -3, 2 ], [ -4, 6, 0, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, 0, 0, -3, 2 ], [ -3, 6, 0, 0, -2, 2 ], [ -4, 6, 0, 0, -3, 2 ], [ -2, 6, 0, 0, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -2, 2 ], [ -4, 6, 0, 0, -3, 2 ], [ -2, 6, 0, 0, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -3, 7, 0, 0, -3, 2 ], [ -4, 6, 0, 0, -3, 2 ], [ -2, 6, 0, 0, -3, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -2, 6, -1, 0, -3, 2 ], [ -4, 6, 0, 0, -3, 2 ], [ -2, 6, 0, 0, -3, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -2, 6, 0, 0, -4, 2 ], [ -4, 6, 0, 0, -3, 2 ], [ -2, 6, 0, 0, -3, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -2, 6, 0, -1, -3, 2 ], [ -4, 6, 0, 0, -3, 2 ], [ -2, 6, 0, 0, -3, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -3, 2 ], [ -4, 6, 0, 0, -3, 2 ], [ -2, 6, 0, 0, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -4, 6, 0, 0, -1, 2 ], [ -4, 6, 0, 0, -3, 2 ], [ -2, 6, 0, 0, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -4, 6, 0, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -2, 6, 0, 0, -3, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -4, 6, 0, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -6, 7, 0, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -5, 6, -1, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -6, 6, 0, 1, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -4, 6, 0, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -3, 6, 0, -1, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -4, 6, 1, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -3, 5, 0, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -4, 7, 0, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -4, 7, 0, 0, -1, 2 ], [ -6, 8, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -4, 7, 0, 0, -1, 2 ], [ -5, 7, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -4, 7, 0, 0, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -4, 7, 0, 0, -1, 2 ], [ -4, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -4, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -4, 6, 0, -1, -1, 2 ], [ -4, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -5, 6, 1, 0, -1, 2 ], [ -4, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -4, 5, 0, 0, -1, 2 ], [ -4, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0 ], + [ [ [ -6, 6, 0, 0, -1, 2 ], [ -4, 5, 0, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -4, 5, 0, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -4, 6, 0, 0, -1, 2 ], [ -4, 5, 0, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -3, 6, 0, -1, -1, 2 ], [ -4, 5, 0, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -4, 6, 1, 0, -1, 2 ], [ -4, 5, 0, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 6, 1, 0, -1, 2 ], [ -5, 6, 1, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -4, 6, 1, 0, -1, 2 ], [ -4, 6, 1, -1, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -4, 6, 1, 0, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -5, 6, 0, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 6, 1, 0, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -4, 5, -1, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -4, 6, 1, 0, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -4, 6, 0, -1, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -4, 6, 1, 0, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -5, 7, -1, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 7, -1, 0, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -5, 7, -1, 0, -1, 2 ], [ -3, 6, 0, 0, -1, 2 ] ], 0 ], + [ [ [ -4, 7, -1, 0, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -5, 7, -1, 0, -1, 2 ], [ -4, 7, -1, 1, -1, 2 ] ], 0.25 ], + [ [ [ -4, 6, -1, 0, -1, 3 ], [ -4, 6, -1, 0, -1, 2 ], [ -5, 7, -1, 0, -1, 2 ], [ -4, 7, -1, 1, -1, 2 ] ], 0.25 ], + [ [ [ -4, 6, -1, 1, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -5, 7, -1, 0, -1, 2 ], [ -4, 7, -1, 1, -1, 2 ] ], 0.25 ], + [ [ [ -4, 6, -1, 1, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -5, 7, -1, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -3, 6, -2, 0, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -5, 7, -1, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 6, -2, 0, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -5, 7, -1, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 4, -1, 0, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -5, 7, -1, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 4, -1, 0, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -4, 5, -1, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 4, -1, 0, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -3, 5, -1, -1, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 4, -1, 0, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -4, 5, 0, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -3, 5, 0, 0, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -4, 5, 0, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 5, -1, -1, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -4, 5, 0, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -2, 5, -1, -1, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -4, 5, -2, 1, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 5, -1, -1, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -3, 4, -1, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 5, -1, -1, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -3, 5, -3, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 5, -1, -1, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -3, 5, -1, -1, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -2, 5, -1, -1, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 5, -1, 0, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0 ], + [ [ [ -3, 5, -1, 0, -1, 2 ], [ -4, 5, -1, 1, -1, 2 ], [ -3, 4, -2, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0 ], + [ [ [ -3, 5, -1, 0, -1, 2 ], [ -4, 5, -1, 1, -1, 2 ], [ -4, 5, -1, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -4, 5, -1, 1, -1, 2 ], [ -4, 5, -1, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -1, 2 ], [ -4, 5, -1, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -2, 5, -1, -1, -1, 2 ], [ -4, 5, -1, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -2, 5, -1, -1, -1, 2 ], [ -4, 5, -1, 0, -1, 2 ], [ -2, 5, -1, -1, -1, 3 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -2, 5, -1, -1, -1, 2 ], [ -4, 5, -1, 0, -1, 2 ], [ -2, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -2, 5, -1, -1, -1, 2 ], [ -4, 5, -1, 0, -1, 2 ], [ -2, 4, -1, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, 0, 0, -1, 2 ], [ -4, 5, -1, 0, -1, 2 ], [ -2, 4, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, 0, 0, -1, 2 ], [ -4, 5, -1, 0, -1, 2 ], [ -3, 6, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, 0, 0, -1, 2 ], [ -4, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -1, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -2, 4, -1, 0, -1, 2 ], [ -4, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 6, -1, 0, -1, 2 ], [ -4, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -4, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -1, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -5, 7, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -1, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -5, 7, -1, 0, -1, 2 ], [ -4, 7, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -4, 6, -1, 0, -2, 2 ], [ -4, 7, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -4, 6, -1, 0, -2, 2 ], [ -3, 6, -1, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -4, 6, -1, 0, -1, 2 ], [ -4, 6, -2, 0, -1, 2 ], [ -3, 6, -1, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -4, 6, -2, 0, -1, 2 ], [ -3, 6, -1, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -4, 6, -2, 0, -1, 2 ], [ -3, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -3, 4, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -1, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -3, 4, -1, 0, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -3, 4, -1, 0, -1, 2 ], [ -4, 5, -1, 1, -1, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -3, 4, -1, 0, -1, 2 ], [ -4, 5, -1, 0, -1, 3 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -3, 4, -1, 0, -1, 2 ], [ -2, 5, -1, 0, -2, 1 ] ], 0 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -2, 5, -1, 0, -2, 1 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 0, -1, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -3, 6, -1, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -4, 5, -1, 1, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -1, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 5, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 5, 0, 0, -1, 2 ] ], 0.25 ], + [ [ [ -5, 5, -1, 0, -1, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 5, -1, 0, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 5, -2, 0, 0, 2 ], [ -3, 5, -2, 0, -1, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 5, -1, 0, 0, 2 ] ], 0 ], + [ [ [ -5, 5, -2, 0, 0, 2 ], [ -3, 6, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 5, -1, 0, 0, 2 ] ], 0.25 ], + [ [ [ -5, 5, -2, 1, -2, 2 ], [ -3, 6, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 5, -1, 0, 0, 2 ] ], 0 ], + [ [ [ -5, 5, -2, 1, -2, 2 ], [ -4, 5, -1, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 5, -1, 0, 0, 2 ] ], 0.25 ], + [ [ [ -4, 5, -2, 0, -2, 2 ], [ -4, 5, -1, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 5, -1, 0, 0, 2 ] ], 0.25 ] + ], + [ + [ [ [ -4, 5, -2, 0, -2, 2 ], [ -4, 5, -1, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 5, -1, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -4, 5, -1, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 5, -1, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -4, 5, -1, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -1, 5, -1, -1, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -4, 5, -1, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 7, -1, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 7, -1, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -3, 7, -1, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 7, -1, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 6, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -4, 6, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 6, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -3, 5, -3, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -2, 6, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -3, 5, -3, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -1, 5, -3, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -4, 6, -2, 0, -2, 2 ], [ -3, 5, -2, 0, -2, 2 ], [ -1, 5, -3, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -4, 6, -2, 0, -2, 2 ], [ -4, 6, -1, 0, -2, 2 ], [ -1, 5, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -4, 6, -2, 0, -2, 2 ], [ -4, 6, -1, 0, -2, 2 ], [ -3, 6, -1, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 7, -1, 0, -2, 2 ], [ -4, 6, -1, 0, -2, 2 ], [ -3, 6, -1, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 7, -1, 0, -2, 2 ], [ -3, 7, -1, 0, -2, 2 ], [ -3, 6, -1, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 7, -1, 0, -2, 2 ], [ -3, 7, -1, 0, -2, 2 ], [ -4, 8, -1, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 7, -1, 0, -2, 2 ], [ -3, 7, -1, 0, -2, 2 ], [ -4, 7, -1, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 7, -1, 0, -2, 2 ], [ -3, 7, -1, 0, -2, 2 ], [ -4, 6, -1, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 7, -1, 0, -2, 2 ], [ -3, 7, -1, 0, -2, 2 ], [ -5, 8, -1, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 7, -1, 0, -2, 2 ], [ -3, 7, -1, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 6, -1, 0, -2, 2 ], [ -5, 7, -1, 0, -2, 2 ], [ -2, 6, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 7, -3, 0, -2, 2 ], [ -5, 7, -1, 0, -2, 2 ], [ -2, 6, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 7, -3, 0, -2, 2 ], [ -4, 6, -2, 0, -2, 2 ], [ -2, 6, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -5, 7, -3, 0, -2, 2 ], [ -4, 6, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 7, -3, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -3, 7, -2, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -5, 7, -3, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -3, 7, -3, 0, -1, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -5, 7, -3, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 8, -2, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ], [ -4, 7, -2, 0, -2, 2 ] ], 0 ], + [ [ [ -6, 8, -2, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ], [ -5, 9, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 8, -2, 0, -2, 2 ], [ -5, 9, -2, 0, -3, 2 ], [ -3, 8, -3, 0, -2, 2 ], [ -5, 9, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -6, 8, -2, 0, -2, 2 ], [ -5, 9, -3, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ], [ -5, 9, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -6, 8, -2, 0, -2, 2 ], [ -6, 10, -2, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ], [ -5, 9, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -6, 8, -2, 0, -2, 2 ], [ -4, 7, -3, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ], [ -5, 9, -2, 0, -2, 2 ] ], 0.25 ], + [ [ [ -6, 8, -2, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ], [ -5, 9, -2, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -6, 8, -2, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ], [ -4, 8, -3, 0, -2, 2 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ -6, 8, -2, 0, -2, 2 ], [ -5, 9, -3, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ], [ -5, 9, -2, 0, -2, 2 ] ], + [ [ -6, 8, -2, 0, -2, 2 ], [ -6, 10, -2, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ], [ -5, 9, -2, 0, -2, 2 ] ], + [ [ -6, 8, -2, 0, -2, 2 ], [ -4, 7, -3, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ], [ -5, 9, -2, 0, -2, 2 ] ], + [ [ -6, 8, -2, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ], [ -5, 9, -2, 0, -2, 2 ] ], + [ [ -6, 8, -2, 0, -2, 2 ], [ -5, 8, -2, 0, -2, 2 ], [ -3, 8, -3, 0, -2, 2 ], [ -4, 8, -3, 0, -2, 2 ] ] +], +"cur_uid": "731cf7ae", +"ref_uid": "4f53a446", +"order_seed": 192987, +"dur_seed": 454936, +"motifs_seed": 709798, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 1.0164835164835, 0.0098039215686275, 0, 0.20915032679739, 0, 0.24183006535948, 0.82432432432432, 0.28758169934641, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 1.0164835164835, 0.0098039215686275, 0, 0.20915032679739, 0, 0.24183006535948, 0.82432432432432, 0.28758169934641, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 1.0164835164835, 0.0098039215686275, 0, 0.20915032679739, 0, 0.24183006535948, 0.82432432432432, 0.28758169934641, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 0, 2, 3 ], [ 1, 1, 1, 1 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 2, 2, 2 ], [ ] ], + [ [ 1, 0 ], [ 3, 2 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 0, 1, 1, 1 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 2, 2, 1, 2 ], [ ] ], + [ [ 0, 3 ], [ 1, 2, 1 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 3, 2 ], [ 0, 1, 1, 0 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 2, 3, 2, 1 ], [ ] ], + [ [ 1, 0, 3 ], [ 2 ], [ ] ], + [ [ 0, 2 ], [ 1, 3, 3, 1, 1 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 2, 0, 3 ], [ ] ], + [ [ 1, 3 ], [ 0, 2, 0, 0, 0, 0 ], [ ] ], + [ [ 3, 1 ], [ 2, 0 ], [ ] ], + [ [ 2, 3 ], [ 0, 1, 0, 1, 1, 1 ], [ ] ], + [ [ 2, 3, 0 ], [ 1, 1 ], [ ] ], + [ [ 2, 1 ], [ 3, 0, 3, 3, 0, 3 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 3 ], [ ] ], + [ [ 1, 3, 2 ], [ 0 ], [ ] ], + [ [ 0, 3, 2 ], [ 1, 1, 1, 1, 1 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 0, 1 ], [ 2, 3 ], [ ] ], + [ [ 0, 2, 3 ], [ 1, 1, 1 ], [ ] ], + [ [ 3, 2, 0 ], [ 1, 1, 1, 1, 1 ], [ ] ], + [ [ 1, 0, 3 ], [ 2, 2, 2 ], [ ] ], + [ [ 0, 3 ], [ 2, 1, 1, 1, 1, 2 ], [ ] ], + [ [ 2, 1, 3 ], [ 0, 0, 0, 0 ], [ ] ], + [ [ 0, 2, 3 ], [ 1, 1, 1 ], [ ] ], + [ [ 3, 0, 1 ], [ 2, 2, 2 ], [ ] ], + [ [ 1, 2 ], [ 0, 3, 0, 0, 3, 0 ], [ ] ], + [ [ 3 ], [ 1, 0, 2, 2, 2, 0, 0 ], [ ] ], + [ [ 0, 1, 3 ], [ 2, 2, 2, 2, 2 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 0, 1, 1 ], [ ] ], + [ [ 1, 2, 0 ], [ 3, 3, 3 ], [ ] ], + [ [ 2, 0 ], [ 1, 3, 3, 1, 1, 1 ], [ ] ], + [ [ 1, 0 ], [ 2, 3, 2, 3, 2 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 3, 3, 3 ], [ ] ], + [ [ 1, 0 ], [ 3, 2, 3, 3, 3, 2 ], [ ] ], + [ [ 0, 2 ], [ 1, 3, 3 ], [ ] ], + [ [ 3, 2 ], [ 0, 1, 0, 1, 0 ], [ ] ], + [ [ 1, 2 ], [ 3, 0, 3 ], [ ] ], + [ [ 0, 2 ], [ 3, 1, 3, 1, 1, 3 ], [ ] ], + [ [ 0 ], [ 1, 2, 3, 1, 2 ], [ ] ], + [ [ 0, 1, 2 ], [ 3, 3, 3, 3, 3 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 2 ], [ ] ], + [ [ 2, 3, 0 ], [ 1 ], [ ] ], + [ [ 3, 1, 0 ], [ 2, 2 ], [ ] ], + [ [ 1, 2 ], [ 0, 3 ], [ ] ], + [ [ 3, 0, 2 ], [ 1, 1, 1, 1, 1 ], [ ] ], + [ [ 2, 1, 0 ], [ 3 ], [ ] ] +], +"sus_weights": [ 0.7, 0.48, 0.49 ], +"order_size": [ 50, 50.5 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/731cf7ae/lilypond/part_I.ly b/resources/string_quartet_3_rise/731cf7ae/lilypond/part_I.ly new file mode 100644 index 0000000..de07d79 --- /dev/null +++ b/resources/string_quartet_3_rise/731cf7ae/lilypond/part_I.ly @@ -0,0 +1,40 @@ +{ + { gis2^\markup { \pad-markup #0.2 "-27"} gis''2^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } + \bar "|" + { gis1^\markup { \pad-markup #0.2 "-27"} ~ } + \bar "|" + { gis2. ~ gis8[ a8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] } + \bar "|" + { gis'2^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} a'8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}[ g'8^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] ~ g'4 } + \bar "|" + { a'8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ gis'8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ gis'2. ~ } + \bar "|" + { gis'2. ~ gis'8[ g'8^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] } + \bar "|" + { fis'8^\markup { \pad-markup #0.2 "-24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}[ a'8^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] gis'8^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }}[ d'8^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] gis''2^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { gis''2 ~ gis''8[ g''8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ g''4 ~ } + \bar "|" + { g''1 ~ } + \bar "|" + { g''1 ~ } + \bar "|" + { g''2. ~ g''8[ gis''8^\markup { \pad-markup #0.2 "+26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ } + \bar "|" + { gis''4 a''2.^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { a''1 ~ } + \bar "|" + { a''4 ~ a''8[ g''8^\markup { \pad-markup #0.2 "+25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}] a''8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ d''8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ d''8[ e''8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] } + \bar "|" + { a'4^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ a'8[ b'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ b'8[ ais'8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] a'8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ f'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] } + \bar "|" + { fis'8^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}[ f'8^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}] g'8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↓" }}[ a'8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ais'8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}[ b'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] c''8^\markup { \pad-markup #0.2 "+40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}[ d''8^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ } + \bar "|" + { d''4 ~ d''8[ dis''8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] f''8^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }}[ f''8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] fis''4^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} } + \bar "|" + { g''4^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ais'4^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} c''8^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}[ f'8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ais8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ c'8^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] } + \bar "|" + { cis'2.^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} dis'4^\markup { \pad-markup #0.2 "+23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/731cf7ae/lilypond/part_II.ly b/resources/string_quartet_3_rise/731cf7ae/lilypond/part_II.ly new file mode 100644 index 0000000..123f769 --- /dev/null +++ b/resources/string_quartet_3_rise/731cf7ae/lilypond/part_II.ly @@ -0,0 +1,40 @@ +{ + { cis'2^\markup { \pad-markup #0.2 "-29"} gis8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ ais8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }}] c'8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}[ cis'8^\markup { \pad-markup #0.2 "-29"}] } + \bar "|" + { dis'8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}[ e'8^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] ~ e'2 dis'8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}[ c''8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] } + \bar "|" + { cis''8^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}[ dis''8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}] gis'4^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} c'4^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ c'8[ cis'8^\markup { \pad-markup #0.2 "-29"}] } + \bar "|" + { f'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}[ fis'8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ fis'8[ e'8^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}] ~ e'2 } + \bar "|" + { dis'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }}[ f'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}] ~ f'8[ fis'8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] ~ fis'4 ~ fis'8[ f'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'4 ~ f'8[ gis8^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ gis2 ~ } + \bar "|" + { gis2 g2^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g2. a8^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}[ d'8^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] } + \bar "|" + { e'8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}[ g'8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ g'4 g2^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { g2 a8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}[ ais8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}] b4^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { b2. a8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ b8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}] } + \bar "|" + { c'4^\markup { \pad-markup #0.2 "+40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} ~ c'8[ d'8^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}] d'8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}[ cis'8^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] b8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ ais8^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] } + \bar "|" + { a1^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a4 ~ a8[ b8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ais8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }}[ c'8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] ~ c'8[ d'8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { d'4 cis'4^\markup { \pad-markup #0.2 "-29"} ~ cis'8[ b8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ b4 ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b4 ais8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ f''8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ f''2 ~ } + \bar "|" + { f''8[ fis''8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] cis''4^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} dis''8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}[ e''8^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ e''4} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/731cf7ae/lilypond/part_III.ly b/resources/string_quartet_3_rise/731cf7ae/lilypond/part_III.ly new file mode 100644 index 0000000..42ac89b --- /dev/null +++ b/resources/string_quartet_3_rise/731cf7ae/lilypond/part_III.ly @@ -0,0 +1,40 @@ +{ + { a'8^\markup { \pad-markup #0.2 "-16"}[ gis'8^\markup { \pad-markup #0.2 "-27"}] a'8^\markup { \pad-markup #0.2 "+11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }}[ gis'8^\markup { \pad-markup #0.2 "-27"}] ~ gis'2 ~ } + \bar "|" + { gis'8[ cis'8^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] d'8^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }}[ dis'8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}] cis'8^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↑" }}[ c'8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }}] ~ c'4 } + \bar "|" + { cis'4^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} dis'8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ f'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] f'8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}[ g'8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] gis'8^\markup { \pad-markup #0.2 "-27"}[ a'8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ } + \bar "|" + { a'4 ais'4^\markup { \pad-markup #0.2 "+40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} cis''4^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} d''8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }}[ cis''8^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''8[ c''8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] b'8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }}[ ais'8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}] c''8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ cis''8^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] d''4^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { d''2. dis''8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}[ f''8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] } + \bar "|" + { dis''8^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }}[ b'8^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }}] gis'8^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ g'8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ g'4 d8^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ e8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] } + \bar "|" + { f8^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}[ g'8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ais'8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}[ b'8^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] c''8^\markup { \pad-markup #0.2 "+40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}[ d''8^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ d''4 ~ } + \bar "|" + { d''8[ g8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ais8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}[ b8^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] c'2^\markup { \pad-markup #0.2 "+40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { c'8[ b8^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] d'8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}[ e'8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] ~ e'2 ~ } + \bar "|" + { e'2 f'2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { f'1 } + \bar "|" + { fis'8^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}[ a'8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] b'2^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} c''4^\markup { \pad-markup #0.2 "+40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} } + \bar "|" + { d''8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}[ e''8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] e'2^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} dis'4^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + \bar "|" + { dis'2. f'4^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} } + \bar "|" + { fis'8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}[ dis8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }}] ~ dis4 ~ dis8[ f8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] fis8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ g8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] ~ } + \bar "|" + { g8[ fis8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] f2.^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { f4 fis8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ gis8^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] ~ gis4 ~ gis8[ ais8^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }}]} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/731cf7ae/lilypond/part_IV.ly b/resources/string_quartet_3_rise/731cf7ae/lilypond/part_IV.ly new file mode 100644 index 0000000..86941cb --- /dev/null +++ b/resources/string_quartet_3_rise/731cf7ae/lilypond/part_IV.ly @@ -0,0 +1,40 @@ +{ + { gis,2^\markup { \pad-markup #0.2 "-27"} cis''2^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { cis''8[ gis'8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ais,2^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} c4^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c2 cis8^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↑" }}[ dis8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}] cis4^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { cis1 } + \bar "|" + { a8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}[ gis8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] g8^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }}[ fis8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] cis'8^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ c'8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }}] cis'4^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} } + \bar "|" + { d'8^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }}[ cis8^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] c2^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ c8[ ais,8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] ~ } + \bar "|" + { ais,8[ a,8^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ a,8[ gis,8^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ gis,8[ g,8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }}] ~ g,4 ~ } + \bar "|" + { g,1 ~ } + \bar "|" + { g,1 ~ } + \bar "|" + { g,2 ~ g,8[ a,8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] g'8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ ais'8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }}] } + \bar "|" + { b'2.^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} ~ b'8[ b'8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] } + \bar "|" + { c''8^\markup { \pad-markup #0.2 "-4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}[ cis''8^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}] ~ cis''8[ c''8^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] ~ c''8[ d''8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}] ~ d''4 ~ } + \bar "|" + { d''8[ c''8^\markup { \pad-markup #0.2 "+40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] b'2.^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} } + \bar "|" + { a'8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ a,8^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ a,2. ~ } + \bar "|" + { a,1 ~ } + \bar "|" + { a,1 } + \bar "|" + { ais,8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }}[ a,8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }}] b,8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ ais,8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ ais,2 ~ } + \bar "|" + { ais,1 ~ } + \bar "|" + { ais,4 a,2^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} gis,4^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7648bbc0/7648bbc0_code.scd b/resources/string_quartet_3_rise/7648bbc0/7648bbc0_code.scd new file mode 100644 index 0000000..070e09d --- /dev/null +++ b/resources/string_quartet_3_rise/7648bbc0/7648bbc0_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/7648bbc0/7648bbc0_mus_model.json b/resources/string_quartet_3_rise/7648bbc0/7648bbc0_mus_model.json new file mode 100644 index 0000000..e197edd --- /dev/null +++ b/resources/string_quartet_3_rise/7648bbc0/7648bbc0_mus_model.json @@ -0,0 +1,164 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -2, 2 ], [ -7, 5, 1, 4, 0, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 1 ], + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, 0, 2 ], [ -6, 5, 1, 4, -2, 2 ] ], 1 ], + [ [ [ -9, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, 0, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, 0, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -8, 5, 1, 4, 0, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -8, 6, 1, 5, -1, 2 ], [ -8, 5, 1, 4, 0, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -8, 6, 1, 5, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -8, 5, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -8, 6, 1, 5, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 6, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -8, 5, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -9, 7, 1, 4, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -8, 5, 1, 4, -1, 2 ], [ -8, 7, 1, 4, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 5, 1, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -7, 6, 0, 4, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 6, 1, 3, -1, 2 ], [ -7, 5, 1, 4, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -8, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 6, 1, 4, -1, 2 ] ], 1 ], + [ [ [ -8, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 5, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 7, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 7, 1, 3, -1, 2 ], [ -8, 6, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 1, 2, -1, 2 ], [ -8, 6, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ], + [ [ [ -7, 6, 1, 2, -1, 2 ], [ -7, 6, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -8, 7, 1, 3, -1, 2 ] ], 1 ], + [ [ [ -7, 7, 1, 3, -1, 2 ], [ -7, 6, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 8, 1, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -7, 6, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -6, 6, 1, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -6, 6, 1, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ] ], 1 ], + [ [ [ -7, 6, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -8, 8, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -7, 7, 1, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -8, 8, 2, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 7, 1, 3, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -8, 8, 2, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 7, 1, 3, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -8, 8, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -7, 7, 1, 3, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -6, 6, 2, 2, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ], [ -7, 6, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 1, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ], [ -6, 7, 1, 2, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 7, 1, 3, -2, 2 ], [ -7, 7, 1, 3, -2, 2 ], [ -6, 7, 1, 2, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -9, 7, 1, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -6, 7, 1, 2, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -9, 7, 1, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -7, 7, 3, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -9, 7, 1, 3, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -7, 7, 2, 3, -2, 2 ] ], 1 ], + [ [ [ -8, 7, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -8, 8, 2, 2, -2, 2 ] ], 1 ] + ], + [ + [ [ [ -7, 6, 2, 2, -2, 2 ], [ -6, 7, 2, 2, -2, 2 ], [ -8, 7, 2, 3, -2, 2 ], [ -8, 8, 2, 2, -2, 2 ] ], 1 ] + ] + ] +], +"last_changes": +[ + [ [ -8, 7, 0, 2, -1, 2 ], [ -7, 8, 1, 2, -1, 2 ], [ -7, 7, 2, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ] ], + [ [ -8, 7, 0, 2, -1, 2 ], [ -7, 8, 1, 2, -1, 2 ], [ -8, 8, 1, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ] ], + [ [ -8, 7, 0, 2, -1, 2 ], [ -6, 7, 0, 2, -1, 2 ], [ -8, 8, 1, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ] ], + [ [ -8, 7, 0, 2, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -8, 8, 1, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ] ], + [ [ -9, 7, 1, 3, -1, 2 ], [ -7, 7, 1, 3, -1, 2 ], [ -8, 8, 1, 2, -1, 2 ], [ -7, 7, 1, 2, -1, 2 ] ] +], +"cur_uid": "7648bbc0", +"ref_uid": "47bdba0e", +"order_seed": 734985, +"dur_seed": 326609, +"motifs_seed": 719227, +"entrances_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"passages_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"exits_probs_vals": [ 0.66, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.50326797385621, 0, 0.5359477124183, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0.0041152263374486, 0.0056818181818179, 0.080246913580247, 0.02840909090909, 0.20781893004115, 0.028409090909091, 0.41152263374486, 0, 0.44650205761317, 0.16477272727273, 0.47736625514403, 0, 0.53086419753086, 0, 0.54320987654321, 0.92045454545455, 0.58641975308642, 0.92613636363636, 0.61111111111111, 0, 0.7880658436214, 0.034090909090909, 1, 0.034090909090909 ], +"passages_weights": [ 0.58, 1, 0.43, 1, 0.82 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 3 ], [ 2, 0, 1, 1, 2, 2 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 3 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 1, 0, 1 ], [ ] ], + [ [ 0 ], [ 1, 2, 3, 2, 3 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 3 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 2, 2 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 2, 1 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 2, 2, 3 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 2 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 3, 2 ], [ 0, 1, 1, 1 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 2 ], [ ] ], + [ [ 3 ], [ 0, 1, 2 ], [ ] ], + [ [ 2 ], [ 3, 1, 0, 3, 0, 3 ], [ ] ], + [ [ 2 ], [ 0, 1, 3, 0, 1, 0 ], [ ] ], + [ [ 2, 1 ], [ 0, 3, 3, 0, 3, 3, 0 ], [ ] ], + [ [ 2 ], [ 0, 3, 1, 1, 1, 3 ], [ ] ], + [ [ 3, 2 ], [ 0, 1, 1, 1, 0, 1, 0 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 3, 0, 3, 0, 0 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 0, 0, 2, 0, 0 ], [ ] ], + [ [ 2 ], [ 3, 1, 0, 3, 0, 1, 0, 1 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 0, 2, 2, 1, 0 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 3, 3, 1, 0, 0 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 3, 3, 1, 0, 3 ], [ ] ], + [ [ 3, 0 ], [ 1, 2, 2 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 0 ], [ 1, 2, 3, 3 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 2, 2, 1, 1, 0 ], [ ] ] +], +"sus_weights": [ 0.69, 0.17, 0 ], +"order_size": [ 28, 28.275510204082 ], +"passages_size": [ 0, 6 ], +"motif_edited": "true", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/766771df/766771df_code.scd b/resources/string_quartet_3_rise/766771df/766771df_code.scd new file mode 100644 index 0000000..e1a9d92 --- /dev/null +++ b/resources/string_quartet_3_rise/766771df/766771df_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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"], {(62.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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/766771df/766771df_mus_model.json b/resources/string_quartet_3_rise/766771df/766771df_mus_model.json new file mode 100644 index 0000000..608e914 --- /dev/null +++ b/resources/string_quartet_3_rise/766771df/766771df_mus_model.json @@ -0,0 +1,64 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -3, 6, -2, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ], [ -3, 5, -2, 1, -3, 2 ], [ -4, 6, -2, 1, -3, 2 ] ], 0.625 ], + [ [ [ -3, 6, -2, 1, -3, 2 ], [ -4, 7, -2, 1, -3, 2 ], [ -3, 5, -2, 1, -3, 2 ], [ -4, 6, -2, 1, -3, 2 ] ], 0 ], + [ [ [ -3, 6, -2, 1, -3, 2 ], [ -4, 7, -2, 1, -3, 2 ], [ -3, 6, -2, 1, -3, 1 ], [ -4, 6, -2, 1, -3, 2 ] ], 0.625 ], + [ [ [ -3, 6, -2, 1, -3, 2 ], [ -4, 7, -2, 1, -3, 2 ], [ -3, 7, -2, 1, -3, 2 ], [ -4, 6, -2, 1, -3, 2 ] ], 0.75 ], + [ [ [ -3, 6, -2, 1, -3, 2 ], [ -4, 7, -2, 1, -3, 2 ], [ -3, 6, -2, 1, -2, 2 ], [ -4, 6, -2, 1, -3, 2 ] ], 0.875 ] + ], + [ + [ [ [ -4, 8, -2, 1, -3, 2 ], [ -4, 7, -2, 1, -3, 2 ], [ -3, 6, -2, 1, -2, 2 ], [ -4, 6, -2, 1, -3, 2 ] ], 0.875 ] + ], + [ + [ [ [ -4, 8, -2, 1, -3, 2 ], [ -4, 7, -2, 1, -3, 2 ], [ -3, 6, -2, 1, -2, 2 ], [ -5, 8, -2, 1, -3, 2 ] ], 0.625 ], + [ [ [ -4, 8, -2, 1, -3, 2 ], [ -4, 7, -2, 1, -3, 2 ], [ -3, 7, -2, 1, -3, 2 ], [ -5, 8, -2, 1, -3, 2 ] ], 0.625 ], + [ [ [ -5, 7, -2, 1, -3, 2 ], [ -4, 7, -2, 1, -3, 2 ], [ -3, 7, -2, 1, -3, 2 ], [ -5, 8, -2, 1, -3, 2 ] ], 0 ], + [ [ [ -5, 7, -2, 1, -3, 2 ], [ -4, 7, -2, 1, -3, 2 ], [ -3, 7, -2, 1, -3, 2 ], [ -4, 7, -3, 1, -3, 2 ] ], 0 ], + [ [ [ -5, 7, -2, 1, -3, 2 ], [ -4, 7, -2, 1, -3, 2 ], [ -4, 8, -2, 1, -3, 2 ], [ -4, 7, -3, 1, -3, 2 ] ], 0.75 ], + [ [ [ -5, 8, -2, 1, -3, 2 ], [ -4, 7, -2, 1, -3, 2 ], [ -4, 8, -2, 1, -3, 2 ], [ -4, 7, -3, 1, -3, 2 ] ], 0.5 ] + ], + [ + [ [ [ -5, 8, -2, 1, -3, 2 ], [ -4, 8, -2, 1, -4, 2 ], [ -4, 8, -2, 1, -3, 2 ], [ -4, 7, -3, 1, -3, 2 ] ], 0.5 ], + [ [ [ -5, 7, -3, 2, -3, 2 ], [ -4, 8, -2, 1, -4, 2 ], [ -4, 8, -2, 1, -3, 2 ], [ -4, 7, -3, 1, -3, 2 ] ], 0.75 ], + [ [ [ -4, 7, -4, 1, -3, 2 ], [ -4, 8, -2, 1, -4, 2 ], [ -4, 8, -2, 1, -3, 2 ], [ -4, 7, -3, 1, -3, 2 ] ], 0.75 ], + [ [ [ -5, 8, -3, 1, -3, 2 ], [ -4, 8, -2, 1, -4, 2 ], [ -4, 8, -2, 1, -3, 2 ], [ -4, 7, -3, 1, -3, 2 ] ], 0.875 ] + ] + ] +], +"last_changes": +[ + [ [ -5, 8, -2, 1, -3, 2 ], [ -4, 7, -2, 1, -3, 2 ], [ -4, 8, -2, 1, -3, 2 ], [ -4, 7, -3, 1, -3, 2 ] ], + [ [ -5, 8, -2, 1, -3, 2 ], [ -4, 8, -2, 1, -4, 2 ], [ -4, 8, -2, 1, -3, 2 ], [ -4, 7, -3, 1, -3, 2 ] ], + [ [ -5, 7, -3, 2, -3, 2 ], [ -4, 8, -2, 1, -4, 2 ], [ -4, 8, -2, 1, -3, 2 ], [ -4, 7, -3, 1, -3, 2 ] ], + [ [ -4, 7, -4, 1, -3, 2 ], [ -4, 8, -2, 1, -4, 2 ], [ -4, 8, -2, 1, -3, 2 ], [ -4, 7, -3, 1, -3, 2 ] ], + [ [ -5, 8, -3, 1, -3, 2 ], [ -4, 8, -2, 1, -4, 2 ], [ -4, 8, -2, 1, -3, 2 ], [ -4, 7, -3, 1, -3, 2 ] ] +], +"cur_uid": "766771df", +"ref_uid": 62918688, +"order_seed": 361964, +"dur_seed": 868549, +"motifs_seed": 455097, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 3, 0.0098039215686275, 0, 0.065359477124183, 0, 0.20588235294118, 0.79391891891892, 0.34967320261438, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 3, 0.0098039215686275, 0, 0.065359477124183, 0, 0.20588235294118, 0.79391891891892, 0.34967320261438, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 3, 0.0098039215686275, 0, 0.065359477124183, 0, 0.20588235294118, 0.79391891891892, 0.34967320261438, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 3 ], [ 0, 1, 2, 2, 2 ], [ ] ], + [ [ 1, 2, 3 ], [ 0 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 3, 2, 0 ], [ ] ], + [ [ 3, 2 ], [ 1, 0, 0, 0 ], [ ] ] +], +"sus_weights": [ 0.7, 0.48, 0.49 ], +"order_size": [ 4.030612244898, 4.030612244898 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/787e1079/787e1079_code.scd b/resources/string_quartet_3_rise/787e1079/787e1079_code.scd new file mode 100644 index 0000000..e1a9d92 --- /dev/null +++ b/resources/string_quartet_3_rise/787e1079/787e1079_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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"], {(62.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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/787e1079/787e1079_mus_model.json b/resources/string_quartet_3_rise/787e1079/787e1079_mus_model.json new file mode 100644 index 0000000..24314f5 --- /dev/null +++ b/resources/string_quartet_3_rise/787e1079/787e1079_mus_model.json @@ -0,0 +1,66 @@ +{ +"music_data": +[ + [ + [ + [ [ [ -4, 8, -3, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 3 ], [ -3, 8, -1, 0, -3, 2 ] ], 0 ], + [ [ [ -4, 8, -3, 0, -3, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -3, 8, -3, 0, -3, 2 ], [ -3, 8, -1, 0, -3, 2 ] ], 0 ], + [ [ [ -4, 8, -2, 1, -3, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -3, 8, -3, 0, -3, 2 ], [ -3, 8, -1, 0, -3, 2 ] ], 0.25 ], + [ [ [ -4, 8, -2, 1, -3, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -4, 9, -2, 0, -3, 2 ], [ -3, 8, -1, 0, -3, 2 ] ], 0 ], + [ [ [ -4, 8, -2, 1, -3, 2 ], [ -4, 8, -2, 0, -3, 2 ], [ -4, 9, -2, 0, -3, 2 ], [ -2, 7, -2, 0, -3, 2 ] ], 0.5 ] + ], + [ + [ [ [ -4, 8, -2, 1, -3, 2 ], [ -3, 7, -3, 0, -3, 2 ], [ -4, 9, -2, 0, -3, 2 ], [ -2, 7, -2, 0, -3, 2 ] ], 0.125 ], + [ [ [ -4, 8, -2, 1, -3, 2 ], [ -3, 7, -3, 0, -3, 2 ], [ -3, 7, -1, 0, -3, 2 ], [ -2, 7, -2, 0, -3, 2 ] ], 0 ], + [ [ [ -3, 7, -2, 0, -3, 2 ], [ -3, 7, -3, 0, -3, 2 ], [ -3, 7, -1, 0, -3, 2 ], [ -2, 7, -2, 0, -3, 2 ] ], 0.375 ], + [ [ [ -4, 7, -2, 0, -3, 2 ], [ -3, 7, -3, 0, -3, 2 ], [ -3, 7, -1, 0, -3, 2 ], [ -2, 7, -2, 0, -3, 2 ] ], 0.25 ], + [ [ [ -3, 6, -2, 0, -3, 2 ], [ -3, 7, -3, 0, -3, 2 ], [ -3, 7, -1, 0, -3, 2 ], [ -2, 7, -2, 0, -3, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, 0, -3, 2 ], [ -3, 7, -3, 0, -3, 2 ], [ -3, 7, -1, 0, -3, 2 ], [ -2, 7, -2, 0, -3, 2 ] ], 0 ], + [ [ [ -3, 7, -4, 0, -3, 2 ], [ -3, 7, -3, 0, -3, 2 ], [ -3, 7, -1, 0, -3, 2 ], [ -2, 7, -3, 0, -2, 2 ] ], 0 ], + [ [ [ -3, 7, -4, 0, -3, 2 ], [ -3, 7, -3, 0, -3, 2 ], [ -3, 8, -3, 0, -3, 2 ], [ -2, 7, -3, 0, -2, 2 ] ], 0.25 ] + ], + [ + [ [ [ -3, 7, -4, 0, -3, 2 ], [ -3, 7, -3, 0, -3, 2 ], [ -3, 8, -3, 0, -3, 2 ], [ -1, 7, -5, 0, -3, 2 ] ], 0 ], + [ [ [ -3, 7, -4, 0, -3, 2 ], [ -2, 6, -4, 0, -3, 2 ], [ -3, 8, -3, 0, -3, 2 ], [ -1, 7, -5, 0, -3, 2 ] ], 0 ], + [ [ [ -3, 7, -4, 0, -3, 2 ], [ -2, 6, -4, 0, -3, 2 ], [ -2, 7, -4, 0, -3, 2 ], [ -1, 7, -5, 0, -3, 2 ] ], 0.5 ], + [ [ [ -3, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -2, 7, -4, 0, -3, 2 ], [ -1, 7, -5, 0, -3, 2 ] ], 0 ], + [ [ [ -3, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -2, 7, -4, 0, -3, 2 ], [ -2, 8, -4, 0, -3, 2 ] ], 0.5 ] + ] + ] +], +"last_changes": +[ + [ [ -3, 7, -4, 0, -3, 2 ], [ -3, 7, -3, 0, -3, 2 ], [ -3, 8, -3, 0, -3, 2 ], [ -1, 7, -5, 0, -3, 2 ] ], + [ [ -3, 7, -4, 0, -3, 2 ], [ -2, 6, -4, 0, -3, 2 ], [ -3, 8, -3, 0, -3, 2 ], [ -1, 7, -5, 0, -3, 2 ] ], + [ [ -3, 7, -4, 0, -3, 2 ], [ -2, 6, -4, 0, -3, 2 ], [ -2, 7, -4, 0, -3, 2 ], [ -1, 7, -5, 0, -3, 2 ] ], + [ [ -3, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -2, 7, -4, 0, -3, 2 ], [ -1, 7, -5, 0, -3, 2 ] ], + [ [ -3, 7, -4, 0, -3, 2 ], [ -3, 8, -4, 0, -3, 2 ], [ -2, 7, -4, 0, -3, 2 ], [ -2, 8, -4, 0, -3, 2 ] ] +], +"cur_uid": "787e1079", +"ref_uid": "6dcb2cc5", +"order_seed": 705077, +"dur_seed": 169562, +"motifs_seed": 961021, +"entrances_probs_vals": [ 0.82, 0, 0, 0, 3, 0.0098039215686275, 0, 0.045751633986928, 0, 0.084967320261438, 0.84121621621622, 0.1797385620915, 0, 1, 0 ], +"passages_probs_vals": [ 0.82, 0, 0, 0, 3, 0.0098039215686275, 0, 0.045751633986928, 0, 0.084967320261438, 0.84121621621622, 0.1797385620915, 0, 1, 0 ], +"exits_probs_vals": [ 0.82, 0, 0, 0, 3, 0.0098039215686275, 0, 0.045751633986928, 0, 0.084967320261438, 0.84121621621622, 0.1797385620915, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 1 ], [ 3, 2, 0, 2, 3 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 0, 0 ], [ ] ], + [ [ 1 ], [ 0, 3, 2 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 1, 3 ], [ ] ] +], +"sus_weights": [ 0.7, 0.48, 0.49 ], +"order_size": [ 4.030612244898, 4.030612244898 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/78a94ed1/lilypond/part_I.ly b/resources/string_quartet_3_rise/78a94ed1/lilypond/part_I.ly index cf060ff..c30b269 100644 --- a/resources/string_quartet_3_rise/78a94ed1/lilypond/part_I.ly +++ b/resources/string_quartet_3_rise/78a94ed1/lilypond/part_I.ly @@ -1,26 +1,26 @@ { - { c''1^\markup { \pad-markup #0.2 "-15"} } + { d''1^\markup { \pad-markup #0.2 "-15"} } \bar "|" - { f'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { g'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { f'1 ~ } + { g'1 ~ } \bar "|" - { f'2 c''2^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { g'2 d''2^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { c''1 ~ } + { d''1 ~ } \bar "|" - { c''2 ais2^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + { d''2 c'2^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } \bar "|" - { ais2 dis'2^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } + { c'2 f'2^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} ~ } \bar "|" - { dis'1 } + { f'1 } \bar "|" - { ais'1^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} } + { c''1^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} } \bar "|" - { b'2^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} b2^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + { cis''2^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} cis'2^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b2 fis'2^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}} + { cis'2 gis'2^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/78a94ed1/lilypond/part_II.ly b/resources/string_quartet_3_rise/78a94ed1/lilypond/part_II.ly index 9712ce1..d2a3ff5 100644 --- a/resources/string_quartet_3_rise/78a94ed1/lilypond/part_II.ly +++ b/resources/string_quartet_3_rise/78a94ed1/lilypond/part_II.ly @@ -1,26 +1,26 @@ { - { dis'2^\markup { \pad-markup #0.2 "-48"} ais'2^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + { f'2^\markup { \pad-markup #0.2 "-48"} c''2^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } \bar "|" - { ais'2 c''2^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { c''2 d''2^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { c''2 a2^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + { d''2 b2^\markup { \pad-markup #0.2 "-30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } \bar "|" - { a1 } + { b1 } \bar "|" - { c'1^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { d'1^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } \bar "|" - { c'1 } + { d'1 } \bar "|" - { cis'1^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + { dis'1^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } \bar "|" - { cis'1 ~ } + { dis'1 ~ } \bar "|" - { cis'2 dis'2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + { dis'2 f'2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } \bar "|" - { dis'1 ~ } + { f'1 ~ } \bar "|" - { dis'2 ais'2^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} } + { f'2 c''2^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }} } \bar "|" - { b'1^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}} + { cis''1^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/78a94ed1/lilypond/part_III.ly b/resources/string_quartet_3_rise/78a94ed1/lilypond/part_III.ly index 4950731..105fd79 100644 --- a/resources/string_quartet_3_rise/78a94ed1/lilypond/part_III.ly +++ b/resources/string_quartet_3_rise/78a94ed1/lilypond/part_III.ly @@ -1,26 +1,26 @@ { - { b1^\markup { \pad-markup #0.2 "-34"} ~ } + { cis'1^\markup { \pad-markup #0.2 "-34"} ~ } \bar "|" - { b1 } + { cis'1 } \bar "|" - { c'1^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + { d'1^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } \bar "|" - { cis'1^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + { dis'1^\markup { \pad-markup #0.2 "-3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } \bar "|" - { cis'2 gis'2^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + { dis'2 ais'2^\markup { \pad-markup #0.2 "-1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } \bar "|" - { gis'1 ~ } + { ais'1 ~ } \bar "|" - { gis'1 ~ } + { ais'1 ~ } \bar "|" - { gis'1 ~ } + { ais'1 ~ } \bar "|" - { gis'1 ~ } + { ais'1 ~ } \bar "|" - { gis'1 } + { ais'1 } \bar "|" - { a'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { b'1^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { a'1} + { b'1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/78a94ed1/lilypond/part_IV.ly b/resources/string_quartet_3_rise/78a94ed1/lilypond/part_IV.ly index f5a6564..81f9b8d 100644 --- a/resources/string_quartet_3_rise/78a94ed1/lilypond/part_IV.ly +++ b/resources/string_quartet_3_rise/78a94ed1/lilypond/part_IV.ly @@ -1,26 +1,26 @@ { - { f,1^\markup { \pad-markup #0.2 "-17"} ~ } + { g,1^\markup { \pad-markup #0.2 "-17"} ~ } \bar "|" - { f,1 ~ } + { g,1 ~ } \bar "|" - { f,1 ~ } + { g,1 ~ } \bar "|" - { f,1 ~ } + { g,1 ~ } \bar "|" - { f,1 } + { g,1 } \bar "|" - { f,1^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↑" }} ~ } + { g,1^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↑" }} ~ } \bar "|" - { f,1 } + { g,1 } \bar "|" - { c2^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} d2^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } + { d2^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} e2^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } \bar "|" - { d1 ~ } + { e1 ~ } \bar "|" - { d1 ~ } + { e1 ~ } \bar "|" - { d1 ~ } + { e1 ~ } \bar "|" - { d1} + { e1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7c30c182/lilypond/part_I.ly b/resources/string_quartet_3_rise/7c30c182/lilypond/part_I.ly new file mode 100644 index 0000000..08cc7a1 --- /dev/null +++ b/resources/string_quartet_3_rise/7c30c182/lilypond/part_I.ly @@ -0,0 +1,92 @@ +{ + { d'1^\markup { \pad-markup #0.2 "+0"} } + \bar "|" + { fis'1^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { fis'2 g'2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'2 gis'2^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + \bar "|" + { gis'1 } + \bar "|" + { ais'1^\markup { \pad-markup #0.2 "-40"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "+25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} } + \bar "|" + { c''1^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + \bar "|" + { c''1 } + \bar "|" + { cis''1^\markup { \pad-markup #0.2 "+44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} } + \bar "|" + { gis'1^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { gis'1 } + \bar "|" + { a'1^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + \bar "|" + { a'1 ~ } + \bar "|" + { a'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 } + \bar "|" + { gis1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + \bar "|" + { gis1 } + \bar "|" + { a1^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }} ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 } + \bar "|" + { ais1^\markup { \pad-markup #0.2 "+38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} } + \bar "|" + { c'1^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { c'2 cis'2^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }} ~ } + \bar "|" + { cis'2 fis'2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'2 g'2^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } + \bar "|" + { g'1 ~ } + \bar "|" + { g'2 a'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + \bar "|" + { a'2 dis'2^\markup { \pad-markup #0.2 "+5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↓" }} ~ } + \bar "|" + { dis'2 e'2^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2 fis'2^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'2 fis'2^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ } + \bar "|" + { fis'2 gis'2^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↑" }} ~ } + \bar "|" + { gis'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7c30c182/lilypond/part_II.ly b/resources/string_quartet_3_rise/7c30c182/lilypond/part_II.ly new file mode 100644 index 0000000..09cc31d --- /dev/null +++ b/resources/string_quartet_3_rise/7c30c182/lilypond/part_II.ly @@ -0,0 +1,92 @@ +{ + { d'2^\markup { \pad-markup #0.2 "+0"} a'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + \bar "|" + { a'2 ais'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 ~ } + \bar "|" + { ais'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "+11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }} ~ } + \bar "|" + { b'2 cis''2^\markup { \pad-markup #0.2 "-24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { cis''1 } + \bar "|" + { d''1^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + \bar "|" + { d''2 e'2^\markup { \pad-markup #0.2 "-4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2 fis'2^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { fis'1 ~ } + \bar "|" + { fis'2 cis''2^\markup { \pad-markup #0.2 "+44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + \bar "|" + { cis''2 cis''2^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + \bar "|" + { cis''2 b'2^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'2 c''2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }} ~ } + \bar "|" + { c''2 cis''2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''2 d'2^\markup { \pad-markup #0.2 "+39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } + \bar "|" + { d'2 e'2^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2 f'2^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 } + \bar "|" + { g'2^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }} gis'2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { gis'1 } + \bar "|" + { a'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} b'2^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { b'2 cis''2^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 } + \bar "|" + { d''2^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }} b'2^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }} ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1 ~ } + \bar "|" + { b'1} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7c30c182/lilypond/part_III.ly b/resources/string_quartet_3_rise/7c30c182/lilypond/part_III.ly new file mode 100644 index 0000000..46a0deb --- /dev/null +++ b/resources/string_quartet_3_rise/7c30c182/lilypond/part_III.ly @@ -0,0 +1,92 @@ +{ + { d'1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { d'1 } + \bar "|" + { d''1^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { d''2 dis'2^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { dis'1 ~ } + \bar "|" + { dis'2 f'2^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'2 fis'2^\markup { \pad-markup #0.2 "-26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + \bar "|" + { fis'2 c''2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }} ~ } + \bar "|" + { c''1 ~ } + \bar "|" + { c''1 } + \bar "|" + { cis''1^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { cis''2 c'2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} ~ } + \bar "|" + { c'1 } + \bar "|" + { cis'1^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ } + \bar "|" + { cis'1 } + \bar "|" + { d'1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} } + \bar "|" + { e'2^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} f'2^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { f'1 ~ } + \bar "|" + { f'1 } + \bar "|" + { g'1^\markup { \pad-markup #0.2 "-17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} ~ } + \bar "|" + { g'1 } + \bar "|" + { gis'1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { gis'2 a'2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + \bar "|" + { a'1 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } + \bar "|" + { c''1^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} } + \bar "|" + { cis''2^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} d''2^\markup { \pad-markup #0.2 "-42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + \bar "|" + { d''2 c''2^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + \bar "|" + { c''1 } + \bar "|" + { cis''1^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 ~ } + \bar "|" + { cis''1 } + \bar "|" + { d''1^\markup { \pad-markup #0.2 "-24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} ~ } + \bar "|" + { d''1 ~ } + \bar "|" + { d''1 ~ } + \bar "|" + { d''1 ~ } + \bar "|" + { d''1 } + \bar "|" + { e1^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } + \bar "|" + { fis1^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7c30c182/lilypond/part_IV.ly b/resources/string_quartet_3_rise/7c30c182/lilypond/part_IV.ly new file mode 100644 index 0000000..7dfa030 --- /dev/null +++ b/resources/string_quartet_3_rise/7c30c182/lilypond/part_IV.ly @@ -0,0 +1,92 @@ +{ + { d1^\markup { \pad-markup #0.2 "+0"} ~ } + \bar "|" + { d1 ~ } + \bar "|" + { d1 } + \bar "|" + { dis1^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} } + \bar "|" + { f1^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } + \bar "|" + { f1 ~ } + \bar "|" + { f1 } + \bar "|" + { fis1^\markup { \pad-markup #0.2 "+27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↑" }} ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis1 ~ } + \bar "|" + { fis2 gis2^\markup { \pad-markup #0.2 "-8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + \bar "|" + { gis1 ~ } + \bar "|" + { gis1 ~ } + \bar "|" + { gis1 ~ } + \bar "|" + { gis1 ~ } + \bar "|" + { gis1 ~ } + \bar "|" + { gis2 a2^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 } + \bar "|" + { ais1^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + \bar "|" + { ais2 e,2^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↑" }} ~ } + \bar "|" + { e,2 fis,2^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + \bar "|" + { fis,2 g,2^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }} ~ } + \bar "|" + { g,1 } + \bar "|" + { a,2^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} b,2^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }} ~ } + \bar "|" + { b,1 ~ } + \bar "|" + { b,1 ~ } + \bar "|" + { b,1 ~ } + \bar "|" + { b,1 ~ } + \bar "|" + { b,1 ~ } + \bar "|" + { b,1 } + \bar "|" + { gis1^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }} ~ } + \bar "|" + { gis1 } + \bar "|" + { a1^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ } + \bar "|" + { a1 } + \bar "|" + { b1^\markup { \pad-markup #0.2 "-31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + \bar "|" + { b1^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} ~ } + \bar "|" + { b1 ~ } + \bar "|" + { b1 } + \bar "|" + { cis'1^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + \bar "|" + { d'2^\markup { \pad-markup #0.2 "-24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} dis'2^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } + \bar "|" + { dis'1 } + \bar "|" + { e'1^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + \bar "|" + { e'1 ~ } + \bar "|" + { e'2 fis'2^\markup { \pad-markup #0.2 "-6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7ede7adb/lilypond/part_I.ly b/resources/string_quartet_3_rise/7ede7adb/lilypond/part_I.ly index 41fe1e5..02e083d 100644 --- a/resources/string_quartet_3_rise/7ede7adb/lilypond/part_I.ly +++ b/resources/string_quartet_3_rise/7ede7adb/lilypond/part_I.ly @@ -1,18 +1,18 @@ { - { g'1^\markup { \pad-markup #0.2 "-21"} ~ } + { a'1^\markup { \pad-markup #0.2 "-21"} ~ } \bar "|" - { g'2 b'2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + { a'2 cis''2^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } \bar "|" - { g1^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} } + { a1^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} } \bar "|" - { d'1^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } + { e'1^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ } \bar "|" - { d'2 e'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} } + { e'2 fis'2^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} } \bar "|" - { fis'2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} a'2^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } + { gis'2^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} b'2^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} ~ } \bar "|" - { a'2 c''2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } + { b'2 d''2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} ~ } \bar "|" - { c''1} + { d''1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7ede7adb/lilypond/part_II.ly b/resources/string_quartet_3_rise/7ede7adb/lilypond/part_II.ly index ce1994b..d4f569b 100644 --- a/resources/string_quartet_3_rise/7ede7adb/lilypond/part_II.ly +++ b/resources/string_quartet_3_rise/7ede7adb/lilypond/part_II.ly @@ -1,18 +1,18 @@ { - { b1^\markup { \pad-markup #0.2 "-34"} ~ } + { cis'1^\markup { \pad-markup #0.2 "-34"} ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b1 ~ } + { cis'1 ~ } \bar "|" - { b1 } + { cis'1 } \bar "|" - { fis'1^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} } + { gis'1^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} } \bar "|" - { gis'1^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}} + { ais'1^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7ede7adb/lilypond/part_III.ly b/resources/string_quartet_3_rise/7ede7adb/lilypond/part_III.ly index e5a072c..f190197 100644 --- a/resources/string_quartet_3_rise/7ede7adb/lilypond/part_III.ly +++ b/resources/string_quartet_3_rise/7ede7adb/lilypond/part_III.ly @@ -1,18 +1,18 @@ { - { fis2^\markup { \pad-markup #0.2 "-33"} c'2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } + { gis2^\markup { \pad-markup #0.2 "-33"} d'2^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } \bar "|" - { c'1 ~ } + { d'1 ~ } \bar "|" - { c'1 ~ } + { d'1 ~ } \bar "|" - { c'2 g'2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + { d'2 a'2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } \bar "|" - { g'1 ~ } + { a'1 ~ } \bar "|" - { g'1 ~ } + { a'1 ~ } \bar "|" - { g'1 ~ } + { a'1 ~ } \bar "|" - { g'2 a'2^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}} + { a'2 b'2^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7ede7adb/lilypond/part_IV.ly b/resources/string_quartet_3_rise/7ede7adb/lilypond/part_IV.ly index bf1c7e0..138d391 100644 --- a/resources/string_quartet_3_rise/7ede7adb/lilypond/part_IV.ly +++ b/resources/string_quartet_3_rise/7ede7adb/lilypond/part_IV.ly @@ -1,18 +1,18 @@ { - { gis'1^\markup { \pad-markup #0.2 "+34"} } + { ais'1^\markup { \pad-markup #0.2 "+34"} } \bar "|" - { c''1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } + { d''1^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ } \bar "|" - { c''2 g,2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { d''2 a,2^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } \bar "|" - { g,1 } + { a,1 } \bar "|" - { d1^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + { e1^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } \bar "|" - { d1 ~ } + { e1 ~ } \bar "|" - { d1 ~ } + { e1 ~ } \bar "|" - { d1} + { e1} \bar "||" } \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7f6eb065/7f6eb065_code.scd b/resources/string_quartet_3_rise/7f6eb065/7f6eb065_code.scd new file mode 100644 index 0000000..e1a9d92 --- /dev/null +++ b/resources/string_quartet_3_rise/7f6eb065/7f6eb065_code.scd @@ -0,0 +1,992 @@ +( +// helper funcs +var hsArrayToCents, pDist, hdSum, hsChordalDistance, hsArrayToFreq; + +// score funcs +var isInRange, spacingScore, rangeScore, intervalScore, inclusionScore; + +// subroutines +var genTuples, initVoices, genOrders, genSubMotif, updateVoices, genDurFunc, genStepFunc; + +// 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, stepProbsVals, passagesWeights, hdExp, hdInvert, +orders, susWeights, orderSize, passagesSize, +motifEdited, orderEdited; + +// model aux vars +var entrancesDurFunc, passagesDurFunc, exitsDurFunc, stepFunc; + +// other global vars +var popSize, exPath, dir, primes, dims, tuples, +group, player, resourceDir, ledgerPath, ledger, currentlyPlayingUID, +nameSpaces; + +// install JSON quark (not used) +/* +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(array2) - hsArrayToCents.value(array1); + 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) + stepFunc.value(pDistance) +}; +*/ + +intervalScore = { + arg hsArray1, hsArray2, mean, sd, signed = true; + var pDistance; + pDistance = pDist.value(hsArray1, hsArray2, signed); + //pDistance.gaussCurve(1, mean, sd) + //if(pDistance >= 0, {stepFunc.value(abs(pDistance))}, {0.01}); + stepFunc.value(pDistance) +}; + +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 = dims.collect({[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); +}; + +genStepFunc = {arg minStep, maxStep, envData, seed; + var envDataNorm, env, pTable, stepFunc; + //[minStep, maxStep, envData].postln; + envDataNorm = ([[0, 0]] ++ envData.clump(2) ++ [[1, 0]]).flop; + envDataNorm = [envDataNorm[0].normalize(minStep, maxStep), envDataNorm[1]].flop; + env = Env.pairs(envDataNorm); + stepFunc = {arg pDist; + env.at(pDist).clip(0.001, 1); + }; + seedFunc.value(stepFunc, seed); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength.asInteger - minMotifLength.asInteger).rand + minMotifLength.asInteger).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent, order; + noSusIns = [1, 2, 3].wchoose(susWeights.normalizeSum); + + //noProgIns = (popSize - noSusIns).rand + 1; + noProgIns = (popSize - noSusIns); + noSilentIns = popSize - noSusIns - noProgIns; + + /* + noSilentIns = (popSize - noSusIns).rand.clip(0, 1); + noProgIns = popSize - noSusIns - noSilentIns; + */ + + # prog, sus, silent = (0..(popSize-1)).scramble.clumps([noProgIns, noSusIns, noSilentIns]); + + prog = (prog.scramble ++ ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}).scramble); + //prog = ((maxProgLength.asInteger - minProgLength.asInteger).rand + minProgLength.asInteger).collect({prog.choose}); + + 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; + //candidates.select({arg item; (item ++ voices).asSet.size >= 4}); + 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.01); + //recentlySoundedScore = inclusionScore.value(lastXChanges.flatten.collect({arg item; item.drop(1)}), candidate.drop(1), 0.01); + + /* + if(rangeScore.value(candidate.collect({0}), voices[ins], ranges[ins][1] - 500, ranges[ins][1], 0, true) == 1, { + isInRangeScore = 1 - rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0] + 500, ranges[ins][1] - 500, 0, true); + isInRangeScore = isInRangeScore * rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true) + }, { + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + }); + */ + + + isInRangeScore = rangeScore.value(candidate.collect({0}), candidate, ranges[ins][0], ranges[ins][1], 0, true); + //old way - worked but actually by accident (I think) + //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 = pow(hdSum.value(voices.deepCopy.put(ins, candidate)), hdExp); + if(hdInvert == 0, {hdScore = 1/hdScore}); + //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]}).postln; + }); + nProbs = nProbs.flop.collect({arg scores, s; scores.product}).normalizeSum; + + nProbs.round(0.001).postln; + [candidates, nProbs.round(0.001)].flop.postln; + + 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, fDur, durAdd; + + 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}); + lastState = if(o == 0, {lastXChanges.last.deepCopy}, {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); + }); + + //round last duration to measure + /* + fDur = fSeq.flatten.flatten.slice(nil, 1).sum; + durAdd = fDur.round(4) - fDur; + if(durAdd < 0, {durAdd = 4 - durAdd}); + fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] = fSeq[0][orders.size - 1][fSeq[0][orders.size - 1].size - 1][1] + durAdd; + */ + + 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.notNil) { + ~msg; + ~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; + # voices, durs = seq.flatten2(if(oneShot, {2}, {3})).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"], {(62.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.0, 3.0)}, {rrand(0.3, 0.5)}); + }); + rels = rels.add(rrand(1.0, 3.0)); + 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(2).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; + }, { + var tmpRes; + if(res.every({arg char; char.isDecDigit}), {tmpRes = res.asInteger}); + if(res.contains("."), {tmpRes = res.asFloat}); + if(tmpRes != nil, {res = tmpRes}); + }); + }); + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + 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, stepProbsVals, passagesWeights, hdExp, hdInvert, + orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + dict = Dictionary.with(*nameSpaces.collect({arg nS, n; nS->modelItems[n]})); +}; + +loadLedgerFile = {arg path; + ledgerPath = path; + resourceDir = path.splitext(".").drop(-1).join; + loadLedgerJSON.value(File(ledgerPath, "r").readAllString.parseJSON) +}; + +loadLedgerJSON = {arg jsonObject; ledger = jsonObject["ledger"]}; + +saveLedger = {arg ledger, path; + var file, curResourceDir; + file = File(path, "w"); + curResourceDir = resourceDir; + resourceDir = path.splitext(".").drop(-1).join; + if(curResourceDir != resourceDir, { + File.mkdir(resourceDir); + ledger.do({arg id; + File.copy(curResourceDir +/+ id, resourceDir +/+ id); + }); + }); + 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"); +resourceDir = (dir +/+ ".." +/+ "resources" +/+ "piece_ledger"); +//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", "step_probs_vals", "passages_weights", "hd_exp", "hd_invert", + "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((resourceDir +/+ 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)); + }); + + stepFunc = genStepFunc.valueArray(stepProbsVals[..1] ++ [stepProbsVals[2..]] ++ [motifSeed]); + 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)); + //~seq = seq; + + addr.sendMsg("/generated", path, modelString, ledgerPath); +}, \generate); + + +OSCdef(\commit, {arg msg, time, addr, port; + var musicData, musicChanged, dict, newLedger, modelPath, musString, musFile, test1, test2, lastCurUID, commitType, commitPos, equalityLedger; + //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; + commitType = msg[2].asString; + commitPos = msg[3].postln.asInteger; + + lastCurUID = curUID.deepCopy; + curUID = genUID.value; + + File.mkdir((resourceDir +/+ curUID).standardizePath); + File.copy(exPath, (resourceDir +/+ curUID +/+ curUID ++ "_code" ++ ".scd").standardizePath); + + modelPath = (resourceDir +/+ 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); + + /* + if(commitType == "add", { + if(lastCurUID == "tmp", { + ledger = ledger.drop(-1).add(curUID); + }, { + ledger = ledger.add(curUID); + }) + }); + */ + + ledger.postln; + + if(commitType == "add", {ledger = ledger.add(curUID)}); + + if(commitType == "insert", {ledger = ledger.insert(commitPos + 1, curUID)}); + + if(commitType == "replace", {ledger = ledger.put(commitPos, curUID)}); + + equalityLedger = ledger.collect({arg item; item.asSymbol}); + if(equalityLedger.includes(\tmp).postln, {ledger.removeAt(equalityLedger.indexOf(\tmp).postln)}); + + ledger.postln; + + 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 = (resourceDir +/+ 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 = (resourceDir +/+ "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); + + +OSCdef(\transcribe_motif, {arg msg, time, addr, port; + var tSeq, refChord, refUID; + + msg.postln; + + tSeq = [loadModelJSON.value(msg[1].asString.parseJSON)["music_data"]]; + refUID = msg[2].asString.postln; + + if((refUID != "nil") && (refUID != "tmp"), { + var file; + file = File((resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }, { + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + }); + + ~transcribe.value(tSeq, refChord, (dir +/+ ".." +/+ "lilypond" +/+ "includes").standardizePath, addr, "/transcribe_motif"); +}, \transcribe_motif); + + +OSCdef(\transcribe_all, {arg msg, time, addr, port; + var cSize, patterns, cuedSeek, indexStart, indexEnd, tmpLedger; + if(true, { + cuedSeek = (seq != nil); + indexStart = msg[1].asInteger; + indexEnd = ledger.size - if(cuedSeek, {2}, {1}); + + //tmp for testing transcription + //indexEnd = (indexStart+5); + + //ledger.postln; + if(((indexStart == (ledger.size - 1)) && cuedSeek).not, { + var lilyPartLedgerFiles; + + lilyPartLedgerFiles = 4.collect({arg p; + File((dir +/+ ".." +/+ "lilypond" +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath, "w"); + }); + + ledger[indexStart..indexEnd].do({arg uid, index; + var path, file, fileString, tSeq, refUID, refChord; + path = (resourceDir +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + fileString = file.readAllString; + tSeq = msgInterpret.value(fileString.parseJSON["music_data"]); + refUID = msgInterpret.value(fileString.parseJSON["ref_uid"]); + file.close; + + //uid.postln; + //(refUID == "nil").postln; + + refChord = [[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]; + + if(refUID != "nil", { + path = (resourceDir +/+ refUID +/+ refUID ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + refChord = msgInterpret.value(file.readAllString.parseJSON["last_changes"]).last; + file.close; + }); + + if(index != indexEnd, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath); + }, { + ~transcribe.value(tSeq, refChord, (resourceDir +/+ uid +/+ "lilypond").standardizePath, addr, "/transcribe_all"); + }); + + lilyPartLedgerFiles.do({arg f, p; + f.write("\\include \"" ++ resourceDir +/+ uid +/+ "lilypond" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly\"\n"); + }); + + }); + + lilyPartLedgerFiles.do({arg f; + f.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; + }); + */ + }, { + + }); + +}, \transcribe_all); + +) + + diff --git a/resources/string_quartet_3_rise/7f6eb065/7f6eb065_mus_model.json b/resources/string_quartet_3_rise/7f6eb065/7f6eb065_mus_model.json new file mode 100644 index 0000000..d058ff0 --- /dev/null +++ b/resources/string_quartet_3_rise/7f6eb065/7f6eb065_mus_model.json @@ -0,0 +1,451 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 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, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, 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, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 1, 1, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 1, 1, 0, -1, 0, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 1, 1, 0, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ 1, 1, 0, -1, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 1, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 1, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 1, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 0, 1, 2, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 1, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 0, 1, 2, 0, 0, 0 ], [ -1, 1, 2, 0, 0, 0 ] ], 0 ], + [ [ [ -2, 1, 2, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 0, 1, 2, 0, 0, 0 ], [ -1, 1, 2, 0, 0, 0 ] ], 0.25 ], + [ [ [ -2, 1, 2, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ -1, 1, 2, 0, 0, 0 ] ], 0.25 ], + [ [ [ -2, 1, 2, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 1, 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 0, 1, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 1, 1, 0, -1, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 1, 1, 0, -1, 0 ], [ -1, 0, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 1, 1, 0, -1, 0 ], [ -1, 0, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 0, 1, 1, 0, -1, 0 ] ], 0.25 ], + [ [ [ -1, 1, 1, 0, -1, 0 ], [ -2, 2, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 0, 1, 1, 0, -1, 0 ] ], 0.25 ], + [ [ [ -1, 1, 1, 0, -1, 0 ], [ -2, 2, 1, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 1, 1, 0, -1, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ -2, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ -2, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ -2, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ -2, 2, 0, 0, 0, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.25 ], + [ [ [ -2, 2, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ], [ 0, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ -2, 2, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -2, 2, 0, 0, 0, 0 ], [ -1, 2, -1, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ -2, 2, 0, 0, 0, 0 ], [ -1, 2, -1, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 0, 1, -1, 0, 1, 0 ] ], 0 ], + [ [ [ -1, 1, -1, 0, 0, 0 ], [ -1, 2, -1, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 0, 1, -1, 0, 1, 0 ] ], 0.25 ], + [ [ [ -1, 1, -1, 0, 0, 0 ], [ 0, 1, -2, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 0, 1, -1, 0, 1, 0 ] ], 0 ], + [ [ [ -2, 2, -1, 0, 0, 0 ], [ 0, 1, -2, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 0, 1, -1, 0, 1, 0 ] ], 0 ], + [ [ [ -2, 2, -1, 0, 0, 0 ], [ 0, 1, -2, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -2, 2, -1, 0, 0, 0 ], [ 0, 1, -2, 0, 0, 0 ], [ 0, 2, 0, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ 0, 1, -2, 0, 0, 0 ], [ 0, 2, 0, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ 0, 2, -1, -1, 0, 0 ], [ 0, 2, 0, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 1, -1, 0, 0, 0 ], [ 0, 2, -1, -1, 0, 0 ], [ 0, 2, 0, 0, 0, 0 ], [ 1, 1, -1, 0, -1, 0 ] ], 0 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ 0, 2, -1, -1, 0, 0 ], [ 0, 1, -1, 1, 0, 0 ], [ 1, 1, -1, 0, -1, 0 ] ], 0 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ -1, 1, -1, 1, 0, 0 ], [ 0, 1, -1, 1, 0, 0 ], [ 1, 1, -1, 0, -1, 0 ] ], 0.25 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ 0, 1, -1, 0, -1, 0 ], [ 0, 1, -1, 1, 0, 0 ], [ 1, 1, -1, 0, -1, 0 ] ], 0 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ 0, 1, -1, 0, -1, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 1, 1, -1, 0, -1, 0 ] ], 0.25 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ 0, 1, -2, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 1, 1, -1, 0, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 1, -1, 0, 0, 0 ], [ -1, 2, -1, 0, 0, 0 ], [ 1, 1, -1, 0, 0, 0 ], [ 1, 1, -1, 0, -1, 0 ] ], 0 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ -1, 2, -1, 0, 0, 0 ], [ 1, 1, -2, 0, 0, 0 ], [ 1, 1, -1, 0, -1, 0 ] ], 0 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ -1, 2, -1, 0, 0, 0 ], [ 1, 1, -2, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ -1, 2, -1, 0, 0, 0 ], [ 1, 1, -2, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ -1, 2, -1, 0, 0, 0 ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 1, -1, 0, 0, 0 ], [ -2, 3, -1, 0, 0, 0 ], [ 0, 1, -1, 1, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -1, 0, 0, 0 ], [ -2, 3, -1, 0, 0, 0 ], [ 0, 2, 0, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 3, -1, 0, 0, 0 ], [ -2, 3, -1, 0, 0, 0 ], [ 0, 2, 0, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 3, -1, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ], [ 0, 2, 0, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 2, -2, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ], [ 0, 2, 0, 0, 0, 0 ], [ 0, 2, -1, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 2, -2, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ], [ 0, 2, 0, 0, 0, 0 ], [ 1, 1, -2, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 2, -2, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ], [ 0, 3, -2, 0, 0, 0 ], [ 1, 1, -2, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 1, -2, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ], [ 0, 3, -2, 0, 0, 0 ], [ 1, 1, -2, 0, 0, 0 ] ], 0.25 ], + [ [ [ -2, 3, -2, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ], [ 0, 3, -2, 0, 0, 0 ], [ 1, 1, -2, 0, 0, 0 ] ], 0 ], + [ [ [ -2, 3, -2, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ], [ 0, 2, -2, 0, 0, 0 ], [ 1, 1, -2, 0, 0, 0 ] ], 0.25 ], + [ [ [ -2, 3, -2, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ], [ 0, 2, -2, 0, 0, 0 ], [ 0, 3, -2, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -2, 3, -2, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ], [ 0, 2, -2, 0, 0, 0 ], [ 1, 2, -2, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -3, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ], [ 0, 2, -2, 0, 0, 0 ], [ 1, 2, -2, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -3, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 1, 2, -2, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 2, -3, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ], [ 1, 2, -2, -1, 0, 0 ], [ 0, 2, -2, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 2, -3, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ], [ 0, 2, -2, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -3, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -3, 0, 0, 0 ], [ 0, 1, -3, 0, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 2, -3, 0, 0, 0 ], [ -1, 3, -3, 0, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 2, -3, 0, 0, 0 ], [ 0, 2, -4, 0, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 2, -3, -1, 0, 0 ], [ 0, 2, -4, 0, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 2, -3, -1, 0, 0 ], [ 0, 2, -4, 0, 0, 0 ], [ 1, 2, -4, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 2, -3, -1, 0, 0 ], [ -1, 2, -3, 0, 0, 1 ], [ 1, 2, -4, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 2, -3, -1, 0, 0 ], [ -1, 2, -3, 1, 0, 0 ], [ 1, 2, -4, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 2, -3, -1, 0, 0 ], [ -1, 2, -3, 1, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 2, -3, -1, 0, 0 ], [ -1, 3, -3, 0, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 2, -3, -1, 0, 0 ], [ -1, 3, -3, 0, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ], 0 ], + [ [ [ -2, 2, -2, 1, 0, 0 ], [ -1, 3, -3, 0, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ], 0 ], + [ [ [ -2, 2, -2, 1, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ], 0.25 ], + [ [ [ -1, 1, -3, 1, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ -1, 2, -2, 1, 0, 0 ] ], 0 ], + [ [ [ -1, 1, -3, 1, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ 0, 1, -3, 1, 0, 0 ] ], 0.25 ], + [ [ [ -1, 1, -3, 1, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0 ], + [ [ [ -1, 1, -3, 1, 0, 0 ], [ -1, 2, -3, 1, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 1, -3, 1, 0, 0 ], [ -1, 2, -3, 1, 0, 0 ], [ -1, 4, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0 ], + [ [ [ -2, 3, -3, 1, 0, 0 ], [ -1, 2, -3, 1, 0, 0 ], [ -1, 4, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0 ], + [ [ [ -2, 3, -3, 1, 0, 0 ], [ -2, 4, -3, 1, 0, 0 ], [ -1, 4, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0.25 ], + [ [ [ -3, 4, -3, 1, 0, 0 ], [ -2, 4, -3, 1, 0, 0 ], [ -1, 4, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -3, 4, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 4, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0 ], + [ [ [ -3, 4, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 1 ], [ -1, 3, -3, 1, 0, 0 ] ], 0.25 ], + [ [ [ -3, 3, -3, 1, 0, 1 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 1 ], [ -1, 3, -3, 1, 0, 0 ] ], 0.25 ], + [ [ [ -2, 3, -4, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 1 ], [ -1, 3, -3, 1, 0, 0 ] ], 0 ], + [ [ [ -2, 3, -4, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 3, -4, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -2, 3, -2, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 3, -4, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0 ], + [ [ [ -2, 3, -2, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 3, -4, 1, 0, 0 ], [ -1, 3, -3, 1, -1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 3, -3, 1, -1, 0 ], [ -1, 3, -3, 1, -1, 0 ] ], 0.25 ], + [ [ [ -2, 3, -2, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 1, 0 ], [ -1, 3, -3, 1, -1, 0 ] ], 0.25 ] + ], + [ + [ [ [ -2, 3, -2, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ -1, 3, -3, 1, -1, 0 ] ], 0 ], + [ [ [ -1, 2, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ -1, 3, -3, 1, -1, 0 ] ], 0 ], + [ [ [ -1, 2, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0.25 ], + [ [ [ -2, 4, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 2, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 4, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 4, -3, 1, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 2, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 3, -4, 1, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 3, -4, 1, 0, 0 ], [ -1, 3, -2, 1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 2, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 3, -4, 1, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ] ], 0 ], + [ [ [ -2, 4, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 3, -4, 1, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ] ], 0 ], + [ [ [ -2, 4, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 4, -3, 1, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ] ], 0.25 ], + [ [ [ -2, 4, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 4, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0.25 ], + [ [ [ -2, 4, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 4, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 1 ] ], 0.25 ], + [ [ [ -2, 4, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 4, -3, 1, 0, 0 ], [ -2, 3, -3, 2, 0, 0 ] ], 0.25 ], + [ [ [ -2, 4, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 4, -3, 1, 0, 0 ], [ -1, 3, -4, 1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -2, 4, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 3, -4, 1, 0, 0 ], [ -1, 3, -4, 1, 0, 0 ] ], 0 ], + [ [ [ -2, 4, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 3, -4, 1, 0, 0 ], [ 0, 3, -3, 1, 0, 0 ] ], 0.25 ], + [ [ [ -1, 3, -4, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 3, -4, 1, 0, 0 ], [ 0, 3, -3, 1, 0, 0 ] ], 0 ], + [ [ [ -1, 3, -4, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 3, -4, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0 ], + [ [ [ -1, 3, -4, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 3, -3, 2, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0.25 ], + [ [ [ -2, 3, -3, 2, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 3, -3, 2, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -2, 2, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 3, -3, 2, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0.25 ], + [ [ [ -2, 2, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ] ], 0 ], + [ [ [ -2, 2, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ 0, 2, -3, 1, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -2, 2, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0.25 ], + [ [ [ -2, 2, -3, 1, 0, 0 ], [ -1, 3, -3, 0, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -3, 0, 0, 0 ], [ -1, 3, -3, 0, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 2, -3, 0, 0, 0 ], [ -1, 3, -3, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 2, -3, 0, 0, 0 ], [ -1, 3, -3, 0, 0, 0 ], [ -1, 4, -3, 0, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0 ], + [ [ [ -2, 4, -3, 0, 0, 0 ], [ -1, 3, -3, 0, 0, 0 ], [ -1, 4, -3, 0, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0.25 ], + [ [ [ -2, 4, -3, 0, 0, 0 ], [ -1, 3, -3, 0, 0, 0 ], [ 0, 3, -4, 0, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 3, -4, 0, 0, 0 ], [ -1, 3, -3, 0, 0, 0 ], [ 0, 3, -4, 0, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 3, -4, 0, 0, 0 ], [ -1, 3, -3, 0, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 3, -4, 0, 0, 0 ], [ 0, 3, -3, -1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0.25 ], + [ [ [ -2, 3, -3, 1, 0, 0 ], [ 0, 3, -3, -1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 3, -3, 0, 0, 0 ], [ 0, 3, -3, -1, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 3, -3, 0, 0, 0 ], [ -1, 3, -2, 0, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 3, -3, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 3, -3, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ], [ -1, 3, -3, 1, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ] ], 0 ], + [ [ [ -1, 3, -3, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ], [ 0, 3, -3, 0, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ] ], 0.25 ], + [ [ [ -1, 3, -3, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ], [ 1, 2, -3, 0, 0, 0 ], [ -2, 3, -3, 1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 3, -3, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ], [ 1, 2, -3, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 2, -4, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ], [ 1, 2, -3, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 2, -4, 0, 0, 0 ], [ 0, 1, -3, 0, 0, 0 ], [ 1, 2, -3, 0, 0, 0 ], [ -1, 2, -2, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 2, -4, 0, 0, 0 ], [ 0, 1, -3, 0, 0, 0 ], [ 1, 2, -3, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ] ], 0.25 ], + [ [ [ 1, 1, -3, 0, 0, 0 ], [ 0, 1, -3, 0, 0, 0 ], [ 1, 2, -3, 0, 0, 0 ], [ 0, 2, -3, 0, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -3, 0, 0, 0 ], [ 0, 1, -3, 0, 0, 0 ], [ 1, 2, -3, 0, 0, 0 ], [ 2, 1, -3, 0, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -3, 0, 0, 0 ], [ -1, 2, -3, 0, 0, 0 ], [ 1, 2, -3, 0, 0, 0 ], [ 2, 1, -3, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 1, -3, 0, 0, 0 ], [ -1, 2, -3, 0, 0, 0 ], [ 1, 2, -3, 0, 0, 0 ], [ 2, 1, -3, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 1, -3, 0, 0, 0 ], [ -1, 2, -3, 0, 0, 0 ], [ 2, 1, -4, 0, 0, 0 ], [ 2, 1, -3, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 1, -3, 0, 0, 0 ], [ -1, 1, -3, 0, 0, 1 ], [ 2, 1, -4, 0, 0, 0 ], [ 2, 1, -3, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -3, -1, 0, 0 ], [ -1, 1, -3, 0, 0, 1 ], [ 2, 1, -4, 0, 0, 0 ], [ 2, 1, -3, 0, 0, 0 ] ], 0.25 ], + [ [ [ 0, 1, -3, 0, 0, -1 ], [ -1, 1, -3, 0, 0, 1 ], [ 2, 1, -4, 0, 0, 0 ], [ 2, 1, -3, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 1, -3, 0, 0, -1 ], [ 0, 1, -4, 0, 0, 0 ], [ 2, 1, -4, 0, 0, 0 ], [ 2, 1, -3, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ 0, 1, -3, 0, 0, -1 ], [ 0, 1, -4, 0, 0, 0 ], [ 2, 1, -4, 0, 0, 0 ], [ 2, 2, -3, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 1, -3, 0, 0, -1 ], [ 0, 1, -2, 0, 0, -1 ], [ 2, 1, -4, 0, 0, 0 ], [ 2, 2, -3, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 1, -3, 0, 0, -1 ], [ 0, 1, -2, 0, 0, -1 ], [ 2, 1, -2, 0, 0, -1 ], [ 2, 2, -3, 0, 0, -1 ] ], 0.25 ], + [ [ [ 0, 1, -3, 0, 0, -1 ], [ 0, 1, -2, 0, 0, -1 ], [ 3, 0, -3, 0, 0, -1 ], [ 2, 2, -3, 0, 0, -1 ] ], 0.25 ], + [ [ [ 0, 1, -3, 0, 0, -1 ], [ 0, 1, -2, 0, 0, -1 ], [ 3, 0, -3, 0, 0, -1 ], [ 3, 1, -4, 0, 0, -1 ] ], 0.25 ], + [ [ [ 0, 1, -3, 0, 0, -1 ], [ 1, 0, -3, 0, 0, -1 ], [ 3, 0, -3, 0, 0, -1 ], [ 3, 1, -4, 0, 0, -1 ] ], 0.25 ] + ], + [ + [ [ [ 0, 1, -3, 0, 0, -1 ], [ 1, 0, -3, 0, 0, -1 ], [ 3, 1, -5, 0, 0, -1 ], [ 3, 1, -4, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 1, -3, 0, 0, -1 ], [ 1, 1, -5, 0, 0, -1 ], [ 3, 1, -5, 0, 0, -1 ], [ 3, 1, -4, 0, 0, -1 ] ], 0 ], + [ [ [ 1, 0, -4, 0, 0, -1 ], [ 1, 1, -5, 0, 0, -1 ], [ 3, 1, -5, 0, 0, -1 ], [ 3, 1, -4, 0, 0, -1 ] ], 0.25 ], + [ [ [ 1, 0, -4, 0, 0, -1 ], [ 1, 1, -5, 0, 0, -1 ], [ 2, 2, -4, 0, 0, -1 ], [ 3, 1, -4, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 2, -4, 0, 0, -1 ], [ 1, 1, -5, 0, 0, -1 ], [ 2, 2, -4, 0, 0, -1 ], [ 3, 1, -4, 0, 0, -1 ] ], 0 ], + [ [ [ 0, 2, -4, 0, 0, -1 ], [ 0, 1, -4, 1, 0, -1 ], [ 2, 2, -4, 0, 0, -1 ], [ 3, 1, -4, 0, 0, -1 ] ], 0.25 ], + [ [ [ 0, 2, -4, 0, 0, -1 ], [ 0, 1, -4, 1, 0, -1 ], [ 2, 1, -4, 0, 0, 0 ], [ 3, 1, -4, 0, 0, -1 ] ], 0.25 ] + ], + [ + [ [ [ 0, 2, -4, 0, 0, -1 ], [ 0, 1, -4, 1, 0, -1 ], [ 2, 1, -4, 0, 0, 0 ], [ 2, 1, -4, 1, 0, -1 ] ], 0.25 ], + [ [ [ 0, 2, -4, 0, 0, -1 ], [ 0, 1, -4, 1, 0, -1 ], [ 1, 2, -4, 1, 0, -1 ], [ 2, 1, -4, 1, 0, -1 ] ], 0.25 ], + [ [ [ 1, 1, -4, 1, 0, -1 ], [ 0, 1, -4, 1, 0, -1 ], [ 1, 2, -4, 1, 0, -1 ], [ 2, 1, -4, 1, 0, -1 ] ], 0 ], + [ [ [ 1, 1, -4, 1, 0, -1 ], [ 0, 1, -4, 1, 0, -1 ], [ 1, 2, -4, 1, 0, -1 ], [ 0, 2, -4, 1, 0, -1 ] ], 0.25 ] + ], + [ + [ [ [ 1, 1, -4, 1, 0, -1 ], [ 0, 1, -4, 1, 0, -1 ], [ 1, 2, -4, 1, 0, -1 ], [ 0, 1, -4, 1, 0, 0 ] ], 0 ], + [ [ [ 1, 1, -4, 1, 0, -1 ], [ 0, 1, -4, 1, 0, -1 ], [ 1, 1, -4, 1, 0, 0 ], [ 0, 1, -4, 1, 0, 0 ] ], 0.25 ], + [ [ [ -2, 1, -4, 1, 0, 0 ], [ 0, 1, -4, 1, 0, -1 ], [ 1, 1, -4, 1, 0, 0 ], [ 0, 1, -4, 1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -2, 1, -4, 1, 0, 0 ], [ 0, 1, -4, 1, 0, -1 ], [ 2, 1, -4, 0, 0, 0 ], [ 0, 1, -4, 1, 0, 0 ] ], 0 ], + [ [ [ -2, 1, -4, 1, 0, 0 ], [ 0, 0, -4, 1, 0, 0 ], [ 2, 1, -4, 0, 0, 0 ], [ 0, 1, -4, 1, 0, 0 ] ], 0.25 ], + [ [ [ -1, 1, -4, 0, 0, 0 ], [ 0, 0, -4, 1, 0, 0 ], [ 2, 1, -4, 0, 0, 0 ], [ 0, 1, -4, 1, 0, 0 ] ], 0.25 ], + [ [ [ -1, 1, -4, 0, 0, 0 ], [ 0, 0, -4, 1, 0, 0 ], [ 0, 2, -4, 1, 0, 0 ], [ 0, 1, -4, 1, 0, 0 ] ], 0.25 ], + [ [ [ -1, 1, -4, 0, 0, 0 ], [ 0, 0, -4, 1, 0, 0 ], [ 1, 0, -4, 1, 0, 0 ], [ 0, 1, -4, 1, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 1, -4, 0, 0, 0 ], [ 0, 0, -4, 1, 0, 0 ], [ 2, 0, -4, 0, 0, 0 ], [ 0, 1, -4, 1, 0, 0 ] ], 0 ], + [ [ [ -1, 1, -4, 0, 0, 0 ], [ 0, 0, -4, 1, 0, 0 ], [ 2, 0, -4, 0, 0, 0 ], [ 1, 0, -4, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, -5, 1, 0, 0 ], [ 0, 0, -4, 1, 0, 0 ], [ 2, 0, -4, 0, 0, 0 ], [ 1, 0, -4, 0, 0, 0 ] ], 0 ], + [ [ [ -1, 0, -5, 1, 0, 0 ], [ 0, 0, -4, 1, 0, 0 ], [ 1, 0, -3, 1, 0, 0 ], [ 1, 0, -4, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, -5, 1, 0, 0 ], [ 0, 0, -4, 1, 0, 0 ], [ 2, -1, -4, 1, 0, 0 ], [ 1, 0, -4, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, -5, 1, 0, 0 ], [ 0, 0, -4, 1, 0, 0 ], [ 1, 1, -4, 1, 0, 0 ], [ 1, 0, -4, 0, 0, 0 ] ], 0.25 ], + [ [ [ -1, 0, -5, 1, 0, 0 ], [ 0, 0, -4, 1, 0, 0 ], [ 1, 0, -4, 1, 0, 1 ], [ 1, 0, -4, 0, 0, 0 ] ], 0.25 ] + ], + [ + [ [ [ -2, 0, -4, 1, 0, 1 ], [ 0, 0, -4, 1, 0, 0 ], [ 1, 0, -4, 1, 0, 1 ], [ 1, 0, -4, 0, 0, 0 ] ], 0 ], + [ [ [ -2, 0, -4, 1, 0, 1 ], [ 0, 0, -4, 1, 0, 0 ], [ 1, 0, -4, 1, 0, 1 ], [ 0, -1, -4, 1, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -4, 1, 0, 1 ], [ -1, 0, -4, 1, 0, 1 ], [ 1, 0, -4, 1, 0, 1 ], [ 0, -1, -4, 1, 0, 1 ] ], 0.25 ] + ], + [ + [ [ [ -2, 0, -4, 1, 0, 1 ], [ -1, 0, -4, 1, 0, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ 0, -1, -4, 1, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -4, 1, 0, 1 ], [ -1, 0, -4, 1, 0, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ -1, 1, -4, 1, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -4, 1, 0, 1 ], [ 0, 0, -4, 1, 0, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ -1, 1, -4, 1, 0, 1 ] ], 0.25 ], + [ [ [ -2, 0, -4, 1, 0, 1 ], [ 1, 0, -4, 0, 0, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ -1, 1, -4, 1, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -4, 1, 0, 1 ], [ 1, 0, -4, 0, 0, 1 ], [ 0, 1, -4, 1, 0, 1 ], [ -1, 1, -4, 1, 0, 1 ] ], 0.25 ], + [ [ [ -2, 0, -4, 1, 0, 1 ], [ 1, 0, -4, 0, 0, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ -1, 1, -4, 1, 0, 1 ] ], 0.25 ], + [ [ [ -2, 0, -4, 1, 0, 1 ], [ 0, 0, -3, 1, 0, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ -1, 1, -4, 1, 0, 1 ] ], 0.25 ] + ], + [ + [ [ [ -2, 0, -4, 1, 0, 1 ], [ -1, 0, -4, 2, 1, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ -1, 1, -4, 1, 0, 1 ] ], 0 ], + [ [ [ -2, 0, -4, 1, 0, 1 ], [ -1, 0, -4, 2, 1, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ -1, 0, -4, 1, 1, 1 ] ], 0 ], + [ [ [ -2, 0, -5, 1, 1, 1 ], [ -1, 0, -4, 2, 1, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ -1, 0, -4, 1, 1, 1 ] ], 0.25 ], + [ [ [ -3, 0, -4, 2, 1, 1 ], [ -1, 0, -4, 2, 1, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ -1, 0, -4, 1, 1, 1 ] ], 0 ], + [ [ [ -3, 0, -4, 2, 1, 1 ], [ -1, 0, -4, 2, 1, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ 0, 0, -4, 2, 1, 1 ] ], 0.25 ], + [ [ [ -3, 0, -4, 2, 1, 1 ], [ -1, 0, -4, 2, 1, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ 1, 0, -5, 1, 1, 1 ] ], 0 ], + [ [ [ -2, 0, -4, 1, 1, 1 ], [ -1, 0, -4, 2, 1, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ 1, 0, -5, 1, 1, 1 ] ], 0.25 ] + ], + [ + [ [ [ -2, 0, -4, 1, 1, 1 ], [ -1, 0, -4, 2, 1, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ 0, 1, -4, 1, 1, 1 ] ], 0 ], + [ [ [ -1, 0, -4, 0, 1, 1 ], [ -1, 0, -4, 2, 1, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ 0, 1, -4, 1, 1, 1 ] ], 0 ], + [ [ [ -1, 0, -4, 0, 1, 1 ], [ -1, -1, -4, 1, 1, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ 0, 1, -4, 1, 1, 1 ] ], 0.25 ], + [ [ [ -1, 0, -4, 1, 1, 0 ], [ -1, -1, -4, 1, 1, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ 0, 1, -4, 1, 1, 1 ] ], 0 ], + [ [ [ -1, 0, -4, 1, 1, 0 ], [ -1, -1, -4, 1, 1, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ 0, -1, -4, 1, 1, 1 ] ], 0.25 ], + [ [ [ -1, 0, -4, 1, 1, 0 ], [ -1, -1, -4, 1, 1, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ 0, 0, -4, 1, 0, 1 ] ], 0.25 ] + ], + [ + [ [ [ -1, 0, -4, 1, 1, 0 ], [ -1, -1, -4, 1, 1, 1 ], [ 0, 0, -4, 1, 1, 1 ], [ 1, -1, -4, 1, 1, 0 ] ], 0 ], + [ [ [ -1, 0, -4, 1, 1, 0 ], [ -1, -1, -4, 1, 1, 1 ], [ 1, 0, -5, 1, 1, 0 ], [ 1, -1, -4, 1, 1, 0 ] ], 0 ], + [ [ [ -1, 0, -4, 1, 1, 0 ], [ 0, 0, -4, 0, 1, 0 ], [ 1, 0, -5, 1, 1, 0 ], [ 1, -1, -4, 1, 1, 0 ] ], 0.25 ], + [ [ [ -1, 0, -4, 1, 1, 0 ], [ -1, 0, -3, 1, 1, 0 ], [ 1, 0, -5, 1, 1, 0 ], [ 1, -1, -4, 1, 1, 0 ] ], 0 ], + [ [ [ -1, 0, -4, 1, 1, 0 ], [ -1, 0, -3, 1, 1, 0 ], [ 0, 1, -4, 1, 1, 0 ], [ 1, -1, -4, 1, 1, 0 ] ], 0 ], + [ [ [ -1, 0, -4, 1, 1, 0 ], [ -1, 0, -3, 1, 1, 0 ], [ 0, 1, -4, 1, 1, 0 ], [ 0, 0, -3, 1, 1, 0 ] ], 0.25 ], + [ [ [ -1, 0, -4, 1, 1, 0 ], [ -1, 0, -3, 1, 1, 0 ], [ 0, 1, -4, 1, 1, 0 ], [ 0, 0, -4, 1, 1, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 0, -4, 1, 1, 0 ], [ -1, 1, -5, 1, 1, 0 ], [ 0, 1, -4, 1, 1, 0 ], [ 0, 0, -4, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, -3, 1, 1, 0 ], [ -1, 1, -5, 1, 1, 0 ], [ 0, 1, -4, 1, 1, 0 ], [ 0, 0, -4, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, -3, 1, 1, 0 ], [ -1, 1, -5, 1, 1, 0 ], [ 0, 1, -4, 1, 1, 0 ], [ -1, 1, -3, 1, 1, 0 ] ], 0.25 ], + [ [ [ -2, 1, -3, 1, 1, 0 ], [ -1, 1, -5, 1, 1, 0 ], [ 0, 1, -4, 1, 1, 0 ], [ 0, 1, -4, 1, 1, -1 ] ], 0.25 ], + [ [ [ -2, 1, -3, 1, 1, 0 ], [ -1, 1, -5, 1, 1, 0 ], [ 0, 1, -4, 1, 1, 0 ], [ 0, 1, -4, 0, 1, 0 ] ], 0.25 ], + [ [ [ -1, 1, -4, 0, 1, 0 ], [ -1, 1, -5, 1, 1, 0 ], [ 0, 1, -4, 1, 1, 0 ], [ 0, 1, -4, 0, 1, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 1, -4, 0, 1, 0 ], [ -1, 1, -5, 1, 1, 0 ], [ 1, 1, -5, 0, 1, 0 ], [ 0, 1, -4, 0, 1, 0 ] ], 0 ], + [ [ [ -1, 1, -4, 0, 1, 0 ], [ -1, 2, -4, 0, 1, 0 ], [ 1, 1, -5, 0, 1, 0 ], [ 0, 1, -4, 0, 1, 0 ] ], 0 ], + [ [ [ -1, 1, -4, 0, 1, 0 ], [ -1, 2, -4, 0, 1, 0 ], [ 1, 1, -5, 0, 1, 0 ], [ 0, 1, -5, 0, 1, 0 ] ], 0.25 ], + [ [ [ -1, 1, -4, 0, 1, 0 ], [ -1, 2, -4, 0, 1, 0 ], [ 0, 2, -4, 0, 1, 0 ], [ 0, 1, -5, 0, 1, 0 ] ], 0.25 ], + [ [ [ -1, 1, -4, 0, 1, 0 ], [ -1, 2, -4, 0, 1, 0 ], [ 0, 2, -4, 0, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0 ], + [ [ [ -1, 1, -4, 0, 1, 0 ], [ 0, 1, -5, 0, 1, 0 ], [ 0, 2, -4, 0, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0.25 ], + [ [ [ -1, 1, -4, 0, 1, 0 ], [ -1, 2, -4, 0, 1, 0 ], [ 0, 2, -4, 0, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 1, -4, 0, 1, 0 ], [ -1, 2, -4, 0, 1, 0 ], [ -1, 1, -4, 2, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0 ], + [ [ [ -1, 1, -4, 0, 1, 0 ], [ -1, 1, -5, 1, 1, 0 ], [ -1, 1, -4, 2, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, -4, 1, 1, 0 ], [ -1, 1, -5, 1, 1, 0 ], [ -1, 1, -4, 2, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0.25 ], + [ [ [ -2, 1, -4, 1, 1, 0 ], [ -1, 1, -5, 1, 1, 0 ], [ 0, 1, -5, 1, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, -5, 1, 1, 0 ], [ -1, 1, -5, 1, 1, 0 ], [ 0, 1, -5, 1, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0.25 ] + ], + [ + [ [ [ 1, 0, -4, 1, 1, 0 ], [ -1, 1, -5, 1, 1, 0 ], [ 0, 1, -5, 1, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0.25 ], + [ [ [ 1, 0, -4, 1, 1, 0 ], [ 0, 1, -4, 1, 1, 0 ], [ 0, 1, -5, 1, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0.25 ], + [ [ [ 1, 0, -4, 1, 1, 0 ], [ 0, 1, -4, 1, 1, 0 ], [ -1, 2, -4, 1, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0.25 ], + [ [ [ 1, 0, -4, 1, 1, 0 ], [ 0, 0, -4, 1, 1, 0 ], [ -1, 2, -4, 1, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0 ], + [ [ [ 1, 0, -4, 1, 1, 0 ], [ 0, 0, -4, 1, 1, 0 ], [ 0, 1, -4, 1, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 0, -4, 1, 1, 0 ], [ 0, 0, -4, 1, 1, 0 ], [ 0, 1, -4, 1, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0 ], + [ [ [ -1, 0, -4, 1, 1, 0 ], [ -1, 2, -4, 1, 1, 0 ], [ 0, 1, -4, 1, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0 ], + [ [ [ -1, 0, -4, 1, 1, 0 ], [ -1, 2, -4, 1, 1, 0 ], [ 1, 1, -4, 0, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0.25 ], + [ [ [ -2, 2, -4, 1, 1, 0 ], [ -1, 2, -4, 1, 1, 0 ], [ 1, 1, -4, 0, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0.25 ], + [ [ [ -2, 1, -4, 1, 2, 0 ], [ -1, 2, -4, 1, 1, 0 ], [ 1, 1, -4, 0, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0 ], + [ [ [ -2, 1, -4, 1, 2, 0 ], [ -1, 2, -4, 1, 1, 0 ], [ 0, 2, -4, 1, 1, 0 ], [ -1, 1, -4, 1, 1, 0 ] ], 0.25 ] + ], + [ + [ [ [ -2, 1, -4, 1, 2, 0 ], [ -1, 2, -4, 1, 1, 0 ], [ 0, 2, -4, 1, 1, 0 ], [ -2, 2, -4, 1, 2, 0 ] ], 0 ], + [ [ [ -2, 1, -4, 1, 2, 0 ], [ -1, 2, -4, 1, 1, 0 ], [ 0, 1, -4, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 0 ] ], 0 ], + [ [ [ -2, 1, -4, 1, 2, 0 ], [ -1, 1, -4, 1, 2, 0 ], [ 0, 1, -4, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 0 ] ], 0.25 ], + [ [ [ -2, 1, -4, 1, 2, 0 ], [ -1, 1, -4, 1, 2, 0 ], [ 0, 1, -4, 1, 2, 0 ], [ -1, 1, -5, 1, 2, 0 ] ], 0 ], + [ [ [ -2, 1, -4, 1, 2, 0 ], [ -1, 1, -4, 1, 2, 0 ], [ -1, 2, -4, 1, 2, 0 ], [ -1, 1, -5, 1, 2, 0 ] ], 0 ], + [ [ [ -2, 1, -4, 1, 2, 0 ], [ 0, 1, -4, 1, 2, 0 ], [ -1, 2, -4, 1, 2, 0 ], [ -1, 1, -5, 1, 2, 0 ] ], 0.25 ], + [ [ [ -2, 1, -4, 1, 2, 0 ], [ 0, 1, -4, 1, 2, 0 ], [ -1, 2, -4, 1, 2, 0 ], [ -1, 1, -4, 1, 2, 0 ] ], 0.25 ] + ], + [ + [ [ [ -2, 1, -4, 1, 2, 0 ], [ 0, 1, -4, 1, 2, 0 ], [ 0, 1, -5, 1, 2, 0 ], [ -1, 1, -4, 1, 2, 0 ] ], 0 ], + [ [ [ -2, 1, -4, 1, 2, 0 ], [ 0, 1, -4, 1, 2, 0 ], [ 0, 1, -5, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 0 ] ], 0 ], + [ [ [ -2, 1, -5, 1, 2, 0 ], [ 0, 1, -4, 1, 2, 0 ], [ 0, 1, -5, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 0 ] ], 0.25 ], + [ [ [ -2, 1, -5, 1, 2, 0 ], [ 0, 1, -4, 1, 2, 0 ], [ -1, 1, -4, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 0 ] ], 0 ], + [ [ [ -3, 2, -4, 1, 2, 0 ], [ 0, 1, -4, 1, 2, 0 ], [ -1, 1, -4, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 0 ] ], 0.25 ] + ], + [ + [ [ [ -3, 2, -4, 1, 2, 0 ], [ -1, 3, -4, 1, 2, 0 ], [ -1, 1, -4, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 0 ] ], 0 ], + [ [ [ -3, 2, -4, 1, 2, 0 ], [ -1, 3, -4, 1, 2, 0 ], [ -2, 3, -4, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 0 ] ], 0 ], + [ [ [ -1, 2, -4, 1, 2, 0 ], [ -1, 3, -4, 1, 2, 0 ], [ -2, 3, -4, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 0 ] ], 0.25 ], + [ [ [ -1, 2, -4, 1, 2, 0 ], [ -2, 1, -4, 1, 2, 0 ], [ -2, 3, -4, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 0 ] ], 0.25 ] + ], + [ + [ [ [ -1, 2, -4, 1, 2, 0 ], [ -2, 1, -4, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 1 ], [ -2, 2, -4, 1, 2, 0 ] ], 0 ], + [ [ [ -1, 2, -4, 1, 2, 0 ], [ -2, 2, -5, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 1 ], [ -2, 2, -4, 1, 2, 0 ] ], 0 ], + [ [ [ -1, 2, -4, 1, 2, 0 ], [ -2, 2, -5, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 1 ], [ 0, 2, -4, 1, 2, 0 ] ], 0.25 ], + [ [ [ -1, 2, -4, 1, 2, 0 ], [ 0, 1, -4, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 1 ], [ 0, 2, -4, 1, 2, 0 ] ], 0.25 ], + [ [ [ -1, 2, -4, 1, 2, 0 ], [ 0, 1, -4, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 0 ], [ 0, 2, -4, 1, 2, 0 ] ], 0 ], + [ [ [ -1, 2, -4, 1, 2, 0 ], [ -1, 3, -4, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 0 ], [ 0, 2, -4, 1, 2, 0 ] ], 0.25 ] + ] + ] +], +"last_changes": +[ + [ [ -1, 2, -4, 1, 2, 0 ], [ -2, 2, -5, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 1 ], [ -2, 2, -4, 1, 2, 0 ] ], + [ [ -1, 2, -4, 1, 2, 0 ], [ -2, 2, -5, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 1 ], [ 0, 2, -4, 1, 2, 0 ] ], + [ [ -1, 2, -4, 1, 2, 0 ], [ 0, 1, -4, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 1 ], [ 0, 2, -4, 1, 2, 0 ] ], + [ [ -1, 2, -4, 1, 2, 0 ], [ 0, 1, -4, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 0 ], [ 0, 2, -4, 1, 2, 0 ] ], + [ [ -1, 2, -4, 1, 2, 0 ], [ -1, 3, -4, 1, 2, 0 ], [ -2, 2, -4, 1, 2, 0 ], [ 0, 2, -4, 1, 2, 0 ] ] +], +"cur_uid": "7f6eb065", +"ref_uid": "nil", +"order_seed": 446169, +"dur_seed": 217145, +"motifs_seed": 874972, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 1, 0.019607843137255, 0, 0.2156862745098, 0, 0.2516339869281, 0.76351351351351, 0.31045751633987, 0, 0.46732026143791, 0, 0.3921568627451, 0, 0.5359477124183, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 1, 0.15, 0.43, 1, 0.82 ], +"hd_exp": 10, +"hd_invert": 0, +"order": +[ + [ [ 1 ], [ 3, 2, 0, 3, 2, 0 ], [ ] ], + [ [ 1 ], [ 2, 0, 3 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 1, 1, 0 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 2, 3, 0, 2 ], [ ] ], + [ [ 2 ], [ 0, 1, 3, 1, 3 ], [ ] ], + [ [ 3 ], [ 1, 0, 2, 2, 1, 1, 2 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 1, 0, 3 ], [ ] ], + [ [ 3 ], [ 2, 0, 1 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 1, 2, 1 ], [ ] ], + [ [ 0 ], [ 1, 2, 3, 3, 2 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 1, 0 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 0, 2, 3 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 3 ], [ ] ], + [ [ 0 ], [ 2, 3, 1, 1, 1 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 1, 2, 1 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 0, 3, 3, 1 ], [ ] ], + [ [ 3 ], [ 2, 0, 1, 0 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 0, 2 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 2 ], [ ] ], + [ [ 1 ], [ 2, 0, 3, 0 ], [ ] ], + [ [ 1 ], [ 0, 2, 3, 2, 3 ], [ ] ], + [ [ 1 ], [ 3, 0, 2, 3, 3, 3, 3 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 3, 2, 0 ], [ ] ], + [ [ 1 ], [ 0, 2, 3 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 2, 2, 0, 2 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 0, 0, 1 ], [ ] ], + [ [ 0 ], [ 1, 3, 2, 2 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 3, 0, 3, 1 ], [ ] ], + [ [ 3 ], [ 0, 2, 1, 0, 0, 1 ], [ ] ], + [ [ 0 ], [ 3, 1, 2, 2, 3, 1 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 2, 0, 1, 2 ], [ ] ], + [ [ 1 ], [ 3, 2, 0, 3 ], [ ] ], + [ [ 1 ], [ 3, 2, 0 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 2, 2 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 2, 2, 2, 2 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 0 ], [ 2, 3, 1, 1, 2, 2, 1 ], [ ] ], + [ [ 2 ], [ 1, 3, 0, 0, 3, 3, 0 ], [ ] ], + [ [ 2 ], [ 3, 0, 1, 0, 3, 3 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 1, 2, 3, 3 ], [ ] ], + [ [ 2 ], [ 1, 0, 3, 3, 3, 0 ], [ ] ], + [ [ 0 ], [ 2, 1, 3, 2, 3, 1, 1 ], [ ] ], + [ [ 3 ], [ 2, 1, 0, 2, 0 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 1, 2 ], [ ] ], + [ [ 3 ], [ 0, 1, 2, 0, 0, 2 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 3, 2, 1, 3 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 2, 0 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 1 ], [ ] ], + [ [ 0 ], [ 2, 1, 3, 1, 2, 1 ], [ ] ] +], +"sus_weights": [ 0.69, 0, 0 ], +"order_size": [ 49, 49.489795918367 ], +"passages_size": [ 0, 5 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7f6eb065/lilypond/part_I.ly b/resources/string_quartet_3_rise/7f6eb065/lilypond/part_I.ly new file mode 100644 index 0000000..10906a9 --- /dev/null +++ b/resources/string_quartet_3_rise/7f6eb065/lilypond/part_I.ly @@ -0,0 +1,36 @@ +{ + { d''8^\markup { \pad-markup #0.2 "+0"}[ g'8^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ g'8[ a'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ a'4 ~ a'8[ f'8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { f'8[ fis'8^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ fis'4 g'4^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} a'4^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} ~ } + \bar "|" + { a'4 b'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↑" }}[ c''8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ c''8[ c''8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↓" }}] ~ c''4 } + \bar "|" + { ais'8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}[ c''8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ c''4 ~ c''8[ cis''8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ cis''8[ dis''8^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] } + \bar "|" + { gis''8^\markup { \pad-markup #0.2 "+31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ gis'8^\markup { \pad-markup #0.2 "+31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] e'2.^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { e'8[ fis'8^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }}] g'8^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ a'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] ~ a'2 ~ } + \bar "|" + { a'8[ e'8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }}] ~ e'8[ a'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ a'8[ b'8^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }}] cis''8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}[ d''8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] } + \bar "|" + { a'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ fis'8^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}] g'8^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}[ f'8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] a''8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ a'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ a'4 } + \bar "|" + { b'1^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} } + \bar "|" + { a4^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} gis8^\markup { \pad-markup #0.2 "+31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}[ e'8^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] a''2^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a''8[ gis''8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ gis''8[ a''8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] ~ a''2 } + \bar "|" + { g''4^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} d'8^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ dis'8^\markup { \pad-markup #0.2 "+26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}] ~ dis'2 ~ } + \bar "|" + { dis'8[ b8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ b2 ais8^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}[ c'8^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { c'4 ~ c'8[ ais8^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] gis''8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ fis''8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] f''8^\markup { \pad-markup #0.2 "+17"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ dis'8^\markup { \pad-markup #0.2 "+13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] } + \bar "|" + { f'8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 11↓" }}[ g'8^\markup { \pad-markup #0.2 "-27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] fis'8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ d'8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] cis'8^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ c'8^\markup { \pad-markup #0.2 "+36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }}] b4^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }} } + \bar "|" + { g4^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} a2.^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }} ~ } + \bar "|" + { a2 ~ a8[ a8^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] ais8^\markup { \pad-markup #0.2 "+42"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}[ d'8^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}]} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7f6eb065/lilypond/part_II.ly b/resources/string_quartet_3_rise/7f6eb065/lilypond/part_II.ly new file mode 100644 index 0000000..0d8a3c2 --- /dev/null +++ b/resources/string_quartet_3_rise/7f6eb065/lilypond/part_II.ly @@ -0,0 +1,36 @@ +{ + { g4^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} a8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}[ d''8^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] e''4^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↓" }} ~ e''8[ f''8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] } + \bar "|" + { fis''4^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }} cis''2^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} ~ cis''8[ d''8^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] } + \bar "|" + { e''8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ f''8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ f''4 e''8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}[ dis''8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] f''4^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }} } + \bar "|" + { cis''4^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} dis''8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}[ e''8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }}] ~ e''8[ dis''8^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}] gis'4^\markup { \pad-markup #0.2 "+31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} } + \bar "|" + { b'4^\markup { \pad-markup #0.2 "-38"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↓" }} b'2^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} cis''8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ d''8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { d''2 e''4^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }} fis''4^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }} } + \bar "|" + { f''8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ e''8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] dis''8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↑" }}[ d''8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] ~ d''8[ e''8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] f''8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}[ e''8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { e''2 f''8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ g''8^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}] ~ g''4 } + \bar "|" + { d''8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ a'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] e'8^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ fis'8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] gis'8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}[ a'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 7↑" }}] ~ a'4 } + \bar "|" + { b'8^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ e''8^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ e''2 fis''4^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} ~ } + \bar "|" + { fis''8[ f''8^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] fis''4^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} ~ fis''8[ f''8^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}] e''8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}[ fis''8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }}] ~ } + \bar "|" + { fis''8[ d''8^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↑" }}] ~ d''8[ dis''8^\markup { \pad-markup #0.2 "+26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ dis''8[ fis''8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}] ~ fis''8[ ais'8^\markup { \pad-markup #0.2 "+27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}] } + \bar "|" + { gis'8^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ b'8^\markup { \pad-markup #0.2 "-45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] c''8^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}[ cis''8^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] dis''8^\markup { \pad-markup #0.2 "+26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}[ f''8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 13↑" }}] ~ f''8[ ais'8^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] } + \bar "|" + { c''8^\markup { \pad-markup #0.2 "-34"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ ais'8^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 11↑" }}] ~ ais'2. ~ } + \bar "|" + { ais'8[ ais'8^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] a'2.^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} } + \bar "|" + { g'8^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}[ fis'8^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ fis'4 fis'8^\markup { \pad-markup #0.2 "+46"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}[ f'8^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ f'4 } + \bar "|" + { e'8^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}[ a'8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] b'4^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} e''8^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ d''8^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] a'4^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7f6eb065/lilypond/part_III.ly b/resources/string_quartet_3_rise/7f6eb065/lilypond/part_III.ly new file mode 100644 index 0000000..8e3cd22 --- /dev/null +++ b/resources/string_quartet_3_rise/7f6eb065/lilypond/part_III.ly @@ -0,0 +1,36 @@ +{ + { d'2^\markup { \pad-markup #0.2 "+0"} e'8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ b8^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] cis'4^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↑" }} ~ } + \bar "|" + { cis'2 fis8^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ gis8^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] ~ gis8[ a8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] } + \bar "|" + { e'8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ f'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }}] c'8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}[ cis'8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] d'8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}[ dis'8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] c'8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ cis'8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}] } + \bar "|" + { c'4^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} ~ c'8[ g8^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}] gis2^\markup { \pad-markup #0.2 "+31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} ~ } + \bar "|" + { gis4 a8^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}[ b8^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] cis'4^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }} cis'8^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↑" }}[ d'8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }}] } + \bar "|" + { b8^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↑" }}[ e'8^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }}] ~ e'8[ d'8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] e'4^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} a4^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a1 ~ } + \bar "|" + { a4 b4^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }} ~ b8[ d'8^\markup { \pad-markup #0.2 "-22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}] ~ d'8[ dis'8^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] } + \bar "|" + { e'4^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }} a4^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} e4^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ e8[ fis8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 13↑" }}] } + \bar "|" + { fis8^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ f8^\markup { \pad-markup #0.2 "-11"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}] ~ f4 fis8^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ f8^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] g4^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↑" }} ~ } + \bar "|" + { g2 ~ g8[ gis8^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↓" }}] ~ gis4 ~ } + \bar "|" + { gis2. f8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}[ f'8^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] } + \bar "|" + { g'4^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }} a'8^\markup { \pad-markup #0.2 "-50"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }}[ gis'8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↑" }}] ~ gis'4 dis4^\markup { \pad-markup #0.2 "+13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} ~ } + \bar "|" + { dis8[ e8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 7↓" }}] fis4^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↑" }} f2^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }} } + \bar "|" + { fis4^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 3↑" }} g8^\markup { \pad-markup #0.2 "+22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 5↓" }}[ fis8^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] f4^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 5↓" }} ~ f8[ a'8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { a'8[ d'8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] e'4^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }} ~ e'8[ d'8^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}] d''4^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super " 1↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/7f6eb065/lilypond/part_IV.ly b/resources/string_quartet_3_rise/7f6eb065/lilypond/part_IV.ly new file mode 100644 index 0000000..0f3af6f --- /dev/null +++ b/resources/string_quartet_3_rise/7f6eb065/lilypond/part_IV.ly @@ -0,0 +1,36 @@ +{ + { d4^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} a'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ ais'8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}] b'4^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }} cis''8^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ f8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { f4 fis8^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ g8^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 11↓" }}] ~ g4 ~ g8[ e8^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { e4 f8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ c8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↑" }}] f'2^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }} ~ } + \bar "|" + { f'4 ~ f'8[ g'8^\markup { \pad-markup #0.2 "+20"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] gis'8^\markup { \pad-markup #0.2 "+31"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ cis8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] dis4^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} } + \bar "|" + { e2^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} ~ e8[ g8^\markup { \pad-markup #0.2 "-24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}] ~ g4 ~ } + \bar "|" + { g8[ fis8^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] g4^\markup { \pad-markup #0.2 "+12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 3↓" }} a8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ e8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] ~ e8[ fis8^\markup { \pad-markup #0.2 "-44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] } + \bar "|" + { f8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }}[ cis'8^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↑" }}] ~ cis'8[ d'8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] e'8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}[ d'8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ d'8[ e'8^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↑" }}] ~ } + \bar "|" + { e'2 ~ e'8[ f'8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] g'8^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ d8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}] ~ } + \bar "|" + { d4 e8^\markup { \pad-markup #0.2 "+45"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 3↓" }}[ fis8^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] ~ fis8[ gis8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] a8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}[ b8^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { b4 cis'4^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} a'8^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ a,8^\markup { \pad-markup #0.2 "+43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ a,8[ c8^\markup { \pad-markup #0.2 "-26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 7↓" }}] } + \bar "|" + { cis2^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 13↓" }} ~ cis8[ d8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }}] e4^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { e4 g'4^\markup { \pad-markup #0.2 "-15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }} dis,4^\markup { \pad-markup #0.2 "+26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} fis,4^\markup { \pad-markup #0.2 "-43"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { fis,4 e,2^\markup { \pad-markup #0.2 "+37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 5↓" }} f,4^\markup { \pad-markup #0.2 "-36"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }} ~ } + \bar "|" + { f,4 ~ f,8[ fis,8^\markup { \pad-markup #0.2 "+29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↓" }}] gis,8^\markup { \pad-markup #0.2 "-16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ ais,8^\markup { \pad-markup #0.2 "+15"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 1↑" }}] c8^\markup { \pad-markup #0.2 "+47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 7↓" }}[ d8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 13↓" }}] ~ } + \bar "|" + { d2 cis4^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super " 5↑" }} ~ cis8[ b,8^\markup { \pad-markup #0.2 "+8"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}] ~ } + \bar "|" + { b,2 a,8^\markup { \pad-markup #0.2 "-23"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 1↑" }}[ f,8^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] d''4^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 3↓" }} ~ } + \bar "|" + { d''4 d8^\markup { \pad-markup #0.2 "-25"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}[ e8^\markup { \pad-markup #0.2 "-21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super " 1↑" }}] d2^\markup { \pad-markup #0.2 "+28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super " 11↑" }}} +\bar "||" +} \ No newline at end of file diff --git a/resources/string_quartet_3_rise/tmp/tmp_mus_model.json b/resources/string_quartet_3_rise/tmp/tmp_mus_model.json index 0270086..8d3e9ab 100644 --- a/resources/string_quartet_3_rise/tmp/tmp_mus_model.json +++ b/resources/string_quartet_3_rise/tmp/tmp_mus_model.json @@ -3,519 +3,224 @@ [ [ [ - [ [ [ 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.5 ], - [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.25 ], - [ [ [ 1, 0, 0, -1, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.625 ], - [ [ [ 1, 0, 0, -1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0.625 ], - [ [ [ 1, 0, 0, -1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ] ], 4.875 ], - [ [ [ 1, 0, 0, -1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ] ], 2.5 ], - [ [ [ 1, 0, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ] ], 0.5 ], - [ [ [ 1, 0, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 3.75 ] + [ [ [ -4, 6, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 6, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 7, -1, 1, -3, 2 ] ], 0.25 ], + [ [ [ -4, 6, -1, 1, -3, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ] ], 0.25 ] ], [ - [ [ [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 4.5 ], - [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0.625 ], - [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 4.375 ], - [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.75 ], - [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.75 ], - [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ] ], 0.125 ], - [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 4 ], - [ [ [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1.625 ] + [ [ [ -4, 6, 0, 1, -4, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 5, -1, 1, -3, 2 ] ], 0.25 ], + [ [ [ -4, 6, 0, 1, -4, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 5, -2, 1, -2, 2 ] ], 0 ], + [ [ [ -4, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 5, -2, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, -1, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0 ], + [ [ [ -5, 6, 0, 1, -2, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ], + [ [ [ -4, 5, 0, 1, -3, 2 ], [ -3, 5, -1, 1, -2, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ] ], [ - [ [ [ 1, -1, 0, 0, 0, 0 ], [ 1, 1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.625 ], - [ [ [ 1, -1, 0, 0, 0, 0 ], [ 1, 1, 0, 0, 0, -1 ], [ 0, 1, 0, 0, -1, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.5 ], - [ [ [ 0, 1, 0, 0, 0, 0 ], [ 1, 1, 0, 0, 0, -1 ], [ 0, 1, 0, 0, -1, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.75 ], - [ [ [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 4 ], - [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.75 ], - [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, -1, 0 ], [ 0, 1, -1, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.375 ], - [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, -1, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.875 ], - [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, -1, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 4 ] + [ [ [ -4, 5, 0, 1, -3, 2 ], [ -3, 5, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 6, -1, 1, -2, 2 ] ], 0.25 ] ], [ - [ [ [ 0, 1, 0, 0, 0, 0 ], [ -2, 1, 0, 1, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.375 ], - [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 1, 0, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.875 ], - [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 1, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.625 ], - [ [ [ 0, 1, 0, 0, 0, 0 ], [ -2, 1, 0, 2, 0, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.5 ], - [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 1 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.5 ], - [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, -1, 0 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 4.75 ] + [ [ [ -4, 5, 0, 1, -3, 2 ], [ -3, 5, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 6, 1, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 5, 0, 1, -3, 2 ], [ -4, 7, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 6, 1, 1, -3, 2 ] ], 0.25 ], + [ [ [ -4, 5, 0, 1, -3, 2 ], [ -4, 7, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 5, 0, 1, -3, 2 ] ], 0.25 ], + [ [ [ -4, 5, 0, 1, -3, 2 ], [ -4, 7, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 6, 0, 1, -4, 2 ] ], 0.25 ] ], [ - [ [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, -1, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.25 ], - [ [ [ 1, 1, 0, -1, 0, 0 ], [ -1, 1, 0, 0, -1, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 3.625 ], - [ [ [ 1, 1, 0, -1, 0, 0 ], [ -2, 1, 0, 0, 0, 1 ], [ -1, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.625 ], - [ [ [ 1, 1, 0, 0, 0, -1 ], [ -2, 1, 0, 0, 0, 1 ], [ -1, 2, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.625 ], - [ [ [ 1, 1, 0, 0, 0, -1 ], [ -2, 1, 0, 0, 0, 1 ], [ -1, 1, 0, 0, 0, 1 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.25 ], - [ [ [ 1, 1, 0, 0, 0, -1 ], [ -2, 1, 0, 0, 0, 1 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.125 ], - [ [ [ 1, 0, 0, 0, 0, 0 ], [ -2, 1, 0, 0, 0, 1 ], [ -1, 1, 0, 1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.125 ], - [ [ [ 1, 0, 0, 0, 0, 0 ], [ -2, 1, 0, 0, 0, 1 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 2.5 ] + [ [ [ -4, 5, 0, 1, -3, 2 ], [ -4, 7, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 6, -1, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 5, 0, 1, -3, 2 ], [ -3, 6, 0, 1, -4, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 6, -1, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 6, 0, 1, -4, 2 ], [ -3, 6, 0, 1, -4, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 6, -1, 1, -3, 2 ] ], 0.25 ] ], [ - [ [ [ -2, 1, 1, 0, 0, 0 ], [ -2, 1, 0, 0, 0, 1 ], [ 0, 1, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.875 ], - [ [ [ -2, 1, 1, 0, 0, 0 ], [ -2, 1, 0, 0, 0, 1 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 0.25 ], - [ [ [ -2, 1, 1, 0, 0, 0 ], [ -2, 1, 0, 1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 0.625 ], - [ [ [ -2, 1, 1, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 0.375 ], - [ [ [ -1, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 0.75 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 3.25 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 4.5 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 1, 1, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 3.875 ] + [ [ [ -4, 6, 0, 1, -4, 2 ], [ -3, 6, 0, 1, -4, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 7, 0, 1, -3, 2 ] ], 0.25 ], + [ [ [ -4, 6, 0, 1, -4, 2 ], [ -3, 5, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 7, 0, 1, -3, 2 ] ], 0.25 ], + [ [ [ -4, 5, 0, 1, -3, 2 ], [ -3, 5, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 7, 0, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 5, 0, 1, -3, 2 ], [ -4, 6, 1, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 7, 0, 1, -3, 2 ] ], 0.25 ], + [ [ [ -5, 7, 0, 1, -3, 2 ], [ -4, 6, 1, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 7, 0, 1, -3, 2 ] ], 0.25 ], + [ [ [ -5, 7, 0, 1, -3, 2 ], [ -4, 6, 1, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 6, -1, 1, -3, 2 ] ], 0 ], + [ [ [ -5, 7, 0, 1, -3, 2 ], [ -3, 6, 0, 0, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 6, -1, 1, -3, 2 ] ], 0.25 ] ], [ - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 2, 1, 0, -2, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 0 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 0, 1, 1, -1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 0.625 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 0.25 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 1, 1, 0, -1, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 0.5 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 1, 1, -1, -1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 4 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 4.75 ] + [ [ [ -5, 7, 0, 1, -3, 2 ], [ -5, 6, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 6, -1, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 6, -1, 1, -3, 2 ], [ -5, 6, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 6, -1, 1, -3, 2 ] ], 0.25 ] ], [ - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 0, 1, 0, -1, 0, 0 ] ], 0.5 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ -1, 1, 0, 1, -1, 0 ] ], 0.625 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 1, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ -1, 1, 0, 1, -1, 0 ] ], 0.25 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 1, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 0.25 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 1, -1, 0 ], [ 0, 1, 0, 0, -1, 1 ], [ 0, 1, 0, 0, -1, 0 ] ], 0.75 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 1, -1, 0 ], [ -1, 1, 0, 0, -1, 1 ], [ 0, 1, 0, 0, -1, 0 ] ], 4 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 1, -1, 0 ], [ -1, 1, 0, 1, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 3.25 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ -1, 1, 0, 1, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 2.75 ] + [ [ [ -4, 6, -1, 1, -3, 2 ], [ -5, 6, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 6, 0, 2, -3, 2 ] ], 0 ], + [ [ [ -5, 6, 0, 2, -3, 2 ], [ -5, 6, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 6, 0, 2, -3, 2 ] ], 0.25 ], + [ [ [ -7, 6, 0, 2, -3, 2 ], [ -5, 6, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 6, 0, 2, -3, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 1, -3, 2 ], [ -5, 6, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 6, 0, 2, -3, 2 ] ], 0.25 ], + [ [ [ -6, 6, 0, 1, -3, 2 ], [ -5, 6, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 6, 0, 1, -3, 2 ] ], 0 ], + [ [ [ -5, 6, 0, 0, -3, 2 ], [ -5, 6, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 6, 0, 1, -3, 2 ] ], 0.25 ] ], [ - [ [ [ -1, 1, 0, 0, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ -1, 2, 1, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 0.25 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 0.5 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ -1, 3, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 0 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 0, 1, 1, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 0.25 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 0.5 ], - [ [ [ -1, 1, 0, 0, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 1.5 ] + [ [ [ -5, 6, 0, 0, -3, 2 ], [ -4, 6, 0, 0, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 6, 0, 1, -3, 2 ] ], 0 ], + [ [ [ -3, 5, 0, 1, -3, 2 ], [ -4, 6, 0, 0, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 6, 0, 1, -3, 2 ] ], 0.25 ], + [ [ [ -3, 5, 0, 1, -3, 2 ], [ -4, 5, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 6, 0, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 7, 0, 1, -3, 2 ], [ -4, 5, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 6, 0, 1, -3, 2 ] ], 0.25 ] ], [ - [ [ [ -1, 1, 0, 0, -1, 0 ], [ 0, 2, 0, -1, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 3 ], - [ [ [ -2, 3, 0, 0, -1, 0 ], [ 0, 2, 0, -1, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 0.875 ], - [ [ [ -2, 3, 0, 0, -1, 0 ], [ 0, 2, 0, -1, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 0, 2, 0, 0, -2, 0 ] ], 0.75 ], - [ [ [ -2, 2, 0, 0, -1, 1 ], [ 0, 2, 0, -1, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 0, 2, 0, 0, -2, 0 ] ], 0.875 ], - [ [ [ -2, 2, 0, 0, -1, 1 ], [ 0, 2, 0, -1, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 0, 2, -1, 0, -1, 0 ] ], 4.25 ], - [ [ [ -2, 2, 0, 0, -1, 1 ], [ -1, 2, 1, 0, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 0, 2, -1, 0, -1, 0 ] ], 1.125 ], - [ [ [ -2, 2, 0, 0, -1, 1 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 0, 2, -1, 0, -1, 0 ] ], 0.375 ], - [ [ [ -2, 2, 0, 1, -1, 0 ], [ -1, 2, 0, 0, 0, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 0, 2, -1, 0, -1, 0 ] ], 1.875 ] + [ [ [ -4, 6, 0, 0, -3, 2 ], [ -4, 5, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -3, 6, 0, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 6, 0, 0, -3, 2 ], [ -4, 5, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 7, 0, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 6, 0, 0, -3, 2 ], [ -5, 7, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 7, 0, 1, -3, 2 ] ], 0.25 ] ], [ - [ [ [ -2, 2, 0, 1, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 0, 2, 0, 0, -1, 0 ], [ 0, 2, -1, 0, -1, 0 ] ], 0.625 ], - [ [ [ -2, 2, 0, 1, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 0, 2, 0, 1, -1, -1 ], [ 0, 2, -1, 0, -1, 0 ] ], 0.625 ], - [ [ [ -2, 2, 0, 1, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 0, 2, 0, 1, -1, -1 ], [ -1, 2, 0, 1, -1, 0 ] ], 0.25 ], - [ [ [ -2, 2, 0, 1, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 0, 2, 0, 1, -1, -1 ], [ 0, 2, 0, 0, -1, 0 ] ], 0.375 ], - [ [ [ -2, 2, 0, 1, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 0, 2, 0, 1, -1, -1 ], [ -1, 2, 1, 1, -1, 0 ] ], 0.5 ], - [ [ [ -2, 2, 0, 1, -1, 0 ], [ -1, 2, 0, 0, -1, 0 ], [ 0, 2, 0, 1, -1, -1 ], [ -1, 2, 0, 1, 0, 0 ] ], 0.125 ], - [ [ [ -2, 2, 0, 1, -1, 0 ], [ -2, 2, 1, 1, -1, 0 ], [ 0, 2, 0, 1, -1, -1 ], [ -1, 2, 0, 1, 0, 0 ] ], 3.875 ], - [ [ [ -2, 2, 0, 1, -1, 0 ], [ -2, 2, 1, 1, -1, 0 ], [ 0, 2, 0, 1, -1, -1 ], [ -1, 2, 0, 1, -1, -1 ] ], 4.125 ] + [ [ [ -4, 6, 0, 0, -3, 2 ], [ -5, 7, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -2, 5, 0, 0, -3, 2 ] ], 0 ], + [ [ [ -4, 6, 0, 0, -3, 2 ], [ -5, 7, 0, 1, -3, 2 ], [ -5, 8, 0, 1, -3, 2 ], [ -2, 5, 0, 0, -3, 2 ] ], 0.25 ], + [ [ [ -4, 6, 0, 0, -3, 2 ], [ -5, 7, 0, 1, -3, 2 ], [ -3, 6, 0, 0, -3, 2 ], [ -2, 5, 0, 0, -3, 2 ] ], 0.25 ], + [ [ [ -4, 6, 0, 0, -3, 2 ], [ -5, 7, 0, 1, -3, 2 ], [ -4, 7, 0, 1, -4, 2 ], [ -2, 5, 0, 0, -3, 2 ] ], 0 ], + [ [ [ -4, 6, 0, 0, -3, 2 ], [ -5, 7, 0, 1, -3, 2 ], [ -4, 7, 0, 1, -4, 2 ], [ -2, 6, 0, 0, -4, 2 ] ], 0.25 ] ], [ - [ [ [ -3, 2, 1, 2, -1, 0 ], [ -2, 2, 1, 1, -1, 0 ], [ 0, 2, 0, 1, -1, -1 ], [ -1, 2, 0, 1, -1, -1 ] ], 3.375 ], - [ [ [ -3, 2, 1, 2, -1, 0 ], [ -2, 2, 1, 1, -1, 0 ], [ 0, 2, 0, 1, -1, -1 ], [ -1, 1, 1, 1, -1, 0 ] ], 0.375 ], - [ [ [ -3, 2, 1, 2, -1, 0 ], [ -2, 2, 1, 1, -1, 0 ], [ -2, 2, 1, 2, -1, 0 ], [ -1, 1, 1, 1, -1, 0 ] ], 1.125 ], - [ [ [ -3, 2, 1, 2, -1, 0 ], [ -2, 2, 1, 1, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -1, 1, 1, 1, -1, 0 ] ], 3.875 ], - [ [ [ -4, 2, 1, 2, -1, 0 ], [ -2, 2, 1, 1, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -1, 1, 1, 1, -1, 0 ] ], 4 ], - [ [ [ -4, 2, 1, 2, -1, 0 ], [ -2, 2, 1, 1, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -1, 2, 1, 1, -2, 0 ] ], 3.875 ], - [ [ [ -4, 2, 1, 2, -1, 0 ], [ -2, 2, 1, 1, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -2, 2, 1, 1, -1, 1 ] ], 0.375 ], - [ [ [ -3, 2, 1, 1, -1, 0 ], [ -2, 2, 1, 1, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -2, 2, 1, 1, -1, 1 ] ], 1.5 ] + [ [ [ -4, 6, 0, 0, -3, 2 ], [ -5, 7, 0, 1, -3, 2 ], [ -4, 7, 0, 1, -4, 2 ], [ -4, 7, 0, 1, -3, 2 ] ], 0.25 ], + [ [ [ -4, 6, 0, 0, -3, 2 ], [ -5, 7, 0, 1, -3, 2 ], [ -4, 6, 0, 1, -3, 2 ], [ -4, 7, 0, 1, -3, 2 ] ], 0.25 ], + [ [ [ -4, 6, 0, 0, -3, 2 ], [ -5, 7, 0, 1, -3, 2 ], [ -5, 7, 1, 1, -3, 2 ], [ -4, 7, 0, 1, -3, 2 ] ], 0.25 ] ], [ - [ [ [ -2, 2, 1, 0, -1, 0 ], [ -2, 2, 1, 1, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -2, 2, 1, 1, -1, 1 ] ], 1 ], - [ [ [ -2, 2, 1, 0, -1, 0 ], [ -1, 2, 1, 0, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -2, 2, 1, 1, -1, 1 ] ], 0.875 ], - [ [ [ -2, 2, 1, 1, -1, -1 ], [ -1, 2, 1, 0, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -2, 2, 1, 1, -1, 1 ] ], 0.125 ], - [ [ [ -2, 1, 1, 1, -1, 0 ], [ -1, 2, 1, 0, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -2, 2, 1, 1, -1, 1 ] ], 0.75 ], - [ [ [ -2, 1, 1, 1, -1, 0 ], [ -2, 2, 2, 1, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -2, 2, 1, 1, -1, 1 ] ], 0.625 ], - [ [ [ -2, 1, 1, 1, -1, 0 ], [ -2, 2, 1, 1, 0, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -2, 2, 1, 1, -1, 1 ] ], 0.875 ], - [ [ [ -2, 1, 1, 1, -1, 0 ], [ -2, 3, 1, 1, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -2, 2, 1, 1, -1, 1 ] ], 5.125 ] + [ [ [ -5, 6, 1, 1, -3, 2 ], [ -5, 7, 0, 1, -3, 2 ], [ -5, 7, 1, 1, -3, 2 ], [ -4, 7, 0, 1, -3, 2 ] ], 0 ], + [ [ [ -5, 6, 1, 1, -3, 2 ], [ -5, 7, 0, 1, -3, 2 ], [ -5, 7, 1, 1, -3, 2 ], [ -5, 8, 1, 1, -3, 2 ] ], 0 ], + [ [ [ -5, 6, 1, 1, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ], [ -5, 7, 1, 1, -3, 2 ], [ -5, 8, 1, 1, -3, 2 ] ], 0.25 ] ], [ - [ [ [ -2, 2, 1, 1, -2, 0 ], [ -2, 3, 1, 1, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -2, 2, 1, 1, -1, 1 ] ], 0.375 ], - [ [ [ -2, 2, 1, 1, -2, 0 ], [ -2, 3, 1, 1, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -2, 3, 2, 1, -1, 0 ] ], 0.75 ], - [ [ [ -2, 2, 1, 1, -2, 0 ], [ -2, 3, 1, 1, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -2, 3, 1, 1, 0, 0 ] ], 0.75 ], - [ [ [ -2, 2, 1, 1, -2, 0 ], [ -2, 3, 1, 1, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -1, 3, 1, 1, -2, 0 ] ], 3.875 ], - [ [ [ -2, 2, 1, 1, -2, 0 ], [ -2, 3, 1, 1, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -3, 4, 1, 1, -1, 0 ] ], 4.25 ], - [ [ [ -2, 2, 1, 1, -2, 0 ], [ -2, 3, 1, 1, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -2, 2, 2, 1, -1, 0 ] ], 0.625 ], - [ [ [ -2, 2, 1, 1, -2, 0 ], [ -2, 3, 1, 1, -1, 0 ], [ -1, 2, 1, 1, -1, 0 ], [ -1, 1, 1, 1, -1, 0 ] ], 2.75 ] + [ [ [ -5, 6, 1, 1, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ], [ -6, 9, 1, 1, -3, 2 ], [ -5, 8, 1, 1, -3, 2 ] ], 0 ], + [ [ [ -5, 6, 1, 1, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ], [ -6, 9, 1, 1, -3, 2 ], [ -4, 8, 1, 0, -3, 2 ] ], 0.25 ] ], [ - [ [ [ -2, 2, 1, 1, -2, 0 ], [ -2, 3, 1, 1, -1, 0 ], [ -1, 3, 1, 1, -2, 0 ], [ -1, 1, 1, 1, -1, 0 ] ], 4 ], - [ [ [ -2, 2, 1, 1, -2, 0 ], [ -2, 3, 1, 1, -1, 0 ], [ -1, 3, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -2, 0 ] ], 0.375 ], - [ [ [ -2, 2, 1, 1, -2, 0 ], [ 0, 2, 1, 0, -2, 0 ], [ -1, 3, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -2, 0 ] ], 4.5 ], - [ [ [ -2, 2, 1, 1, -2, 0 ], [ 0, 2, 1, 0, -2, 0 ], [ -1, 3, 1, 1, -2, 0 ], [ -2, 2, 1, 1, -1, 0 ] ], 0.625 ], - [ [ [ -2, 2, 1, 1, -2, 0 ], [ 0, 2, 1, 0, -2, 0 ], [ -1, 3, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 0 ] ], 0.875 ], - [ [ [ -2, 2, 1, 1, -2, 0 ], [ -1, 2, 2, 1, -2, 0 ], [ -1, 3, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 0 ] ], 0.375 ], - [ [ [ -2, 2, 1, 1, -2, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 3, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 0 ] ], 0.125 ], - [ [ [ -2, 2, 1, 1, -2, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -2, 2, 1, 1, -2, 1 ], [ -1, 2, 1, 1, -3, 0 ] ], 1.25 ] + [ [ [ -5, 6, 1, 1, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ], [ -5, 8, 0, 1, -3, 2 ], [ -4, 8, 1, 0, -3, 2 ] ], 0.25 ], + [ [ [ -5, 6, 1, 1, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ], [ -4, 6, 1, 1, -3, 2 ], [ -4, 8, 1, 0, -3, 2 ] ], 0.25 ], + [ [ [ -5, 6, 1, 1, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ], [ -5, 8, 1, 1, -3, 2 ], [ -4, 8, 1, 0, -3, 2 ] ], 0.25 ] ], [ - [ [ [ -2, 3, 1, 1, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -2, 2, 1, 1, -2, 1 ], [ -1, 2, 1, 1, -3, 0 ] ], 0.625 ], - [ [ [ -2, 3, 1, 1, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ 0, 2, 1, 1, -3, -1 ], [ -1, 2, 1, 1, -3, 0 ] ], 0.625 ], - [ [ [ -2, 3, 1, 1, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 0 ] ], 0.375 ], - [ [ [ -2, 1, 1, 2, -2, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 0 ] ], 0.625 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 0 ] ], 0.5 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 3, 1, 1, -3, 0 ], [ -1, 2, 1, 1, -3, 0 ] ], 0.75 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 0 ] ], 3.125 ] + [ [ [ -7, 8, 1, 2, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ], [ -5, 8, 1, 1, -3, 2 ], [ -4, 8, 1, 0, -3, 2 ] ], 0 ], + [ [ [ -7, 8, 1, 2, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ], [ -5, 8, 1, 1, -3, 2 ], [ -5, 8, 2, 1, -3, 2 ] ], 0.25 ], + [ [ [ -7, 8, 1, 2, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ], [ -6, 9, 1, 1, -3, 2 ], [ -5, 8, 2, 1, -3, 2 ] ], 0 ], + [ [ [ -7, 8, 1, 2, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ], [ -6, 9, 1, 1, -3, 2 ], [ -4, 7, 1, 1, -3, 2 ] ], 0.25 ], + [ [ [ -7, 8, 1, 2, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ], [ -6, 9, 1, 1, -3, 2 ], [ -5, 9, 1, 1, -3, 2 ] ], 0.25 ], + [ [ [ -7, 8, 1, 2, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ], [ -6, 9, 1, 1, -3, 2 ], [ -4, 8, 0, 1, -3, 2 ] ], 0.25 ] ], [ - [ [ [ -2, 1, 2, 1, -2, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 0 ] ], 0.375 ], - [ [ [ -2, 2, 2, 1, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 0 ] ], 0.125 ], - [ [ [ -1, 1, 1, 1, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 0 ] ], 0.5 ], - [ [ [ -2, 1, 1, 1, -2, 1 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 0 ] ], 4 ], - [ [ [ -1, 2, 0, 1, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 0 ] ], 4.125 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 0 ] ], 4.875 ] + [ [ [ -7, 8, 1, 2, -3, 2 ], [ -5, 7, 0, 1, -3, 2 ], [ -6, 9, 1, 1, -3, 2 ], [ -4, 8, 0, 1, -3, 2 ] ], 0 ], + [ [ [ -7, 8, 1, 2, -3, 2 ], [ -5, 7, 0, 1, -3, 2 ], [ -5, 8, 0, 1, -3, 2 ], [ -4, 8, 0, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 7, 0, 1, -3, 2 ], [ -5, 7, 0, 1, -3, 2 ], [ -5, 8, 0, 1, -3, 2 ], [ -4, 8, 0, 1, -3, 2 ] ], 0.25 ], + [ [ [ -4, 7, 0, 1, -3, 2 ], [ -6, 8, 0, 1, -3, 2 ], [ -5, 8, 0, 1, -3, 2 ], [ -4, 8, 0, 1, -3, 2 ] ], 0.25 ], + [ [ [ -4, 7, 0, 1, -3, 2 ], [ -5, 8, 0, 0, -3, 2 ], [ -5, 8, 0, 1, -3, 2 ], [ -4, 8, 0, 1, -3, 2 ] ], 0.25 ] ], [ - [ [ [ -2, 2, 1, 2, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 1, -2, 1 ] ], 0.5 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 2, -2, 0 ] ], 0.25 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 3, 1, 2, -3, 0 ] ], 0.5 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 2, -3, 1 ] ], 0.75 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -1, 1, 1, 2, -2, 0 ] ], 0.625 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ 0, 2, 1, 0, -3, 1 ] ], 9.25 ] + [ [ [ -5, 8, 1, 1, -3, 2 ], [ -5, 8, 0, 0, -3, 2 ], [ -5, 8, 0, 1, -3, 2 ], [ -4, 8, 0, 1, -3, 2 ] ], 0.25 ], + [ [ [ -5, 8, 1, 1, -3, 2 ], [ -5, 8, 0, 0, -3, 2 ], [ -5, 8, 0, 1, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 8, 0, 0, -3, 2 ], [ -5, 8, 0, 0, -3, 2 ], [ -5, 8, 0, 1, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ] ], 0.25 ] ], [ - [ [ [ -2, 2, 1, 2, -3, 0 ], [ 0, 1, 1, 1, -2, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -1, 2, 2, 1, -3, 1 ] ], 0.25 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ 0, 2, 1, 1, -3, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -1, 2, 2, 1, -3, 1 ] ], 4.125 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ 0, 2, 1, 1, -3, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -1, 2, 1, 2, -4, 0 ] ], 4.375 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ -2, 2, 1, 1, -4, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -1, 2, 1, 2, -4, 0 ] ], 0.125 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ -2, 2, 1, 1, -4, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -1, 2, 0, 2, -3, 0 ] ], 0.5 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ -2, 2, 0, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -1, 2, 0, 2, -3, 0 ] ], 0.5 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ -2, 2, 0, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 3, -3, 0 ] ], 0.75 ] + [ [ [ -4, 8, 0, 0, -3, 2 ], [ -5, 8, 0, 0, -3, 2 ], [ -6, 9, 1, 1, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ] ], 0 ], + [ [ [ -4, 8, 0, 0, -3, 2 ], [ -7, 8, 1, 2, -3, 2 ], [ -6, 9, 1, 1, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ] ], 0 ], + [ [ [ -6, 8, 1, 2, -3, 2 ], [ -7, 8, 1, 2, -3, 2 ], [ -6, 9, 1, 1, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ] ], 0.25 ] ], [ - [ [ [ -2, 2, 1, 2, -3, 0 ], [ -3, 2, 1, 2, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 3, -3, 0 ] ], 0.25 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ -2, 2, 1, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 3, -3, 0 ] ], 0.5 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ -1, 2, 1, 0, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 3, -3, 0 ] ], 0.75 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ -2, 1, 1, 3, -3, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 3, -3, 0 ] ], 0.125 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ -2, 2, 1, 3, -4, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 3, -3, 0 ] ], 0.75 ], - [ [ [ -2, 2, 1, 2, -3, 0 ], [ -2, 3, 1, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 3, -3, 0 ] ], 4.25 ] + [ [ [ -6, 8, 1, 2, -3, 2 ], [ -7, 8, 1, 2, -3, 2 ], [ -6, 8, 0, 2, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ] ], 0.25 ], + [ [ [ -6, 8, 1, 2, -3, 2 ], [ -7, 8, 1, 2, -3, 2 ], [ -7, 9, 1, 2, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ] ], 0.25 ], + [ [ [ -6, 8, 1, 2, -3, 2 ], [ -7, 8, 1, 2, -3, 2 ], [ -7, 8, 1, 2, -3, 3 ], [ -6, 8, 1, 1, -3, 2 ] ], 0.25 ], + [ [ [ -6, 8, 1, 2, -3, 2 ], [ -7, 8, 1, 2, -3, 2 ], [ -5, 7, 1, 1, -3, 2 ], [ -6, 8, 1, 1, -3, 2 ] ], 0.25 ], + [ [ [ -6, 8, 1, 2, -3, 2 ], [ -7, 8, 1, 2, -3, 2 ], [ -6, 8, 1, 2, -4, 2 ], [ -6, 8, 1, 1, -3, 2 ] ], 0.25 ] ], [ - [ [ [ -2, 2, 1, 3, -3, -1 ], [ -2, 3, 1, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 3, -3, 0 ] ], 0.625 ], - [ [ [ -2, 2, 1, 3, -3, -1 ], [ -1, 2, 0, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 3, -3, 0 ] ], 0.75 ], - [ [ [ -2, 1, 1, 3, -3, 0 ], [ -1, 2, 0, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 3, -3, 0 ] ], 0.5 ], - [ [ [ -2, 1, 1, 3, -3, 0 ], [ -4, 3, 1, 3, -3, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 3, -3, 0 ] ], 0.375 ], - [ [ [ -4, 3, 1, 1, -3, 1 ], [ -4, 3, 1, 3, -3, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 3, -3, 0 ] ], 0.625 ], - [ [ [ -4, 3, 1, 1, -3, 1 ], [ -4, 2, 1, 3, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 3, -3, 0 ] ], 0.75 ], - [ [ [ -4, 2, 1, 1, -3, 2 ], [ -4, 2, 1, 3, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 3, -3, 0 ] ], 3 ] + [ [ [ -6, 8, 1, 2, -3, 2 ], [ -7, 8, 1, 2, -3, 2 ], [ -6, 8, 1, 2, -4, 2 ], [ -7, 8, 2, 2, -3, 2 ] ], 0 ], + [ [ [ -6, 8, 1, 2, -3, 2 ], [ -7, 8, 2, 2, -4, 2 ], [ -6, 8, 1, 2, -4, 2 ], [ -7, 8, 2, 2, -3, 2 ] ], 0.25 ], + [ [ [ -6, 8, 1, 2, -3, 2 ], [ -7, 8, 2, 2, -4, 2 ], [ -6, 8, 1, 2, -4, 2 ], [ -6, 8, 0, 2, -4, 2 ] ], 0.25 ] ], [ - [ [ [ -4, 2, 1, 1, -3, 2 ], [ -3, 2, 1, 1, -3, 2 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 3, -3, 0 ] ], 0.5 ], - [ [ [ -4, 2, 1, 1, -3, 2 ], [ -3, 2, 1, 1, -3, 2 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 2, 1, -3, 1 ] ], 4.875 ], - [ [ [ -4, 2, 1, 2, -3, 1 ], [ -3, 2, 1, 1, -3, 2 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 2, 1, -3, 1 ] ], 0.75 ], - [ [ [ -3, 2, 1, 1, -3, 1 ], [ -3, 2, 1, 1, -3, 2 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 2, 1, -3, 1 ] ], 0.125 ], - [ [ [ -3, 2, 1, 1, -3, 1 ], [ -3, 2, 1, 2, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 2, 1, -3, 1 ] ], 3.75 ], - [ [ [ -3, 2, 1, 1, -3, 1 ], [ -3, 2, 1, 2, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 1, -2, 1 ] ], 0.75 ], - [ [ [ -3, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 1, -2, 1 ] ], 0.625 ], - [ [ [ -2, 2, 1, 0, -3, 1 ], [ -2, 2, 1, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 1, -2, 1 ] ], 1.125 ] + [ [ [ -6, 8, 1, 2, -3, 2 ], [ -7, 8, 2, 2, -4, 2 ], [ -7, 8, 2, 2, -4, 3 ], [ -6, 8, 0, 2, -4, 2 ] ], 0.25 ], + [ [ [ -6, 8, 1, 2, -3, 2 ], [ -7, 8, 2, 2, -4, 2 ], [ -5, 8, 0, 2, -4, 1 ], [ -6, 8, 0, 2, -4, 2 ] ], 0.25 ] ], [ - [ [ [ -2, 2, 1, 0, -3, 1 ], [ -3, 2, 1, 1, -2, 2 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 1, -2, 1 ] ], 0.625 ], - [ [ [ -2, 2, 1, 0, -3, 1 ], [ -1, 2, 1, 1, -3, 0 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 1, -2, 1 ] ], 0.625 ], - [ [ [ -2, 2, 1, 0, -3, 1 ], [ -1, 1, 1, 1, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 1, -2, 1 ] ], 0.875 ], - [ [ [ -2, 2, 1, 0, -3, 1 ], [ -1, 2, 1, 1, -4, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 1, -2, 1 ] ], 0.75 ], - [ [ [ -2, 2, 1, 0, -3, 1 ], [ -1, 2, 1, 0, -2, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 1, -2, 1 ] ], 0.625 ], - [ [ [ -2, 2, 1, 0, -3, 1 ], [ -2, 2, 2, 1, -2, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 1, -2, 1 ] ], 1.125 ] + [ [ [ -6, 8, 1, 2, -3, 2 ], [ -7, 8, 2, 2, -4, 2 ], [ -5, 7, 0, 2, -4, 2 ], [ -6, 8, 0, 2, -4, 2 ] ], 0 ], + [ [ [ -6, 8, 2, 2, -4, 2 ], [ -7, 8, 2, 2, -4, 2 ], [ -5, 7, 0, 2, -4, 2 ], [ -6, 8, 0, 2, -4, 2 ] ], 0.25 ], + [ [ [ -6, 8, 2, 2, -4, 2 ], [ -7, 8, 2, 2, -4, 2 ], [ -6, 8, 1, 2, -4, 2 ], [ -6, 8, 0, 2, -4, 2 ] ], 0.25 ] ], [ - [ [ [ -2, 2, 1, 0, -3, 1 ], [ -2, 2, 2, 1, -2, 1 ], [ -1, 2, 0, 1, -2, 1 ], [ -2, 2, 1, 1, -2, 1 ] ], 0.125 ], - [ [ [ -2, 2, 1, 0, -3, 1 ], [ -1, 1, 1, 1, -2, 1 ], [ -1, 2, 0, 1, -2, 1 ], [ -2, 2, 1, 1, -2, 1 ] ], 4.25 ], - [ [ [ -2, 2, 1, 0, -3, 1 ], [ -1, 1, 1, 1, -2, 1 ], [ -2, 2, 1, 2, -2, 1 ], [ -2, 2, 1, 1, -2, 1 ] ], 4.125 ], - [ [ [ -2, 2, 1, 0, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ -2, 2, 1, 2, -2, 1 ], [ -2, 2, 1, 1, -2, 1 ] ], 0.375 ], - [ [ [ -2, 2, 1, 0, -3, 1 ], [ -1, 2, 1, 1, -3, 1 ], [ 0, 2, 1, 0, -3, 0 ], [ -2, 2, 1, 1, -2, 1 ] ], 0.75 ], - [ [ [ -2, 2, 1, 0, -3, 1 ], [ -1, 2, 0, 1, -2, 1 ], [ 0, 2, 1, 0, -3, 0 ], [ -2, 2, 1, 1, -2, 1 ] ], 0.875 ], - [ [ [ -2, 2, 1, 0, -3, 1 ], [ -2, 2, 1, 2, -2, 1 ], [ 0, 2, 1, 0, -3, 0 ], [ -2, 2, 1, 1, -2, 1 ] ], 5.375 ] + [ [ [ -6, 8, 2, 2, -4, 2 ], [ -7, 8, 2, 2, -4, 2 ], [ -6, 8, 1, 2, -4, 2 ], [ -6, 7, 2, 2, -4, 2 ] ], 0 ], + [ [ [ -6, 8, 2, 2, -4, 2 ], [ -7, 8, 2, 2, -4, 2 ], [ -7, 9, 2, 2, -4, 2 ], [ -6, 7, 2, 2, -4, 2 ] ], 0 ], + [ [ [ -6, 8, 2, 2, -4, 2 ], [ -6, 9, 2, 2, -4, 2 ], [ -7, 9, 2, 2, -4, 2 ], [ -6, 7, 2, 2, -4, 2 ] ], 0.25 ], + [ [ [ -6, 8, 2, 2, -4, 2 ], [ -6, 9, 2, 2, -4, 2 ], [ -7, 9, 2, 2, -4, 2 ], [ -7, 8, 2, 2, -4, 2 ] ], 0 ], + [ [ [ -6, 8, 2, 2, -4, 2 ], [ -5, 8, 1, 2, -4, 2 ], [ -7, 9, 2, 2, -4, 2 ], [ -7, 8, 2, 2, -4, 2 ] ], 0.25 ], + [ [ [ -6, 8, 2, 2, -4, 2 ], [ -6, 9, 2, 2, -4, 2 ], [ -7, 9, 2, 2, -4, 2 ], [ -7, 8, 2, 2, -4, 2 ] ], 0.25 ], + [ [ [ -6, 8, 2, 2, -4, 2 ], [ -6, 8, 2, 2, -4, 3 ], [ -7, 9, 2, 2, -4, 2 ], [ -7, 8, 2, 2, -4, 2 ] ], 0.25 ] ], [ - [ [ [ -2, 2, 1, 1, -3, 0 ], [ -2, 2, 1, 2, -2, 1 ], [ 0, 2, 1, 0, -3, 0 ], [ -2, 2, 1, 1, -2, 1 ] ], 0.5 ], - [ [ [ -3, 2, 1, 1, -2, 1 ], [ -2, 2, 1, 2, -2, 1 ], [ 0, 2, 1, 0, -3, 0 ], [ -2, 2, 1, 1, -2, 1 ] ], 0 ], - [ [ [ -4, 2, 2, 2, -2, 1 ], [ -2, 2, 1, 2, -2, 1 ], [ 0, 2, 1, 0, -3, 0 ], [ -2, 2, 1, 1, -2, 1 ] ], 4.875 ], - [ [ [ -2, 2, 1, 1, -2, 0 ], [ -2, 2, 1, 2, -2, 1 ], [ 0, 2, 1, 0, -3, 0 ], [ -2, 2, 1, 1, -2, 1 ] ], 3.875 ], - [ [ [ -2, 1, 1, 1, -2, 1 ], [ -2, 2, 1, 2, -2, 1 ], [ 0, 2, 1, 0, -3, 0 ], [ -2, 2, 1, 1, -2, 1 ] ], 0.5 ], - [ [ [ -1, 3, 1, 0, -3, 0 ], [ -2, 2, 1, 2, -2, 1 ], [ 0, 2, 1, 0, -3, 0 ], [ -2, 2, 1, 1, -2, 1 ] ], 1.625 ] + [ [ [ -6, 8, 2, 2, -4, 2 ], [ -6, 8, 2, 2, -4, 3 ], [ -7, 9, 2, 2, -4, 2 ], [ -7, 7, 2, 2, -4, 3 ] ], 0 ], + [ [ [ -6, 7, 2, 2, -4, 3 ], [ -6, 8, 2, 2, -4, 3 ], [ -7, 9, 2, 2, -4, 2 ], [ -7, 7, 2, 2, -4, 3 ] ], 0.25 ], + [ [ [ -6, 7, 2, 2, -4, 3 ], [ -6, 8, 2, 2, -4, 3 ], [ -7, 9, 2, 2, -4, 2 ], [ -8, 9, 2, 2, -4, 3 ] ], 0.25 ] ], [ - [ [ [ -1, 3, 1, 0, -3, 0 ], [ -2, 2, 1, 2, -2, 1 ], [ 0, 3, 1, 0, -4, 0 ], [ -2, 2, 1, 1, -2, 1 ] ], 0.625 ], - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ 0, 3, 1, 0, -4, 0 ], [ -2, 2, 1, 1, -2, 1 ] ], 2.125 ], - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ 0, 3, 1, 0, -4, 0 ], [ -1, 3, 1, 0, -2, 0 ] ], 0.25 ], - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ 0, 3, 1, 0, -4, 0 ], [ -1, 4, 1, 0, -3, 0 ] ], 0.75 ], - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ -1, 3, 1, 0, -3, 1 ], [ -1, 4, 1, 0, -3, 0 ] ], 0.75 ], - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ -1, 3, 1, 1, -3, 0 ], [ -1, 4, 1, 0, -3, 0 ] ], 0.625 ], - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ 0, 3, 1, 0, -3, 0 ], [ -1, 4, 1, 0, -3, 0 ] ], 3.875 ], - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 1, -1, -3, 0 ], [ -1, 4, 1, 0, -3, 0 ] ], 3.375 ] + [ [ [ -7, 9, 2, 2, -4, 3 ], [ -6, 8, 2, 2, -4, 3 ], [ -7, 9, 2, 2, -4, 2 ], [ -8, 9, 2, 2, -4, 3 ] ], 0 ], + [ [ [ -7, 9, 2, 2, -4, 3 ], [ -6, 8, 2, 2, -4, 3 ], [ -7, 8, 2, 2, -4, 3 ], [ -8, 9, 2, 2, -4, 3 ] ], 0.25 ], + [ [ [ -7, 9, 2, 2, -4, 3 ], [ -6, 8, 2, 2, -4, 3 ], [ -8, 9, 3, 2, -4, 3 ], [ -8, 9, 2, 2, -4, 3 ] ], 0.25 ] ], [ - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ -1, 3, 1, 1, -3, -1 ], [ -1, 4, 1, 0, -3, 0 ] ], 0.625 ], - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ -1, 3, 1, 1, -3, -1 ], [ -1, 3, 1, 0, -3, 1 ] ], 0.625 ], - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ -1, 3, 1, 1, -3, -1 ], [ 1, 3, 1, 0, -4, -1 ] ], 0.375 ], - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ -1, 3, 1, 1, -3, -1 ], [ 1, 3, 0, 0, -3, -1 ] ], 0.625 ], - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ -1, 3, 1, 1, -3, -1 ], [ 0, 3, 1, 1, -3, -1 ] ], 0.625 ], - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ -1, 3, 1, 1, -3, -1 ], [ -1, 4, 1, 0, -3, -1 ] ], 0.625 ], - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ 0, 3, 1, -1, -3, 0 ], [ -1, 4, 1, 0, -3, -1 ] ], 2.875 ] + [ [ [ -7, 9, 2, 2, -4, 3 ], [ -6, 8, 2, 2, -4, 3 ], [ -7, 8, 2, 2, -4, 3 ], [ -8, 9, 2, 2, -4, 3 ] ], 0 ], + [ [ [ -7, 9, 2, 2, -4, 3 ], [ -7, 9, 3, 2, -4, 3 ], [ -7, 8, 2, 2, -4, 3 ], [ -8, 9, 2, 2, -4, 3 ] ], 0.25 ], + [ [ [ -7, 9, 2, 2, -4, 3 ], [ -6, 8, 2, 2, -4, 3 ], [ -7, 8, 2, 2, -4, 3 ], [ -8, 9, 2, 2, -4, 3 ] ], 0 ], + [ [ [ -7, 9, 2, 2, -4, 3 ], [ -6, 8, 2, 2, -4, 3 ], [ -8, 10, 2, 2, -4, 3 ], [ -8, 9, 2, 2, -4, 3 ] ], 0.25 ], + [ [ [ -7, 9, 2, 2, -4, 3 ], [ -6, 9, 2, 2, -4, 2 ], [ -8, 10, 2, 2, -4, 3 ], [ -8, 9, 2, 2, -4, 3 ] ], 0.25 ] ], [ - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ 0, 3, 1, -1, -3, 0 ], [ 0, 3, 0, 0, -3, -1 ] ], 0.875 ], - [ [ [ -1, 3, 1, 0, -3, 0 ], [ 1, 3, 1, 0, -3, -1 ], [ 0, 3, 1, 0, -3, -1 ], [ 0, 3, 0, 0, -3, -1 ] ], 4.625 ], - [ [ [ -1, 3, 1, 1, -3, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 0, 3, 1, 0, -3, -1 ], [ 0, 3, 0, 0, -3, -1 ] ], 3.5 ], - [ [ [ -1, 3, 1, 1, -3, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 0, 3, 1, 0, -3, -1 ], [ -1, 3, 1, 0, -2, -1 ] ], 4.375 ], - [ [ [ -1, 3, 1, 1, -3, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 0, 3, 1, 0, -3, -1 ], [ 0, 3, 1, 0, -4, -1 ] ], 0.625 ], - [ [ [ -1, 3, 1, 1, -3, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 0, 3, 1, 0, -3, -1 ], [ -1, 3, 1, 0, -3, 0 ] ], 0.375 ], - [ [ [ -1, 3, 1, 1, -3, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 1, -1, -3, -1 ], [ -1, 3, 1, 0, -3, 0 ] ], 0 ], - [ [ [ -1, 3, 1, 1, -3, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 1, -1, -3, -1 ], [ 0, 3, 1, 0, -3, -1 ] ], 9.375 ] - ], - [ - [ [ [ 0, 3, 1, 0, -3, -2 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 1, -1, -3, -1 ], [ 0, 3, 1, 0, -3, -1 ] ], 0.75 ], - [ [ [ 0, 3, 1, 0, -3, -2 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 1, 0, -3, -2 ], [ 0, 3, 1, 0, -3, -1 ] ], 0.75 ], - [ [ [ 0, 3, 1, 0, -3, -2 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 2, 1, 0, -3, -1 ], [ 0, 3, 1, 0, -3, -1 ] ], 0.625 ], - [ [ [ 0, 3, 1, 0, -3, -2 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 1, 0, -4, -1 ], [ 0, 3, 1, 0, -3, -1 ] ], 0.375 ], - [ [ [ 0, 2, 1, 0, -3, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 1, 0, -4, -1 ], [ 0, 3, 1, 0, -3, -1 ] ], 0.5 ], - [ [ [ 0, 2, 1, 0, -3, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 0, 0, -3, -1 ], [ 0, 3, 1, 0, -3, -1 ] ], 0.25 ], - [ [ [ 0, 3, 1, 0, -4, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 0, 0, -3, -1 ], [ 0, 3, 1, 0, -3, -1 ] ], 3.125 ] - ], - [ - [ [ [ 0, 3, 1, 0, -4, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 0, 0, -3, -1 ], [ 0, 4, 1, 0, -4, -1 ] ], 0.375 ], - [ [ [ 0, 3, 1, 0, -4, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 0, 0, -3, -1 ], [ 0, 4, 0, 0, -3, -1 ] ], 0.25 ], - [ [ [ 0, 3, 1, 0, -4, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 0, 0, -3, -1 ], [ 0, 3, 1, 1, -4, -1 ] ], 0.75 ], - [ [ [ 0, 3, 1, 0, -4, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 0, 0, -3, -1 ], [ 0, 3, 0, 1, -3, -1 ] ], 3.875 ], - [ [ [ 0, 3, 1, 0, -4, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 0, 0, -3, -1 ], [ 0, 4, 1, 0, -3, -1 ] ], 0.625 ], - [ [ [ 0, 3, 1, 0, -4, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 0, 0, -3, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 1 ] - ], - [ - [ [ [ 0, 3, 1, 0, -4, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 2, -1, -4, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 0.5 ], - [ [ [ 1, 3, 1, -1, -4, -1 ], [ 1, 3, 1, 0, -3, -1 ], [ 1, 3, 2, -1, -4, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 1 ], - [ [ [ 1, 3, 1, -1, -4, -1 ], [ 1, 4, 1, -1, -4, -1 ], [ 1, 3, 2, -1, -4, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 0.5 ], - [ [ [ 1, 3, 1, -1, -4, -1 ], [ 1, 3, 1, -1, -4, 0 ], [ 1, 3, 2, -1, -4, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 3.375 ], - [ [ [ 1, 3, 1, -1, -4, -1 ], [ 1, 3, 1, 0, -4, -1 ], [ 1, 3, 2, -1, -4, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 0.625 ], - [ [ [ 1, 3, 1, -1, -4, -1 ], [ 2, 2, 1, -1, -4, -1 ], [ 1, 3, 2, -1, -4, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 3.125 ], - [ [ [ 1, 3, 1, -1, -4, -1 ], [ 2, 2, 1, -1, -4, -1 ], [ 1, 3, 1, -1, -3, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 1 ], - [ [ [ 2, 3, 1, -2, -4, -1 ], [ 2, 2, 1, -1, -4, -1 ], [ 1, 3, 1, -1, -3, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 0.75 ] - ], - [ - [ [ [ 2, 3, 1, -2, -4, -1 ], [ 2, 3, 1, -1, -5, -1 ], [ 1, 3, 1, -1, -3, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 0.5 ], - [ [ [ 1, 3, 2, -1, -4, -1 ], [ 2, 3, 1, -1, -5, -1 ], [ 1, 3, 1, -1, -3, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 4.25 ], - [ [ [ 1, 3, 2, -1, -4, -1 ], [ 2, 3, 1, -1, -5, -1 ], [ 1, 4, 1, -1, -4, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 3.375 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 2, 3, 1, -1, -5, -1 ], [ 1, 4, 1, -1, -4, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 0.5 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 2, 3, 0, -1, -4, -1 ], [ 1, 4, 1, -1, -4, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 4.375 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 2, 3, 0, -1, -4, -1 ], [ 1, 3, 1, -1, -4, 0 ], [ 2, 3, 1, -1, -4, -1 ] ], 0.75 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 2, 3, 0, -1, -4, -1 ], [ 1, 3, 1, 0, -4, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 0.5 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 0, 3, 1, -1, -3, -1 ], [ 1, 3, 1, 0, -4, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 1.5 ] - ], - [ - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 2, 2, 1, -2, -4, -1 ], [ 1, 3, 1, 0, -4, -1 ], [ 2, 3, 1, -1, -4, -1 ] ], 0.375 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 2, 2, 1, -2, -4, -1 ], [ 1, 3, 1, 0, -4, -1 ], [ 3, 2, 0, -1, -4, -1 ] ], 0.375 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 2, 2, 1, -2, -4, -1 ], [ 1, 3, 1, 0, -4, -1 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.625 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 2, 2, 1, -1, -4, -2 ], [ 1, 3, 1, 0, -4, -1 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.125 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 2, 2, 1, -1, -4, -2 ], [ 1, 3, 1, 0, -4, -1 ], [ 2, 3, 1, 0, -4, -2 ] ], 0.75 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 1, 2, 1, -1, -3, -1 ], [ 1, 3, 1, 0, -4, -1 ], [ 2, 3, 1, 0, -4, -2 ] ], 3.75 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 1, 3, 1, -1, -4, -1 ], [ 1, 3, 1, 0, -4, -1 ], [ 2, 3, 1, 0, -4, -2 ] ], 1.5 ] - ], - [ - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 1, 3, 1, -1, -4, -1 ], [ 2, 3, 1, -1, -4, -1 ], [ 2, 3, 1, 0, -4, -2 ] ], 3.5 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 1, 2, 1, -1, -4, 0 ], [ 2, 3, 1, -1, -4, -1 ], [ 2, 3, 1, 0, -4, -2 ] ], 0.875 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 1, 2, 1, -1, -4, 0 ], [ 2, 3, 1, -1, -4, -1 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.625 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 2, 3, 1, -1, -4, -1 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.125 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 2, 2, 1, -1, -4, 0 ], [ 2, 2, 1, 0, -4, -1 ] ], 4.25 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 2, 2, 0, -1, -4, -1 ], [ 2, 2, 1, -1, -4, 0 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.75 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 2, 1, 1, -1, -4, -1 ], [ 2, 2, 1, -1, -4, 0 ], [ 2, 2, 1, 0, -4, -1 ] ], 4.125 ], - [ [ [ 2, 2, 1, -1, -4, -1 ], [ 2, 1, 1, -1, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 2, 2, 1, 0, -4, -1 ] ], 2.75 ] - ], - [ - [ [ [ 1, 2, 2, 0, -4, -1 ], [ 2, 1, 1, -1, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.5 ], - [ [ [ 1, 2, 2, 0, -4, -1 ], [ 0, 2, 1, 1, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.375 ], - [ [ [ 1, 2, 2, 0, -4, -1 ], [ 0, 2, 1, 1, -4, -1 ], [ 2, 2, 1, -1, -4, -1 ], [ 2, 2, 1, 0, -4, -1 ] ], 4.25 ], - [ [ [ 2, 1, 1, 0, -4, -1 ], [ 0, 2, 1, 1, -4, -1 ], [ 2, 2, 1, -1, -4, -1 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.25 ], - [ [ [ 1, 3, 1, 0, -4, -1 ], [ 0, 2, 1, 1, -4, -1 ], [ 2, 2, 1, -1, -4, -1 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.375 ], - [ [ [ 1, 2, 1, 0, -4, 0 ], [ 0, 2, 1, 1, -4, -1 ], [ 2, 2, 1, -1, -4, -1 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.375 ], - [ [ [ 1, 2, 1, 0, -4, 0 ], [ 1, 2, 1, 0, -4, -1 ], [ 2, 2, 1, -1, -4, -1 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.5 ], - [ [ [ 1, 2, 1, 1, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 2, 2, 1, -1, -4, -1 ], [ 2, 2, 1, 0, -4, -1 ] ], 4.125 ] - ], - [ - [ [ [ 1, 2, 1, 1, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 2, 2, 1, 0, -4, -2 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.5 ], - [ [ [ 0, 2, 1, -1, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 2, 2, 1, 0, -4, -2 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.5 ], - [ [ [ 0, 2, 1, -1, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 2, 2, 1, 0, -4, -2 ], [ 2, 2, 0, 0, -4, -1 ] ], 0.625 ], - [ [ [ 0, 2, 1, -1, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 2, 1, 1, 0, -4, -1 ], [ 2, 2, 0, 0, -4, -1 ] ], 0.875 ], - [ [ [ 0, 2, 1, -1, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 1, 3, 1, 0, -4, -1 ], [ 2, 2, 0, 0, -4, -1 ] ], 0.625 ], - [ [ [ 0, 2, 1, -1, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 1, 3, 1, 0, -4, -1 ], [ 1, 2, 1, 1, -4, -1 ] ], 4.375 ], - [ [ [ -1, 2, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 1, 3, 1, 0, -4, -1 ], [ 1, 2, 1, 1, -4, -1 ] ], 0.625 ], - [ [ [ -1, 2, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ], [ 1, 2, 1, 1, -4, -1 ] ], 5.25 ] - ], - [ - [ [ [ -1, 2, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.625 ], - [ [ [ -1, 2, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 1, 2, 2, 0, -3, -1 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.75 ], - [ [ [ -1, 2, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 2, 2, 1, 0, -4, -1 ] ], 0.25 ], - [ [ [ -1, 2, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 2, 2, 1, 0, -4, -2 ] ], 0.5 ], - [ [ [ -1, 2, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -3, -1 ] ], 0.625 ], - [ [ [ -1, 2, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 3, 1, 0, -4, -1 ] ], 0.75 ], - [ [ [ -1, 2, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 3.75 ] - ], - [ - [ [ [ -1, 2, 2, 0, -4, -1 ], [ 1, 3, 2, -1, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.25 ], - [ [ [ -2, 2, 1, 0, -4, 1 ], [ 1, 3, 2, -1, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.875 ], - [ [ [ -2, 2, 1, 0, -4, 1 ], [ 0, 3, 3, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.625 ], - [ [ [ -2, 2, 1, 0, -4, 1 ], [ 0, 2, 1, 0, -4, 1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.75 ], - [ [ [ -2, 2, 1, 1, -4, 0 ], [ 0, 2, 1, 0, -4, 1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.625 ], - [ [ [ -1, 2, 1, 0, -4, 0 ], [ 0, 2, 1, 0, -4, 1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.625 ], - [ [ [ -1, 3, 2, 0, -4, -1 ], [ 0, 2, 1, 0, -4, 1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 1.375 ] - ], - [ - [ [ [ -1, 3, 2, 0, -4, -1 ], [ 1, 3, 1, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 4 ], - [ [ [ -1, 3, 2, 0, -4, -1 ], [ 0, 3, 2, 1, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.875 ], - [ [ [ -1, 3, 2, 0, -4, -1 ], [ 2, 2, 1, -1, -4, 0 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.625 ], - [ [ [ -1, 3, 2, 0, -4, -1 ], [ 2, 2, 1, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.625 ], - [ [ [ -1, 3, 2, 0, -4, -1 ], [ 0, 1, 1, 0, -4, 0 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 3.75 ], - [ [ [ -1, 3, 2, 0, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 1.5 ] - ], - [ - [ [ [ -1, 2, 2, 0, -4, 0 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.625 ], - [ [ [ 0, 1, 1, 0, -4, 0 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 4.625 ], - [ [ [ 0, 2, 2, 0, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.75 ], - [ [ [ -1, 4, 2, 0, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 3 ], - [ [ [ 0, 3, 1, 0, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.125 ], - [ [ [ -1, 3, 2, 1, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 1.25 ] - ], - [ - [ [ [ -1, 4, 3, 0, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 4.875 ], - [ [ [ 1, 2, 1, -1, -4, 0 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0 ], - [ [ [ 1, 2, 1, 0, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 4.25 ], - [ [ [ 1, 1, 1, 0, -4, 0 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.625 ], - [ [ [ 0, 3, 3, 0, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 4.5 ], - [ [ [ 0, 3, 2, 0, -3, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 3.125 ] - ], - [ - [ [ [ 0, 3, 4, 0, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 2, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.625 ], - [ [ [ 0, 3, 4, 0, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 0, 3, 3, 1, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 4 ], - [ [ [ 0, 3, 4, 0, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 2, 1, 0, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 3 ], - [ [ [ 0, 3, 4, 0, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 0, 2, 1, 0, -3, 0 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.5 ], - [ [ [ 1, 2, 3, 0, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 0, 2, 1, 0, -3, 0 ], [ 1, 2, 1, 0, -4, 0 ] ], 4.5 ], - [ [ [ 1, 2, 3, 0, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 2, 1, 0, -5, 0 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.25 ], - [ [ [ 1, 2, 3, 0, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 3.25 ] - ], - [ - [ [ [ 1, 3, 3, 0, -5, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.75 ], - [ [ [ 2, 3, 3, -1, -5, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.875 ], - [ [ [ 0, 3, 3, 1, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.5 ], - [ [ [ 0, 2, 3, 0, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 4 ], - [ [ [ 1, 2, 3, -1, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 0.5 ], - [ [ [ 0, 4, 3, -1, -4, -1 ], [ -1, 3, 3, 0, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 1.375 ] - ], - [ - [ [ [ 0, 4, 3, -1, -4, -1 ], [ 0, 3, 3, -1, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 3.875 ], - [ [ [ 0, 3, 3, -1, -4, 0 ], [ 0, 3, 3, -1, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 2, 1, 0, -4, 0 ] ], 3.5 ], - [ [ [ 0, 3, 3, -1, -4, 0 ], [ 0, 3, 3, -1, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 2, 2, 3, -1, -4, -1 ] ], 0.875 ], - [ [ [ 0, 3, 3, -1, -4, 0 ], [ 0, 3, 3, -1, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], 4.625 ], - [ [ [ 0, 3, 3, -1, -4, 0 ], [ 1, 3, 3, -2, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], 0.75 ], - [ [ [ 0, 3, 3, 0, -4, -1 ], [ 1, 3, 3, -2, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], 0.5 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 1, 3, 3, -2, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], 0.75 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 0, 3, 4, -1, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], 0.75 ] - ], - [ - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 0, 3, 4, -1, -4, -1 ], [ 0, 3, 4, 0, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], 0.125 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 0, 3, 4, -1, -4, -1 ], [ 0, 3, 4, 0, -4, -1 ], [ 1, 2, 4, -1, -4, -1 ] ], 0.5 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 0, 3, 4, -1, -4, -1 ], [ 0, 3, 4, 0, -4, -1 ], [ 0, 4, 4, -1, -4, -1 ] ], 0.625 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 0, 3, 4, -1, -4, -1 ], [ 1, 3, 4, -1, -4, -1 ], [ 0, 4, 4, -1, -4, -1 ] ], 0.5 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 0, 3, 4, -1, -4, -1 ], [ 1, 3, 4, -1, -4, -1 ], [ 0, 3, 4, -1, -4, 0 ] ], 1 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 0, 3, 4, -1, -4, -1 ], [ 1, 3, 4, -1, -4, -1 ], [ 0, 3, 4, 0, -4, -1 ] ], 0.5 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 0, 3, 4, -1, -4, -1 ], [ 1, 3, 4, -1, -4, -1 ], [ 2, 3, 3, -1, -4, -2 ] ], 4.375 ] - ], - [ - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 0, 3, 3, -1, -3, -1 ], [ 1, 3, 4, -1, -4, -1 ], [ 2, 3, 3, -1, -4, -2 ] ], 0.625 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 0, 4, 3, -1, -4, -1 ], [ 1, 3, 4, -1, -4, -1 ], [ 2, 3, 3, -1, -4, -2 ] ], 4.25 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 0, 3, 3, -1, -4, 0 ], [ 1, 3, 4, -1, -4, -1 ], [ 2, 3, 3, -1, -4, -2 ] ], 0.75 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 1, 4, 3, -1, -4, -2 ], [ 1, 3, 4, -1, -4, -1 ], [ 2, 3, 3, -1, -4, -2 ] ], 0.5 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 3, 4, -1, -4, -1 ], [ 2, 3, 3, -1, -4, -2 ] ], 0.5 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 1, 3, 4, -1, -4, -2 ], [ 1, 3, 4, -1, -4, -1 ], [ 2, 3, 3, -1, -4, -2 ] ], 6.375 ] - ], - [ - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 1, 3, 4, -1, -4, -2 ], [ 1, 3, 4, -1, -4, -1 ], [ 2, 2, 3, -1, -4, -1 ] ], 0.625 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 0, 3, 4, -1, -3, -1 ], [ 1, 3, 4, -1, -4, -1 ], [ 2, 2, 3, -1, -4, -1 ] ], 0.875 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 0, 4, 4, -1, -4, -1 ], [ 1, 3, 4, -1, -4, -1 ], [ 2, 2, 3, -1, -4, -1 ] ], 0.625 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 0, 3, 4, -1, -4, 0 ], [ 1, 3, 4, -1, -4, -1 ], [ 2, 2, 3, -1, -4, -1 ] ], 0.875 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 2, 3, 3, -2, -4, -1 ], [ 1, 3, 4, -1, -4, -1 ], [ 2, 2, 3, -1, -4, -1 ] ], 0.75 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 2, 3, 3, -2, -4, -1 ], [ 1, 3, 4, -1, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], 0.375 ], - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 2, 3, 3, -1, -4, -2 ], [ 1, 3, 4, -1, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], 3.875 ] - ], - [ - [ [ [ -1, 3, 3, -1, -4, -1 ], [ 2, 3, 3, -1, -4, -2 ], [ 0, 4, 3, 0, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], 0.5 ], - [ [ [ -2, 5, 3, -1, -4, -1 ], [ 2, 3, 3, -1, -4, -2 ], [ 0, 4, 3, 0, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], 0.625 ], - [ [ [ -2, 5, 3, -1, -4, -1 ], [ 2, 3, 3, -1, -4, -2 ], [ -1, 4, 3, 0, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], 0.375 ], - [ [ [ -2, 5, 3, -1, -4, -1 ], [ 2, 3, 3, -1, -4, -2 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], 0.375 ], - [ [ [ -2, 4, 3, -1, -4, 0 ], [ 2, 3, 3, -1, -4, -2 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], 0.75 ], - [ [ [ -2, 4, 3, -1, -4, 0 ], [ 2, 3, 3, -1, -4, -2 ], [ 1, 3, 3, 0, -4, -2 ], [ 1, 4, 3, -1, -4, -1 ] ], 0.375 ], - [ [ [ -2, 4, 3, -1, -4, 0 ], [ 2, 3, 3, -1, -4, -2 ], [ 1, 4, 2, -1, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], 2.375 ] + [ [ [ -7, 9, 2, 2, -4, 3 ], [ -8, 11, 2, 2, -4, 3 ], [ -8, 10, 2, 2, -4, 3 ], [ -8, 9, 2, 2, -4, 3 ] ], 0.25 ], + [ [ [ -8, 10, 3, 2, -4, 3 ], [ -8, 11, 2, 2, -4, 3 ], [ -8, 10, 2, 2, -4, 3 ], [ -8, 9, 2, 2, -4, 3 ] ], 0 ], + [ [ [ -8, 10, 3, 2, -4, 3 ], [ -8, 8, 2, 2, -4, 3 ], [ -8, 10, 2, 2, -4, 3 ], [ -8, 9, 2, 2, -4, 3 ] ], 0.25 ] ] ] ], "last_changes": [ - [ [ -2, 5, 3, -1, -4, -1 ], [ 2, 3, 3, -1, -4, -2 ], [ -1, 4, 3, 0, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], - [ [ -2, 5, 3, -1, -4, -1 ], [ 2, 3, 3, -1, -4, -2 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], - [ [ -2, 4, 3, -1, -4, 0 ], [ 2, 3, 3, -1, -4, -2 ], [ 1, 3, 3, -1, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ], - [ [ -2, 4, 3, -1, -4, 0 ], [ 2, 3, 3, -1, -4, -2 ], [ 1, 3, 3, 0, -4, -2 ], [ 1, 4, 3, -1, -4, -1 ] ], - [ [ -2, 4, 3, -1, -4, 0 ], [ 2, 3, 3, -1, -4, -2 ], [ 1, 4, 2, -1, -4, -1 ], [ 1, 4, 3, -1, -4, -1 ] ] + [ [ -7, 9, 2, 2, -4, 3 ], [ -6, 8, 2, 2, -4, 3 ], [ -8, 10, 2, 2, -4, 3 ], [ -8, 9, 2, 2, -4, 3 ] ], + [ [ -7, 9, 2, 2, -4, 3 ], [ -6, 9, 2, 2, -4, 2 ], [ -8, 10, 2, 2, -4, 3 ], [ -8, 9, 2, 2, -4, 3 ] ], + [ [ -7, 9, 2, 2, -4, 3 ], [ -8, 11, 2, 2, -4, 3 ], [ -8, 10, 2, 2, -4, 3 ], [ -8, 9, 2, 2, -4, 3 ] ], + [ [ -8, 10, 3, 2, -4, 3 ], [ -8, 11, 2, 2, -4, 3 ], [ -8, 10, 2, 2, -4, 3 ], [ -8, 9, 2, 2, -4, 3 ] ], + [ [ -8, 10, 3, 2, -4, 3 ], [ -8, 8, 2, 2, -4, 3 ], [ -8, 10, 2, 2, -4, 3 ], [ -8, 9, 2, 2, -4, 3 ] ] ], "cur_uid": "tmp", -"ref_uid": "nil", -"order_seed": 668999, -"dur_seed": 772296, -"motifs_seed": 584044, -"entrances_probs_vals": [ 0, 0, 5.3174603174603, 0, 5, 0, 0, 0, 0.013513513513513, 0.12745098039216, 0.59459459459459, 0.2156862745098, 0, 0.29738562091503, 0.0033783783783784, 0.55555555555556, 0, 0.8202614379085, 0.074324324324325, 1, 0 ], -"passages_probs_vals": [ 0, 0, 5.3174603174603, 0, 5, 0, 0, 0, 0.013513513513513, 0.12745098039216, 0.59459459459459, 0.2156862745098, 0, 0.29738562091503, 0.0033783783783784, 0.55555555555556, 0, 0.8202614379085, 0.074324324324325, 1, 0 ], -"exits_probs_vals": [ 0, 0, 5.3174603174603, 0, 5, 0, 0, 0, 0.013513513513513, 0.12745098039216, 0.59459459459459, 0.2156862745098, 0, 0.29738562091503, 0.0033783783783784, 0.55555555555556, 0, 0.8202614379085, 0.074324324324325, 1, 0 ], -"ranges": [ [ -2400, 1200 ], [ -1200, 1200 ], [ -702, 1200 ], [ -702, 1200 ] ], -"step_probs_vals": [ -1200, 1200, 0, 0, 0.037037037037037, 0, 0.18518518518519, 0, 0.40740740740741, 0, 0.44444444444444, 0, 0.48765432098765, 0, 0.53086419753086, 0, 0.53292181069959, 0, 0.55555555555556, 0.91477272727273, 0.60905349794239, 0, 0.61111111111111, 0, 0.7798353909465, 0, 1, 0 ], -"passages_weights": [ 1, 0.47, 0.43, 1, 0.84 ], -"hd_exp": 2.17, +"ref_uid": "624f7439", +"order_seed": 297821, +"dur_seed": 692519, +"motifs_seed": 730459, +"entrances_probs_vals": [ 0.78, 0, 0, 0, 1.02, 0.0098039215686275, 0, 0.20915032679739, 0, 0.24183006535948, 0.82432432432432, 0.28758169934641, 0, 1, 0 ], +"passages_probs_vals": [ 0.78, 0, 0, 0, 1.02, 0.0098039215686275, 0, 0.20915032679739, 0, 0.24183006535948, 0.82432432432432, 0.28758169934641, 0, 1, 0 ], +"exits_probs_vals": [ 0.78, 0, 0, 0, 1.02, 0.0098039215686275, 0, 0.20915032679739, 0, 0.24183006535948, 0.82432432432432, 0.28758169934641, 0, 1, 0 ], +"ranges": [ [ -2400, 1200 ], [ -1200, 1453 ], [ -702, 1694 ], [ -702, 1973 ] ], +"step_probs_vals": [ -1200, 1200, 0, 0, 0.41358024691358, 0.0056818181818177, 0.46913580246914, 0.67045454545455, 0.52057613168724, 0, 0.56378600823045, 0.85795454545455, 0.60082304526749, 0, 1, 0 ], +"passages_weights": [ 0.38, 0.15, 0.43, 1, 1 ], +"hd_exp": 10, "hd_invert": 0, "order": [ - [ [ 2 ], [ 3, 1, 0, 1, 3, 3, 0, 3 ], [ ] ], - [ [ 2 ], [ 1, 0, 3, 3, 1, 3, 3, 3 ], [ ] ], - [ [ 3 ], [ 1, 2, 0, 1, 1, 2, 1, 2 ], [ ] ], - [ [ 2, 3, 0 ], [ 1, 1, 1, 1, 1, 1 ], [ ] ], - [ [ 3 ], [ 2, 0, 1, 0, 2, 2, 0, 2 ], [ ] ], - [ [ 2 ], [ 0, 3, 1, 1, 0, 0, 1, 1 ], [ ] ], - [ [ 0, 2, 3 ], [ 1, 1, 1, 1, 1, 1 ], [ ] ], - [ [ 0 ], [ 2, 3, 1, 3, 2, 2, 2, 1 ], [ ] ], - [ [ 0, 1, 3 ], [ 2, 2, 2, 2, 2, 2 ], [ ] ], - [ [ 2 ], [ 1, 0, 3, 0, 3, 1, 1, 0 ], [ ] ], - [ [ 0 ], [ 1, 2, 3, 3, 3, 3, 1, 3 ], [ ] ], - [ [ 1 ], [ 0, 3, 2, 2, 0, 3, 3, 0 ], [ ] ], - [ [ 3, 2 ], [ 0, 1, 0, 0, 1, 1, 1 ], [ ] ], - [ [ 2, 1 ], [ 0, 3, 3, 3, 3, 3, 3 ], [ ] ], - [ [ 0 ], [ 2, 3, 1, 3, 3, 1, 1, 2 ], [ ] ], - [ [ 1, 3 ], [ 0, 2, 2, 0, 0, 2, 2 ], [ ] ], - [ [ 1, 3, 2 ], [ 0, 0, 0, 0, 0, 0 ], [ ] ], - [ [ 0, 1, 2 ], [ 3, 3, 3, 3, 3, 3 ], [ ] ], - [ [ 2, 0 ], [ 3, 1, 3, 1, 3, 1, 3 ], [ ] ], - [ [ 2, 3, 0 ], [ 1, 1, 1, 1, 1, 1 ], [ ] ], - [ [ 2, 3 ], [ 0, 1, 0, 1, 0, 1, 0 ], [ ] ], - [ [ 2 ], [ 1, 3, 0, 0, 1, 3, 1, 0 ], [ ] ], - [ [ 3, 2, 0 ], [ 1, 1, 1, 1, 1, 1 ], [ ] ], - [ [ 3, 0 ], [ 2, 1, 2, 1, 2, 1, 1 ], [ ] ], - [ [ 2, 3, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ ] ], - [ [ 0 ], [ 2, 1, 3, 3, 2, 2, 2, 2 ], [ ] ], - [ [ 0, 1 ], [ 2, 3, 3, 3, 3, 3, 2 ], [ ] ], - [ [ 1 ], [ 3, 2, 0, 3, 3, 3, 2, 3 ], [ ] ], - [ [ 1, 3 ], [ 0, 2, 2, 2, 0, 2, 0 ], [ ] ], - [ [ 1, 0, 2 ], [ 3, 3, 3, 3, 3, 3 ], [ ] ], - [ [ 3 ], [ 2, 0, 1, 1, 1, 1, 2, 0 ], [ ] ], - [ [ 3 ], [ 1, 0, 2, 0, 1, 2, 2, 1 ], [ ] ], - [ [ 2, 0 ], [ 1, 3, 3, 1, 3, 1, 1 ], [ ] ], - [ [ 0 ], [ 2, 1, 3, 1, 2, 1, 1, 2 ], [ ] ], - [ [ 3 ], [ 0, 1, 2, 0, 0, 0, 1, 0 ], [ ] ], - [ [ 1 ], [ 2, 0, 3, 2, 2, 3, 0, 2 ], [ ] ], - [ [ 1, 0 ], [ 3, 2, 2, 3, 3, 3, 3 ], [ ] ], - [ [ 2, 3 ], [ 1, 0, 1, 1, 0, 0, 0 ], [ ] ], - [ [ 0, 2, 3 ], [ 1, 1, 1, 1, 1, 1 ], [ ] ], - [ [ 2, 1, 3 ], [ 0, 0, 0, 0, 0, 0 ], [ ] ], - [ [ 2, 1, 3 ], [ 0, 0, 0, 0, 0, 0 ], [ ] ], - [ [ 3, 1 ], [ 0, 2, 2, 2, 0, 2, 2 ], [ ] ], - [ [ 2, 3, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ ] ], - [ [ 2 ], [ 1, 0, 3, 3, 1, 0, 0, 1 ], [ ] ], - [ [ 0, 1 ], [ 2, 3, 3, 2, 3, 3, 3 ], [ ] ], - [ [ 0, 2, 3 ], [ 1, 1, 1, 1, 1, 1 ], [ ] ], - [ [ 2, 0 ], [ 3, 1, 1, 1, 1, 3, 1 ], [ ] ], - [ [ 1, 3 ], [ 2, 0, 2, 2, 0, 2, 2 ], [ ] ] + [ [ 0, 1 ], [ 2, 3, 3 ], [ ] ], + [ [ 1, 2 ], [ 0, 3, 0, 3, 0, 0 ], [ ] ], + [ [ 3, 0, 2 ], [ 1 ], [ ] ], + [ [ 0, 2 ], [ 3, 1, 3, 3 ], [ ] ], + [ [ 2 ], [ 3, 1, 0 ], [ ] ], + [ [ 2 ], [ 3, 1, 0, 1, 0, 3, 1 ], [ ] ], + [ [ 3, 2 ], [ 1, 0 ], [ ] ], + [ [ 2, 1 ], [ 3, 0, 0, 0, 3, 0 ], [ ] ], + [ [ 3, 2 ], [ 1, 0, 1, 0 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 0, 1 ], [ 3, 2, 2, 2, 3 ], [ ] ], + [ [ 1, 0 ], [ 3, 2, 2 ], [ ] ], + [ [ 2 ], [ 0, 3, 1 ], [ ] ], + [ [ 1, 0 ], [ 2, 3 ], [ ] ], + [ [ 1, 0, 3 ], [ 2, 2, 2 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 3, 3, 3 ], [ ] ], + [ [ 3 ], [ 1, 2, 0, 1, 1 ], [ ] ], + [ [ 2, 1 ], [ 0, 3, 0 ], [ ] ], + [ [ 3 ], [ 2, 1, 0 ], [ ] ], + [ [ 0, 3, 1 ], [ 2, 2, 2, 2, 2 ], [ ] ], + [ [ 2, 0 ], [ 3, 1, 3 ], [ ] ], + [ [ 0, 3, 1 ], [ 2, 2 ], [ ] ], + [ [ 3, 1 ], [ 2, 0, 2 ], [ ] ], + [ [ 0 ], [ 3, 2, 1, 3, 1, 1, 1 ], [ ] ], + [ [ 2, 1 ], [ 3, 0, 3 ], [ ] ], + [ [ 3, 1 ], [ 0, 2, 2 ], [ ] ], + [ [ 3, 0 ], [ 2, 1, 1, 2, 1 ], [ ] ], + [ [ 2, 3 ], [ 1, 0, 1 ], [ ] ] ], -"sus_weights": [ 0.35, 0.37, 0.38 ], -"order_size": [ 48, 48.479591836735 ], -"passages_size": [ 5, 5 ], +"sus_weights": [ 0.37, 0.61, 0.22535211267606 ], +"order_size": [ 28.275510204082, 28.275510204082 ], +"passages_size": [ 0, 5 ], "motif_edited": "false", "order_edited": "false" } \ No newline at end of file diff --git a/supercollider/material_tweak.scd b/supercollider/material_tweak.scd index dba0f4c..b4cf4ed 100644 --- a/supercollider/material_tweak.scd +++ b/supercollider/material_tweak.scd @@ -30,12 +30,12 @@ stringifyToDepth = {arg data, maxDepth = 1; }) }; -transpose = {arg data, trans; +transpose = {arg data, trans, tList; var res; res = data.collect({arg x; x.collect({arg y; y.collect({arg z; - [z[0].collect({arg item; if(item == ["Rest"], {item}, {item + trans })}), z[1]]})})}); + [z[0].collect({arg item, itemIndex; if((item == ["Rest"]) || tList.includes(itemIndex).not, {item}, {item + trans })}), z[1]]})})}); }; swap = {arg data, swaplist; @@ -55,33 +55,43 @@ swap = {arg data, swaplist; }; c = [ + [ [ - [ - [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.875 ], - [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], - [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], - [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ] ], 4.875 ] - ], - [ - [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], - [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, 0 ] ], 0 ], - [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 1, 0, 0, 0 ] ], 4.75 ] - ], - [ - [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 0 ], - [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], - [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 4.125 ], - [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], - [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ] ], 0 ], - [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], - [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 9.625 ] - ] + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ "Rest" ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 2, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 7 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ], [ -1, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -1, -1, 1, 0 ], [ -2, 4, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ -1, 3, -1, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 5.5 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 0, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 2, -2, -1, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 4 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -1, 2, -2, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -1, 3, -3, -1, 1, 0 ], [ 0, 3, -2, -2, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ 0, 3, -2, -2, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 5.625 ] + ], + [ + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 1, 0 ], [ -2, 3, -1, -1, 1, 0 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, -1, 1, 1 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ -1, 3, -2, -1, 1, 0 ], [ -1, 3, -2, -1, 1, -1 ] ], 6.5 ], + [ [ [ -2, 3, -2, -1, 1, 0 ], [ -2, 3, -2, 0, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ "Rest" ], [ -2, 3, -2, 0, 1, 0 ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ -1, 3, -2, -1, 1, -1 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 6.375 ] ] + ] ]; //c = c.collect({arg x; x.collect({arg y; y.collect({arg z; [z[0].collect({arg item; if(item == ["Rest"], {item}, {item + [ 1, -1, 0, 0, -1, 0 ] })}), z[1]]})})}); -c = transpose.value(c, [ 0, 2, -1, 0, 0, 0 ]); -//c = swap.value(c, [[2, 3]]); +c = transpose.value(c, [ 1, 0, 0, 0, 0, 0 ], [1, 2, 3]); +//c = swap.value(c, [[1, 3]]); f = File("tweak.txt", "w"); diff --git a/supercollider/seeds_and_ledgers_backend.scd b/supercollider/seeds_and_ledgers_backend.scd index 57e638d..c5b0896 100644 --- a/supercollider/seeds_and_ledgers_backend.scd +++ b/supercollider/seeds_and_ledgers_backend.scd @@ -385,7 +385,7 @@ genPatterns = {arg inSeq, addr, oneShot = false; 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)})}); + freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(62.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)}); diff --git a/supercollider/seeds_and_ledgers_backend_rise.scd b/supercollider/seeds_and_ledgers_backend_rise.scd index 070e09d..e1a9d92 100644 --- a/supercollider/seeds_and_ledgers_backend_rise.scd +++ b/supercollider/seeds_and_ledgers_backend_rise.scd @@ -432,7 +432,7 @@ genPatterns = {arg inSeq, addr, oneShot = false; 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)})}); + freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(62.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)}); diff --git a/supercollider/seeds_and_ledgers_main.scd b/supercollider/seeds_and_ledgers_main.scd index a16ad4c..d3f7a4c 100644 --- a/supercollider/seeds_and_ledgers_main.scd +++ b/supercollider/seeds_and_ledgers_main.scd @@ -12,8 +12,8 @@ s.waitForBoot({ c = Condition.new; // load all files - //"seeds_and_ledgers_backend.scd".loadRelative; - "seeds_and_ledgers_backend_rise.scd".loadRelative; + "seeds_and_ledgers_backend.scd".loadRelative; + //"seeds_and_ledgers_backend_rise.scd".loadRelative; "seeds_and_ledgers_transcriber.scd".loadRelative; "seeds_and_ledgers_synthdefs.scd".loadRelative; s.sync(c);