commit f67943c01002ad0d625224db14d1d5b12249cb35 Author: mwinter Date: Sun Apr 9 17:20:10 2023 +0200 initial commit of seeds and ledgers development code diff --git a/lilypond/includes/part_I.ly b/lilypond/includes/part_I.ly new file mode 100644 index 0000000..047248e --- /dev/null +++ b/lilypond/includes/part_I.ly @@ -0,0 +1,481 @@ +\new StaffGroup \with {\remove "System_start_delimiter_engraver"} +<< +\new Staff = "I" \with { +instrumentName = "I" +shortInstrumentName = "I" +midiInstrument = #"clarinet" + +} +<< + +{ +\set Score.markFormatter = #format-mark-box-numbers \tempo 2 = 60 + \numericTimeSignature \time 2/2 + \clef treble + +<< + { r1 } +>> + \bar "|" +<< + { r2 r16[ e'8.^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "5/4" }}] ~ e'4 ~ } +>> + \bar "|" +<< + { e'1 ~ } +>> + \bar "|" +<< + { e'1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { e'1 ~ } +>> + \bar "|" +<< + { e'1 ~ } +>> + \bar "|" +<< + { e'4 ~ e'16[ r8.] r2 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \break \noPageBreak +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r2. d'4^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "16/11" }} ~ } +>> + \bar "|" \pageBreak +<< + { d'1 ~ } +>> + \bar "|" +<< + { d'2 dis'4^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "8/5" }} ~ dis'4 ~ } +>> + \bar "|" +<< + { dis'4 ~ dis'8[ f'8^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "7/4" }}] ~ f'2 ~ } +>> + \bar "|" +<< + { f'1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { f'1 ~ } +>> + \bar "|" +<< + { f'2 ~ f'16[ e'8.^\markup { \pad-markup #0.2 "+13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "11/8" }}] ~ e'4 ~ } +>> + \bar "|" +<< + { e'1 ~ } +>> + \bar "|" +<< + { e'1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { e'4 ~ e'8.[ e'16^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "4/3" }}] ~ e'2 ~ } +>> + \bar "|" +<< + { e'8.[ fis'16^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "2/1" }}] ~ fis'2. ~ } +>> + \bar "|" +<< + { fis'1 ~ } +>> + \bar "|" +<< + { fis'1 ~ } +>> + \bar "|" \pageBreak +<< + { fis'2. ~ fis'8.[ r16] } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r4 r16[ gis'8.^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "3/4" }}] ~ gis'2 ~ } +>> + \bar "|" +<< + { gis'1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { gis'1 ~ } +>> + \bar "|" +<< + { gis'1 ~ } +>> + \bar "|" +<< + { gis'4 fis'4^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "2/3" }} ~ fis'2 ~ } +>> + \bar "|" +<< + { fis'1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { fis'1 ~ } +>> + \bar "|" +<< + { fis'2. ~ fis'8.[ r16] } +>> + \bar "|" +<< + { r2. r8[ gis'8^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "3/4" }}] ~ } +>> + \bar "|" +<< + { gis'1 ~ } +>> + \bar "|" \pageBreak +<< + { gis'1 ~ } +>> + \bar "|" +<< + { gis'1 ~ } +>> + \bar "|" +<< + { gis'4 ~ gis'16[ a'8.^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "13/16" }}] ~ a'2 ~ } +>> + \bar "|" +<< + { a'2 ~ a'8[ r8] r4 } +>> + \bar "|" \break \noPageBreak +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r8.[ ais'16^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "2/1" }}] ~ ais'2. ~ } +>> + \bar "|" \break \noPageBreak +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" \pageBreak +<< + { ais'2. r4 } +>> + \bar "|" +<< + { r8.[ ais'16^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "100/100" }}] ~ ais'2. ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" \pageBreak +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'8.[ r16] r2. } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \break \noPageBreak +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \break \noPageBreak +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \pageBreak +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \break \noPageBreak +<< + { r1 } +>> + \bar "|" +<< + { r2 ais'4^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "11/4" }} ~ ais'4 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" \pageBreak +<< + { ais'16[ r8.] r2. } +>> + \bar "|" +<< + { r2 r8[ ais'8^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "100/100" }}] ~ ais'4 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'2. ~ ais'8[ r8] } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \break \noPageBreak +<< + { r1 } +>> + \bar "|" +<< + { r4 ais'4^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "13/4" }} ~ ais'2 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" \pageBreak +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'16[ r8.] r2. } +>> + \bar "|" \break \noPageBreak +<< + { r1 } +>> + \bar "|" +<< + { r8.[ a'16^\markup { \pad-markup #0.2 "-22"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "32/13" }}] ~ a'2 ~ a'8.[ g'16^\markup { \pad-markup #0.2 "+49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "16/7" }}] ~ } +>> + \bar "|" +<< + { g'1 ~ } +>> + \bar "|" +<< + { g'1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { g'4 ais'4^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "8/3" }} ~ ais'2 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" \pageBreak +<< + { ais'8[ r8] r8[ ais'8^\markup { \pad-markup #0.2 "+16"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "100/100" }}] ~ ais'2 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { ais'1 ~ } +>> + \bar "|" +<< + { ais'2 ~ ais'16[ r8.] r4 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 \fermata }>> \bar "|." +} + +>> +>> \ No newline at end of file diff --git a/lilypond/includes/part_II.ly b/lilypond/includes/part_II.ly new file mode 100644 index 0000000..8234a07 --- /dev/null +++ b/lilypond/includes/part_II.ly @@ -0,0 +1,481 @@ +\new StaffGroup \with {\remove "System_start_delimiter_engraver"} +<< +\new Staff = "II" \with { +instrumentName = "II" +shortInstrumentName = "II" +midiInstrument = #"clarinet" + +} +<< + +{ +\set Score.markFormatter = #format-mark-box-numbers \tempo 2 = 60 + \numericTimeSignature \time 2/2 + \clef treble + +<< + { r1 } +>> + \bar "|" +<< + { r8[ fis'8^\markup { \pad-markup #0.2 "-49"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "11/8" }}] ~ fis'2. ~ } +>> + \bar "|" +<< + { fis'2 ~ fis'8[ e'8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "16/13" }}] ~ e'4 ~ } +>> + \bar "|" +<< + { e'2 f'4^\markup { \pad-markup #0.2 "-2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "4/3" }} ~ f'4 ~ } +>> + \bar "|" \break \noPageBreak +<< + { f'1 ~ } +>> + \bar "|" +<< + { f'4 g'4^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "2/1" }} ~ g'2 ~ } +>> + \bar "|" +<< + { g'1 ~ } +>> + \bar "|" +<< + { g'2. r4 } +>> + \bar "|" \break \noPageBreak +<< + { r4 r8[ f'8^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "7/4" }}] ~ f'2 ~ } +>> + \bar "|" +<< + { f'1 ~ } +>> + \bar "|" +<< + { f'8.[ g'16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "2/1" }}] ~ g'2. } +>> + \bar "|" +<< + { a'4^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "16/7" }} ~ a'2. ~ } +>> + \bar "|" \pageBreak +<< + { a'2 ~ a'8.[ r16] r4 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \break \noPageBreak +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r4 r8.[ b'16^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "2/1" }}] ~ b'2 ~ } +>> + \bar "|" +<< + { b'1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { b'1 ~ } +>> + \bar "|" +<< + { b'1 } +>> + \bar "|" +<< + { d''4^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "32/13" }} ~ d''2. ~ } +>> + \bar "|" +<< + { d''4 ~ d''16[ cis''8.^\markup { \pad-markup #0.2 "-7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "16/7" }}] ~ cis''2 ~ } +>> + \bar "|" \pageBreak +<< + { cis''1 ~ } +>> + \bar "|" +<< + { cis''4 ~ cis''8[ r8] r2 } +>> + \bar "|" +<< + { cis''4^\markup { \pad-markup #0.2 "-7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "100/100" }} ~ cis''2. ~ } +>> + \bar "|" +<< + { cis''1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { cis''1 ~ } +>> + \bar "|" +<< + { cis''1 ~ } +>> + \bar "|" +<< + { cis''1 ~ } +>> + \bar "|" +<< + { cis''1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { cis''2. ~ cis''16[ r8.] } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r4 r16[ cis''8.^\markup { \pad-markup #0.2 "-7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "100/100" }}] ~ cis''2 ~ } +>> + \bar "|" +<< + { cis''1 ~ } +>> + \bar "|" \pageBreak +<< + { cis''1 ~ } +>> + \bar "|" +<< + { cis''1 ~ } +>> + \bar "|" +<< + { cis''1 ~ } +>> + \bar "|" +<< + { cis''1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { cis''1 ~ } +>> + \bar "|" +<< + { cis''1 ~ } +>> + \bar "|" +<< + { cis''2 ~ cis''8.[ d''16^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "5/2" }}] ~ d''4 ~ } +>> + \bar "|" +<< + { d''1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { d''2 dis''4^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "11/4" }} ~ dis''4 ~ } +>> + \bar "|" +<< + { dis''4 ~ dis''8[ fis''8^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "16/5" }}] ~ fis''2 ~ } +>> + \bar "|" +<< + { fis''4 f''4^\markup { \pad-markup #0.2 "-26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "3/1" }} ~ f''2 ~ } +>> + \bar "|" +<< + { f''1 ~ } +>> + \bar "|" \pageBreak +<< + { f''2. ~ f''8[ r8] } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r4 r16[ e''8.^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "16/11" }}] ~ e''2 } +>> + \bar "|" +<< + { dis''4^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "11/8" }} ~ dis''2. ~ } +>> + \bar "|" \break \noPageBreak +<< + { dis''1 ~ } +>> + \bar "|" +<< + { dis''8.[ fis''16^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "8/5" }}] ~ fis''2. ~ } +>> + \bar "|" +<< + { fis''1 ~ } +>> + \bar "|" +<< + { fis''1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { fis''1 ~ } +>> + \bar "|" +<< + { fis''1 ~ } +>> + \bar "|" +<< + { fis''1 ~ } +>> + \bar "|" +<< + { fis''1 ~ } +>> + \bar "|" \pageBreak +<< + { fis''1 ~ } +>> + \bar "|" +<< + { fis''2. gis''4^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "4/1" }} ~ } +>> + \bar "|" +<< + { gis''1 ~ } +>> + \bar "|" +<< + { gis''4 ~ gis''16[ a''8.^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "16/3" }}] ~ a''2 ~ } +>> + \bar "|" \break \noPageBreak +<< + { a''2. ~ a''16[ ais''8.^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "11/2" }}] ~ } +>> + \bar "|" +<< + { ais''1 ~ } +>> + \bar "|" +<< + { ais''1 ~ } +>> + \bar "|" +<< + { ais''8.[ gis''16^\markup { \pad-markup #0.2 "-19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "64/13" }}] ~ gis''2. ~ } +>> + \bar "|" \break \noPageBreak +<< + { gis''4 gis''4^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "5/1" }} ~ gis''2 ~ } +>> + \bar "|" +<< + { gis''4 r2. } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r4 r16[ g''8.^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "4/1" }}] ~ g''2 ~ } +>> + \bar "|" \pageBreak +<< + { g''2 ~ g''8.[ e''16^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "4/1" }}] ~ e''4 ~ } +>> + \bar "|" +<< + { e''2 ~ e''8[ d''8^\markup { \pad-markup #0.2 "-10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "7/2" }}] ~ d''4 ~ } +>> + \bar "|" +<< + { d''1 ~ } +>> + \bar "|" +<< + { d''1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { d''16[ r8.] r2. } +>> + \bar "|" +<< + { r2. r8[ d''8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "5/4" }}] ~ } +>> + \bar "|" +<< + { d''2 dis''4^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "11/8" }} ~ dis''4 ~ } +>> + \bar "|" +<< + { dis''2 ~ dis''8[ e''8^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "4/1" }}] ~ e''4 ~ } +>> + \bar "|" \break \noPageBreak +<< + { e''2. ~ e''8[ f''8^\markup { \pad-markup #0.2 "-26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "3/2" }}] ~ } +>> + \bar "|" +<< + { f''1 ~ } +>> + \bar "|" +<< + { f''4 fis''4^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "8/5" }} ~ fis''2 ~ } +>> + \bar "|" +<< + { fis''8[ g''8^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "32/7" }}] ~ g''2. ~ } +>> + \bar "|" \pageBreak +<< + { g''2 ~ g''16[ r8.] r4 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r8.[ g''16^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "4/1" }}] ~ g''2. ~ } +>> + \bar "|" +<< + { g''2 ~ g''8[ fis''8^\markup { \pad-markup #0.2 "-14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "8/5" }}] ~ fis''4 ~ } +>> + \bar "|" \break \noPageBreak +<< + { fis''2 ~ fis''8[ dis''8^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "11/8" }}] ~ dis''4 ~ } +>> + \bar "|" +<< + { dis''4 ~ dis''8.[ e''16^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "32/7" }}] ~ e''2 ~ } +>> + \bar "|" +<< + { e''2. ~ e''8[ cis''8^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "4/1" }}] ~ } +>> + \bar "|" +<< + { cis''1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { cis''2 b'4^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "7/2" }} ~ b'4 ~ } +>> + \bar "|" +<< + { b'1 ~ } +>> + \bar "|" +<< + { b'1 ~ } +>> + \bar "|" +<< + { b'1 ~ } +>> + \bar "|" \pageBreak +<< + { b'1 ~ } +>> + \bar "|" +<< + { b'1 ~ } +>> + \bar "|" +<< + { b'1 ~ } +>> + \bar "|" +<< + { b'4 ~ b'8.[ r16] r2 } +>> + \bar "|" \break \noPageBreak +<< + { r2 r16[ cis''8.^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "16/5" }}] ~ cis''4 ~ } +>> + \bar "|" +<< + { cis''1 ~ } +>> + \bar "|" +<< + { cis''2 ~ cis''8.[ dis''16^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "7/2" }}] ~ dis''4 ~ } +>> + \bar "|" +<< + { dis''1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { dis''2 ~ dis''16[ r8.] r4 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \pageBreak +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \break \noPageBreak +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 \fermata }>> \bar "|." +} + +>> +>> \ No newline at end of file diff --git a/lilypond/includes/part_III.ly b/lilypond/includes/part_III.ly new file mode 100644 index 0000000..abf62f9 --- /dev/null +++ b/lilypond/includes/part_III.ly @@ -0,0 +1,481 @@ +\new StaffGroup \with {\remove "System_start_delimiter_engraver"} +<< +\new Staff = "III" \with { +instrumentName = "III" +shortInstrumentName = "III" +midiInstrument = #"clarinet" + +} +<< + +{ +\set Score.markFormatter = #format-mark-box-numbers \tempo 2 = 60 + \numericTimeSignature \time 2/2 + \clef alto + +<< + { c'4^\markup { \pad-markup #0.2 "+0"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "nil"\normal-size-super "1/1" }} ~ c'2. ~ } +>> + \bar "|" +<< + { c'1 ~ } +>> + \bar "|" +<< + { c'1 ~ } +>> + \bar "|" +<< + { c'1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { c'1 ~ } +>> + \bar "|" +<< + { c'1 ~ } +>> + \bar "|" +<< + { c'2 ~ c'8.[ r16] r4 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \break \noPageBreak +<< + { r2. r16[ cis'8.^\markup { \pad-markup #0.2 "-47"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "11/8" }}] ~ } +>> + \bar "|" +<< + { cis'1 ~ } +>> + \bar "|" +<< + { cis'1 ~ } +>> + \bar "|" +<< + { cis'1 ~ } +>> + \bar "|" \pageBreak +<< + { cis'4 ~ cis'16[ b8.^\markup { \pad-markup #0.2 "-12"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "5/4" }}] ~ b2 ~ } +>> + \bar "|" +<< + { b1 ~ } +>> + \bar "|" +<< + { b1 ~ } +>> + \bar "|" +<< + { b2. a4^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "8/7" }} ~ } +>> + \bar "|" \break \noPageBreak +<< + { a4 ~ a8[ b8^\markup { \pad-markup #0.2 "-39"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "16/13" }}] ~ b2 ~ } +>> + \bar "|" +<< + { b1 ~ } +>> + \bar "|" +<< + { b1 ~ } +>> + \bar "|" +<< + { b1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { b1 ~ } +>> + \bar "|" +<< + { b1 ~ } +>> + \bar "|" +<< + { b1 ~ } +>> + \bar "|" +<< + { b1 ~ } +>> + \bar "|" \pageBreak +<< + { b4 ~ b16[ r8.] r2 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r4 a4^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "2/5" }} ~ a2 ~ } +>> + \bar "|" \break \noPageBreak +<< + { a4 ~ a8.[ fis16^\markup { \pad-markup #0.2 "+44"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "11/32" }}] ~ fis2 ~ } +>> + \bar "|" +<< + { fis1 ~ } +>> + \bar "|" +<< + { fis1 ~ } +>> + \bar "|" +<< + { fis1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { fis1 ~ } +>> + \bar "|" +<< + { fis4 ~ fis8[ r8] r2 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r2. a4^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "2/5" }} ~ } +>> + \bar "|" \pageBreak +<< + { a2. ~ a8[ g8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "4/11" }}] ~ } +>> + \bar "|" +<< + { g2 ~ g8[ dis8^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "2/7" }}] ~ dis4 ~ } +>> + \bar "|" +<< + { dis1 ~ } +>> + \bar "|" +<< + { dis1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { dis1 ~ } +>> + \bar "|" +<< + { dis1 ~ } +>> + \bar "|" +<< + { dis1 ~ } +>> + \bar "|" +<< + { dis2. dis4^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "2/3" }} ~ } +>> + \bar "|" \break \noPageBreak +<< + { dis1 ~ } +>> + \bar "|" +<< + { dis1 ~ } +>> + \bar "|" +<< + { dis2. ~ dis8[ cis8^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "8/13" }}] ~ } +>> + \bar "|" +<< + { cis2. ~ cis8[ r8] } +>> + \bar "|" \pageBreak +<< + { r1 } +>> + \bar "|" +<< + { r2. r16[ c8.^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "2/7" }}] ~ } +>> + \bar "|" +<< + { c1 ~ } +>> + \bar "|" +<< + { c1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { c4 ~ c16[ dis8.^\markup { \pad-markup #0.2 "+24"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "1/4" }}] ~ dis2 ~ } +>> + \bar "|" +<< + { dis1 ~ } +>> + \bar "|" +<< + { dis8.[ d16^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "5/16" }}] ~ d2. } +>> + \bar "|" +<< + { dis4^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "1/3" }} ~ dis2. } +>> + \bar "|" \break \noPageBreak +<< + { c4^\markup { \pad-markup #0.2 "+4"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "2/7" }} ~ c2. ~ } +>> + \bar "|" +<< + { c4 c4^\markup { \pad-markup #0.2 "+35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "2/11" }} ~ c2 ~ } +>> + \bar "|" +<< + { c2 ~ c16[ d8.^\markup { \pad-markup #0.2 "+27"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "13/64" }}] ~ d4 ~ } +>> + \bar "|" +<< + { d2 ~ d8[ dis8^\markup { \pad-markup #0.2 "-29"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "1/3" }}] ~ dis4 ~ } +>> + \bar "|" \pageBreak +<< + { dis4 ~ dis16[ e8.^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "4/11" }}] ~ e2 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { e1 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { e1 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" +<< + { e8[ r8] r4 r16[ e8.^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "100/100" }}] ~ e4 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" \pageBreak +<< + { e1 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { e2. ~ e8.[ r16] } +>> + \bar "|" +<< + { r4 e4^\markup { \pad-markup #0.2 "+21"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "100/100" }} ~ e2 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { e1 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" +<< + { e1 ~ } +>> + \bar "|" \pageBreak +<< + { e1 ~ } +>> + \bar "|" +<< + { e8[ r8] r2. } +>> + \bar "|" +<< + { r2 r8[ cis8^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "4/13" }}] ~ cis4 ~ } +>> + \bar "|" +<< + { cis1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { cis1 ~ } +>> + \bar "|" +<< + { cis1 ~ } +>> + \bar "|" +<< + { cis1 ~ } +>> + \bar "|" +<< + { cis1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { cis1 ~ } +>> + \bar "|" +<< + { cis2 ~ cis16[ f8.^\markup { \pad-markup #0.2 "-26"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "3/8" }}] ~ f4 ~ } +>> + \bar "|" +<< + { f4 ~ f8.[ dis16^\markup { \pad-markup #0.2 "-13"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "5/16" }}] ~ dis2 ~ } +>> + \bar "|" +<< + { dis8.[ fis16^\markup { \pad-markup #0.2 "+3"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "3/8" }}] ~ fis2. } +>> + \bar "|" \pageBreak +<< + { g4^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "2/5" }} ~ g4 ~ g8.[ ais16^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "1/2" }}] ~ ais4 ~ } +>> + \bar "|" +<< + { ais4 ~ ais16[ b8.^\markup { \pad-markup #0.2 "+1"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "1/2" }}] ~ b2 ~ } +>> + \bar "|" +<< + { b16[ cis'8.^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "4/7" }}] ~ cis'2. ~ } +>> + \bar "|" +<< + { cis'2. ~ cis'8[ r8] } +>> + \bar "|" \break \noPageBreak +<< + { r1 } +>> + \bar "|" +<< + { d'4^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "13/8" }} ~ d'2. ~ } +>> + \bar "|" +<< + { d'1 ~ } +>> + \bar "|" +<< + { d'2 ~ d'8[ cis'8^\markup { \pad-markup #0.2 "+32"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "8/5" }}] ~ cis'4 ~ } +>> + \bar "|" \break \noPageBreak +<< + { cis'1 ~ } +>> + \bar "|" +<< + { cis'4 ~ cis'8[ d'8^\markup { \pad-markup #0.2 "-41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "13/8" }}] ~ d'2 ~ } +>> + \bar "|" +<< + { d'8[ c'8^\markup { \pad-markup #0.2 "-33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "16/11" }}] ~ c'2. ~ } +>> + \bar "|" +<< + { c'8[ r8] r2. } +>> + \bar "|" \pageBreak +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \break \noPageBreak +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 \fermata }>> \bar "|." +} + +>> +>> \ No newline at end of file diff --git a/lilypond/includes/part_IV.ly b/lilypond/includes/part_IV.ly new file mode 100644 index 0000000..c0ce49b --- /dev/null +++ b/lilypond/includes/part_IV.ly @@ -0,0 +1,481 @@ +\new StaffGroup \with {\remove "System_start_delimiter_engraver"} +<< +\new Staff = "IV" \with { +instrumentName = "IV" +shortInstrumentName = "IV" +midiInstrument = #"clarinet" + +} +<< + +{ +\set Score.markFormatter = #format-mark-box-numbers \tempo 2 = 60 + \numericTimeSignature \time 2/2 + \clef bass + +<< + { r2 r8[ gis8^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "4/5" }}] ~ gis4 ~ } +>> + \bar "|" +<< + { gis1 ~ } +>> + \bar "|" +<< + { gis1 ~ } +>> + \bar "|" +<< + { gis1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { gis2 ~ gis16[ g8.^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "3/4" }}] ~ g4 ~ } +>> + \bar "|" +<< + { g1 ~ } +>> + \bar "|" +<< + { g1 ~ } +>> + \bar "|" +<< + { g8.[ r16] r2. } +>> + \bar "|" \break \noPageBreak +<< + { r8.[ g16^\markup { \pad-markup #0.2 "+2"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "1/1" }}] ~ g2. ~ } +>> + \bar "|" +<< + { g1 ~ } +>> + \bar "|" +<< + { g1 ~ } +>> + \bar "|" +<< + { g1 ~ } +>> + \bar "|" \pageBreak +<< + { g1 ~ } +>> + \bar "|" +<< + { g1 ~ } +>> + \bar "|" +<< + { g1 ~ } +>> + \bar "|" +<< + { g1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { g1 ~ } +>> + \bar "|" +<< + { g2. ~ g8.[ f16^\markup { \pad-markup #0.2 "+10"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "8/11" }}] ~ } +>> + \bar "|" +<< + { f1 ~ } +>> + \bar "|" +<< + { f4 ~ f8[ fis8^\markup { \pad-markup #0.2 "-37"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "3/4" }}] ~ fis2 ~ } +>> + \bar "|" \break \noPageBreak +<< + { fis1 ~ } +>> + \bar "|" +<< + { fis1 ~ } +>> + \bar "|" +<< + { fis1 ~ } +>> + \bar "|" +<< + { fis1 ~ } +>> + \bar "|" \pageBreak +<< + { fis1 ~ } +>> + \bar "|" +<< + { fis2 ~ fis16[ r8.] r4 } +>> + \bar "|" +<< + { r2. r8[ gis8^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "1/2" }}] ~ } +>> + \bar "|" +<< + { gis1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { gis1 ~ } +>> + \bar "|" +<< + { gis4 ~ gis8.[ a16^\markup { \pad-markup #0.2 "+33"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "13/32" }}] ~ a2 ~ } +>> + \bar "|" +<< + { a1 ~ } +>> + \bar "|" +<< + { a4 ~ a16[ g8.^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "4/11" }}] ~ g2 ~ } +>> + \bar "|" \break \noPageBreak +<< + { g8.[ fis16^\markup { \pad-markup #0.2 "-9"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "1/2" }}] ~ fis2. ~ } +>> + \bar "|" +<< + { fis2 ~ fis8[ r8] r4 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r8.[ gis16^\markup { \pad-markup #0.2 "-5"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "1/2" }}] ~ gis2. ~ } +>> + \bar "|" \pageBreak +<< + { gis1 ~ } +>> + \bar "|" +<< + { gis1 ~ } +>> + \bar "|" +<< + { gis1 ~ } +>> + \bar "|" +<< + { gis4 g2.^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "4/11" }} ~ } +>> + \bar "|" \break \noPageBreak +<< + { g2. ~ g8[ a8^\markup { \pad-markup #0.2 "+6"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "II"\normal-size-super "2/5" }}] ~ } +>> + \bar "|" +<< + { a2 ~ a8.[ ais16^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "16/11" }}] ~ ais4 ~ } +>> + \bar "|" +<< + { ais1 ~ } +>> + \bar "|" +<< + { ais1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { ais1 ~ } +>> + \bar "|" +<< + { ais1 ~ } +>> + \bar "|" +<< + { ais1 ~ } +>> + \bar "|" +<< + { ais1 ~ } +>> + \bar "|" \pageBreak +<< + { ais4 ~ ais16[ r8.] r2 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \break \noPageBreak +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \break \noPageBreak +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \pageBreak +<< + { r1 } +>> + \bar "|" +<< + { r8.[ gis16^\markup { \pad-markup #0.2 "+7"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "5/4" }}] ~ gis2. ~ } +>> + \bar "|" +<< + { gis1 ~ } +>> + \bar "|" +<< + { gis1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { gis16[ g8.^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "8/7" }}] ~ g2. ~ } +>> + \bar "|" +<< + { g2. ~ g8[ a8^\markup { \pad-markup #0.2 "+19"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "4/3" }}] ~ } +>> + \bar "|" +<< + { a1 ~ } +>> + \bar "|" +<< + { a1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { a1 ~ } +>> + \bar "|" +<< + { a2 r2 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r8[ g8^\markup { \pad-markup #0.2 "-48"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "8/7" }}] ~ g2. ~ } +>> + \bar "|" \pageBreak +<< + { g1 ~ } +>> + \bar "|" +<< + { g1 ~ } +>> + \bar "|" +<< + { g2 ~ g8.[ ais16^\markup { \pad-markup #0.2 "-28"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "11/8" }}] ~ ais4 ~ } +>> + \bar "|" +<< + { ais1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { ais2 r2 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \break \noPageBreak +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \pageBreak +<< + { r1 } +>> + \bar "|" +<< + { r2. r8[ g8^\markup { \pad-markup #0.2 "+41"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "7/16" }}] ~ } +>> + \bar "|" +<< + { g1 ~ } +>> + \bar "|" +<< + { g1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { g1 ~ } +>> + \bar "|" +<< + { g2 ~ g16[ fis8.^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "4/3" }}] ~ fis4 ~ } +>> + \bar "|" +<< + { fis1 ~ } +>> + \bar "|" +<< + { fis2. ~ fis16[ f8.^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "III"\normal-size-super "5/4" }}] ~ } +>> + \bar "|" \break \noPageBreak +<< + { f1 ~ } +>> + \bar "|" +<< + { f2 ~ f8.[ r16] r4 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \pageBreak +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" \break \noPageBreak +<< + { r4 f2.^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "IV"\normal-size-super "1/1" }} ~ } +>> + \bar "|" +<< + { f1 ~ } +>> + \bar "|" +<< + { f1 ~ } +>> + \bar "|" +<< + { f1 ~ } +>> + \bar "|" \break \noPageBreak +<< + { f1 ~ } +>> + \bar "|" +<< + { f1 ~ } +>> + \bar "|" +<< + { f1 ~ } +>> + \bar "|" +<< + { f2 ~ f8.[ r16] r4 } +>> + \bar "|" \pageBreak +<< + { r2 fis2^\markup { \pad-markup #0.2 "+30"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "2/5" }} ~ } +>> + \bar "|" +<< + { fis2. ~ fis8[ f8^\markup { \pad-markup #0.2 "-35"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "4/11" }}] ~ } +>> + \bar "|" +<< + { f1 ~ } +>> + \bar "|" +<< + { f4 f2.^\markup { \pad-markup #0.2 "+18"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "3/8" }} ~ } +>> + \bar "|" \break \noPageBreak +<< + { f8.[ dis16^\markup { \pad-markup #0.2 "+14"}_\markup { \lower #3 \pad-markup #0.2 \concat{ "I"\normal-size-super "1/3" }}] ~ dis2. ~ } +>> + \bar "|" +<< + { dis8.[ r16] r2. } +>> + \bar "|" +<< + { r1 } +>> + \bar "|" +<< + { r1 \fermata }>> \bar "|." +} + +>> +>> \ No newline at end of file diff --git a/lilypond/score_template.ly b/lilypond/score_template.ly new file mode 100644 index 0000000..822f3a6 --- /dev/null +++ b/lilypond/score_template.ly @@ -0,0 +1,177 @@ +\version "2.22.2" + +#(define (override-color-for-all-grobs color) + (lambda (context) + (let loop ((x all-grob-descriptions)) + (if (not (null? x)) + (let ((grob-name (caar x))) + (ly:context-pushpop-property context grob-name 'color color) + (loop (cdr x))))))) + + #(define-markup-command (relMark layout props mus) (ly:music?) + #:properties ((size -2)) + (interpret-markup layout props + #{ + \markup { + \score { + \new Staff { $mus } + \layout { + \context { + \Staff + \remove Time_signature_engraver + fontSize = #-2 + \hide Stem + \override TextScript.outside-staff-priority = ##f + \override StaffSymbol.staff-space = #(magstep -2) + \override StaffSymbol.thickness = #(magstep -2) + \override TextScript.self-alignment-X = #-0.4 + \override TextScript.staff-padding = #1 + } + \context { + \Score + proportionalNotationDuration = #(ly:make-moment 1/16) + \remove "Separating_line_group_engraver" + \override SpacingSpanner.strict-note-spacing = ##t + \override RehearsalMark.self-alignment-X = #-1 + \override RehearsalMark.Y-offset = #10 + \override RehearsalMark.X-offset = #10 + } + \context { + \Voice + \consists "Horizontal_bracket_engraver" + \override HorizontalBracket.direction = #UP + } + indent = 0 + line-width = 4\cm + } + } + } + #})) + + +\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 { \on-the-fly #not-first-page {\pad-markup #2 { \concat {\italic {"test"}}}}}}} + evenHeaderMarkup = \markup { \fill-line { \line { \on-the-fly #not-first-page {\pad-markup #2 { \concat {\italic {"test"}}}}}}} + oddFooterMarkup = \markup { \fill-line { + \concat { + "-" + \fontsize #1.5 + \on-the-fly #print-page-number-check-first + \fromproperty #'page:page-number-string + "-"}}} + evenFooterMarkup = \markup { \fill-line { + \concat { + "-" + \fontsize #1.5 + \on-the-fly #print-page-number-check-first + \fromproperty #'page:page-number-string + "-"}}} +} + +\header { + title = \markup { \italic {test}} + 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 + } + \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 + } +} + +\midi { } + + +\score{ +\new Score + << + \new SemiStaffGroup { + << + \include "includes/part_I.ly" + \include "includes/part_II.ly" + \include "includes/part_III.ly" + \include "includes/part_IV.ly" + >> + } + >> + + \layout{} + \midi{} +} diff --git a/lilypond/score_template.midi b/lilypond/score_template.midi new file mode 100644 index 0000000..9e56cb4 Binary files /dev/null and b/lilypond/score_template.midi differ diff --git a/lilypond/score_template.pdf b/lilypond/score_template.pdf new file mode 100644 index 0000000..7b0bd5a Binary files /dev/null and b/lilypond/score_template.pdf differ diff --git a/open_stage_control/fragments/dur_probs_panel.json b/open_stage_control/fragments/dur_probs_panel.json new file mode 100644 index 0000000..29f4d8d --- /dev/null +++ b/open_stage_control/fragments/dur_probs_panel.json @@ -0,0 +1,159 @@ +{ + "version": "1.24.0", + "createdWith": "Open Stage Control", + "type": "fragment", + "content": { + "type": "panel", + "top": 0, + "left": 0, + "lock": false, + "id": "@{parent.id}_probs", + "visible": true, + "interaction": true, + "comments": "", + "width": "100%", + "height": "100%", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "fragment", + "top": 0, + "left": 0, + "lock": false, + "id": "@{parent.id}_dur", + "visible": true, + "interaction": true, + "comments": "", + "width": "auto", + "height": "100%", + "expand": "false", + "css": ":host {\n\n width: calc(100% - 160rem);\n\n}", + "file": "fragments/env.json", + "fallback": "", + "props": { + "variables": { + "grandparent": "@{parent.id}" + } + }, + "address": "auto", + "variables": "@{parent.variables}" + }, + { + "type": "fragment", + "top": 0, + "left": "auto", + "lock": false, + "id": "@{parent.id}_chord", + "visible": true, + "interaction": true, + "comments": "", + "width": 80, + "height": "100%", + "expand": "false", + "css": ":host {\n\n left: calc(100% - 160rem);\n\n}", + "file": "fragments/slider.json", + "fallback": "", + "props": { + "variables": { + "min": 0, + "max": 1, + "slider_label": "chord prob", + "grandparent": "@{parent.id}" + } + }, + "address": "auto", + "variables": "@{parent.variables}" + }, + { + "type": "variable", + "lock": false, + "id": "@{parent.id}_vals", + "comments": "", + "value": "", + "default": [ + 0, + 0.25, + 2, + 0, + 0.5, + 0.5, + 0.5, + 1, + 0.5 + ], + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "var sync = get(getProp(\"parent\", \"id\") + \"_sync\");\nvar pID = getProp(\"parent\", \"id\");\nif(sync == \"entrances\") {\n pID = \"entrances_probs\"\n} else \nif (sync == \"passages\") {\n pID = \"passages_probs\"\n} else \nif (sync == \"exits\") {\n pID = \"exits_probs\"\n}\n\nvar cProb = get(pID + '_chord_val_slider')\nvar pRange = get(pID + '_pad_val_rslider')\nvar env = get(pID + '_dur_env_vals')\nvalue = ([cProb]).concat(pRange).concat(env);\nset(\"this\", value)" + }, + { + "type": "fragment", + "top": 0, + "left": "auto", + "lock": false, + "id": "@{parent.id}_pad", + "visible": true, + "interaction": true, + "comments": "", + "width": 80, + "height": "100%", + "expand": "false", + "css": ":host {\n\n left: calc(100% - 80rem);\n\n}", + "file": "fragments/range_slider.json", + "fallback": "", + "props": { + "variables": { + "min": 0, + "max": 10, + "rslider_label": "pad", + "grandparent": "@{parent.id}", + "decimals": 2 + } + }, + "address": "auto", + "variables": "@{parent.variables}" + } + ], + "tabs": [], + "tabsPosition": "top" + } +} \ No newline at end of file diff --git a/open_stage_control/fragments/env.json b/open_stage_control/fragments/env.json new file mode 100644 index 0000000..802a4a2 --- /dev/null +++ b/open_stage_control/fragments/env.json @@ -0,0 +1,372 @@ +{ + "version": "1.22.0", + "createdWith": "Open Stage Control", + "type": "fragment", + "content": { + "type": "panel", + "top": 90, + "left": 160, + "lock": false, + "id": "@{parent.id}_env", + "visible": true, + "interaction": true, + "comments": "", + "width": 440, + "height": 310, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "variable", + "lock": false, + "id": "@{parent.id}_vals", + "comments": "", + "value": "", + "default": [ + [ + 0, + 0.5 + ], + [ + 0.5, + 0.5 + ], + [ + 1, + 0.5 + ] + ], + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "canvas", + "top": 30, + "left": 0, + "lock": false, + "id": "@{parent.id}_canvas", + "visible": true, + "interaction": true, + "comments": "", + "width": "auto", + "height": "auto", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": ":host {\n\n width: 100%;\n height: calc(100% - 70rem);\n\n}", + "valueLength": 64, + "autoClear": true, + "continuous": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "set(getProp(\"parent\", \"id\") + \"_size\", 3)\nvalue[0] = [0.0, 0.5]\nvalue[1] = [0.5, 0.5]\nvalue[2] = [1.0, 0.5]\n\nlocals.eucDistance = function(p1, p2) {\n var a = p1[0] - p2[0];\n var b = p1[1] - (1 - p2[1]);\n return Math.sqrt( a*a + b*b );\n}\n\nlocals.closest = function(v, x, y, s){\n return (v.slice(0, s).reduce((a, b) => \n locals.eucDistance([x, y], a) < locals.eucDistance([x, y], b) ? a : b));\n}\n\nlocals.cIndex = 1\nlocals.cDist = 0\n\nsetVar(this, 'reset', function() {\n set(getProp(\"parent\", \"id\") + \"_size\", 3)\n var val = []\n val.length = 64; \n val.fill(0);\n val[0] = [0.0, 0.5]\n val[1] = [0.5, 0.5]\n val[2] = [1.0, 0.5]\n set(getProp(\"parent\", \"id\") + '_canvas', val)\n})\n\n\nsetVar(this, 'update', function() {\n var limits = get(getProp(\"parent\", \"id\") + '_rslider')\n var vals = get(getProp(\"parent\", \"id\") + '_canvas')\n var size = get(getProp(\"parent\", \"id\") + '_size')\n set(getProp(\"parent\", \"id\") + \"_vals\", (limits).concat(vals.slice(0, size).flat()));\n var parentVariables = getProp('parent', 'variables')\n if (parentVariables.grandparent) {\n set(parentVariables.grandparent + '_vals', value)\n }\n})\n", + "onValue": "// apply limits\nfor(var i = 0; i < get(getProp(\"parent\", \"id\") + \"_size\"); i += 1) {\n if(typeof value[i] === 'string') {value[i] = JSON.parse(value[i])}\n value[i] = [Math.max(0, Math.min(1, value[i][0])), Math.max(0, Math.min(1, value[i][1]))]\n}\n\n// re-update widget value without retriggering script or sending message\nset(\"this\", value, {sync: true, send: false})\ngetVar('this', 'update')()", + "onTouch": "var lock = false\n\n// store normalized coordinates\nif (event.type == \"start\") {\n locals.x = event.offsetX / width\n locals.y = event.offsetY / height\n lock = true\n locals.cIndex = value.indexOf(locals.closest(value, locals.x, locals.y, get(getProp(\"parent\", \"id\") + \"_size\")))\n locals.cDist = locals.eucDistance([locals.x, locals.y], value[locals.cIndex])\n} else {\n // when the pointer is moving, increment coordinates\n // because offsetX and offsetY may not be relevant\n // if the pointer hovers a different widgets\n locals.x += event.movementX / width\n locals.y += event.movementY / height\n}\n\n\nif(lock && (locals.cDist > 0.1) && (locals.x >= 0) && (locals.y >= 0) && (locals.x <= 1) && (locals.y <= 1)) {\n value[get(getProp(\"parent\", \"id\") + \"_size\")] = [locals.x, 1 - locals.y]\n value.sort((a, b) => a[0] - b[0])\n locals.cIndex = value.indexOf(locals.closest(value, locals.x, locals.y, get(getProp(\"parent\", \"id\") + \"_size\")))\n set(getProp(\"parent\", \"id\") + '_size', get(getProp(\"parent\", \"id\") + \"_size\") + 1)\n} else {\n value[locals.cIndex] = [locals.x, 1 - locals.y]\n}\n\nvar min = get(getProp(\"parent\", \"id\") + \"_input_min\")\nvar max = get(getProp(\"parent\", \"id\") + \"_input_max\")\n\nif (event.type != \"stop\") {\n set(getProp(\"parent\", \"id\") + \"_mpos\", \"x: \" + ((locals.x * (max - min)) + min).toFixed(2) + \"\\ny: \" + (1 - locals.y).toFixed(2))\n} else {\n lock = false\n set(getProp(\"parent\", \"id\") + \"_mpos\", \"\")\n}\nset(\"this\", value)", + "onDraw": "//var size = get('@{parent.id}_size')\nfor(var i = 0; i < get(getProp(\"parent\", \"id\") + \"_size\"); i += 1) {\n ctx.fillStyle = cssVars.colorFill\n ctx.fillRect(value[i][0] * width - 2.5, (1 - value[i][1]) * height - 2.5, 5, 5)\n}\n\nctx.stroke();\nctx.strokeStyle = cssVars.colorFill\nctx.beginPath();\n\nfor(var i = 0; i < get(getProp(\"parent\", \"id\") + \"_size\"); i += 1) {\n if(i === 0){\n ctx.moveTo(value[i][0] * width, (1 - value[i][1]) * height)\n } else {\n ctx.lineTo(value[i][0] * width, (1 - value[i][1]) * height); // Draw a line to (150, 100)\n }\n}\n\nctx.stroke();", + "onResize": "" + }, + { + "type": "variable", + "lock": false, + "id": "@{parent.id}_size", + "comments": "", + "value": "", + "default": 3, + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "button", + "top": "auto", + "left": 0, + "lock": false, + "id": "@{parent.id}_flatten", + "visible": true, + "interaction": true, + "comments": "", + "width": 30, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": ":host {\n\n top: calc(100% - 30rem);\n\n}", + "colorTextOn": "auto", + "label": "F", + "vertical": false, + "wrap": false, + "on": 1, + "off": 0, + "mode": "push", + "doubleTap": false, + "decoupled": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "if(value === 1){\n getVar(getProp(\"parent\", \"id\") + '_canvas', 'reset')()\n}" + }, + { + "type": "range", + "top": 0, + "left": 50, + "lock": false, + "id": "@{parent.id}_rslider", + "visible": true, + "interaction": true, + "comments": "", + "width": "auto", + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": ":host {\n\n width: calc(100% - 100rem);\n\n}", + "design": "default", + "knobSize": "auto", + "horizontal": true, + "pips": false, + "dashed": false, + "gradient": [], + "snap": true, + "spring": false, + "doubleTap": false, + "range": { + "min": 0, + "max": 5 + }, + "logScale": false, + "sensitivity": 1, + "steps": "", + "value": "[@{@{parent.id}_input_min.value}, @{@{parent.id}_input_max.value}]", + "default": [ + 0.5, + 2 + ], + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "getVar(getProp(\"parent\", \"id\") + '_canvas', 'update')()", + "onTouch": "" + }, + { + "type": "input", + "top": 0, + "left": "auto", + "lock": false, + "id": "@{parent.id}_input_max", + "visible": true, + "interaction": true, + "comments": "", + "width": 50, + "height": "auto", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": ":host {\n\n left: calc(100% - 50rem);\n\n}", + "align": "center", + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "value": "@{@{parent.id}_rslider.value.1}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "" + }, + { + "type": "input", + "top": 0, + "left": 0, + "lock": false, + "id": "@{parent.id}_input_min", + "visible": true, + "comments": "", + "width": 50, + "height": "auto", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "@{@{parent.id}_rslider.value.0}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "typeTags": "", + "ignoreDefaults": false, + "bypass": true + }, + { + "type": "text", + "top": "auto", + "left": "auto", + "lock": false, + "id": "@{parent.id}_mpos", + "visible": true, + "comments": "", + "width": 130, + "height": 40, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": ":host {\n\n top: calc(100% - 40rem);\n left: calc(50% - 65rem);\n\n}", + "align": "center", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "vertical": false, + "wrap": false + } + ], + "tabs": [] + } +} \ No newline at end of file diff --git a/open_stage_control/fragments/range_slider.json b/open_stage_control/fragments/range_slider.json new file mode 100644 index 0000000..2b39825 --- /dev/null +++ b/open_stage_control/fragments/range_slider.json @@ -0,0 +1,228 @@ +{ + "version": "1.22.0", + "createdWith": "Open Stage Control", + "type": "fragment", + "content": { + "type": "panel", + "top": 0, + "left": 0, + "lock": false, + "id": "@{parent.id}_val", + "visible": true, + "interaction": true, + "comments": "", + "width": 130, + "height": 340, + "expand": true, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "variables": "@{parent.variables}", + "traversing": false, + "value": "@{this.id}_rslider", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "input", + "top": "auto", + "left": 0, + "lock": false, + "id": "@{parent.id}_input_min", + "visible": true, + "interaction": true, + "comments": "", + "width": "100%", + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": ":host {\n\n top: calc(100% - 30rem);\n\n}", + "align": "center", + "unit": "", + "asYouType": false, + "numeric": true, + "validation": "", + "maxLength": "", + "value": "@{@{parent.id}_rslider.value.0}", + "default": "@{parent.variables.min}", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": "@{parent.variables.decimals}", + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "" + }, + { + "type": "range", + "top": 60, + "left": 0, + "lock": false, + "id": "@{parent.id}_rslider", + "visible": true, + "interaction": true, + "comments": "", + "width": "100%", + "height": "auto", + "expand": false, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": ":host {\n\n height: calc(100% - 90rem);\n\n}", + "design": "default", + "knobSize": "auto", + "horizontal": false, + "pips": false, + "dashed": false, + "gradient": [], + "snap": true, + "spring": false, + "doubleTap": false, + "range": "{\n \"min\": @{parent.variables.min},\n \"max\": @{parent.variables.max}\n}", + "logScale": false, + "sensitivity": 1, + "steps": "", + "value": "[@{@{parent.id}_input_min.value}, @{@{parent.id}_input_max.value}]", + "default": "[\n @{parent.variables.min},\n @{parent.variables.max}\n]", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "i", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "var parentVariables = getProp('parent', 'variables')\nif (parentVariables.grandparent) {\n set(parentVariables.grandparent + '_vals', value)\n}", + "onTouch": "" + }, + { + "type": "input", + "width": "100%", + "height": 30, + "left": 0, + "top": 30, + "lock": false, + "id": "@{parent.id}_input_max", + "visible": true, + "interaction": true, + "comments": "", + "expand": "false", + "css": "", + "address": "auto", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "align": "center", + "unit": "", + "asYouType": false, + "numeric": true, + "validation": "", + "maxLength": "", + "value": "@{@{parent.id}_rslider.value.1}", + "default": "@{parent.variables.max}", + "linkId": "", + "preArgs": "", + "typeTags": "", + "decimals": "@{parent.variables.decimals}", + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "" + }, + { + "type": "text", + "top": 0, + "left": 0, + "lock": false, + "id": "@{parent.id}_rslider_label", + "visible": true, + "comments": "", + "width": "100%", + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "align": "center", + "value": "@{parent.variables.rslider_label}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "" + } + ], + "tabs": [] + } +} \ No newline at end of file diff --git a/open_stage_control/fragments/slider.json b/open_stage_control/fragments/slider.json new file mode 100644 index 0000000..6284252 --- /dev/null +++ b/open_stage_control/fragments/slider.json @@ -0,0 +1,186 @@ +{ + "version": "1.22.0", + "createdWith": "Open Stage Control", + "type": "fragment", + "content": { + "type": "panel", + "top": 0, + "left": 0, + "lock": false, + "id": "@{parent.id}_val", + "visible": true, + "interaction": true, + "comments": "", + "width": "100%", + "height": "100%", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": ":host {\n\n left: calc(100% - 80rem);\n\n}", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "fader", + "top": 30, + "left": 0, + "lock": false, + "id": "@{parent.id}_slider", + "visible": true, + "comments": "", + "width": "100%", + "height": "auto", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": ":host {\n\n height: calc(100% - 60rem);\n\n}", + "value": "@{@{parent.id}_input.value}", + "default": 0.75, + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "var parentVariables = getProp('parent', 'variables')\nif (parentVariables.grandparent) {\n set(parentVariables.grandparent + '_vals', value)\n}", + "interaction": true, + "typeTags": "", + "ignoreDefaults": false, + "bypass": false, + "design": "default", + "knobSize": "auto", + "horizontal": false, + "pips": false, + "dashed": false, + "gradient": [], + "snap": true, + "spring": false, + "doubleTap": false, + "range": "{\n \"min\": @{parent.variables.min},\n \"max\": @{parent.variables.max}\n}", + "logScale": false, + "sensitivity": 1, + "steps": "", + "onTouch": "", + "origin": "auto" + }, + { + "type": "input", + "top": "auto", + "left": 0, + "lock": false, + "id": "@{parent.id}_input", + "visible": true, + "comments": "", + "width": "100%", + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": ":host {\n\n top: calc(100% - 30rem);\n\n}", + "align": "center", + "value": "@{@{parent.id}_slider.value}", + "default": 0.75, + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "typeTags": "", + "ignoreDefaults": false, + "bypass": true + }, + { + "type": "text", + "top": 0, + "left": 0, + "lock": false, + "id": "@{parent.id}_slider_label", + "visible": true, + "comments": "", + "width": "100%", + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "align": "center", + "value": "@{parent.variables.slider_label}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "" + } + ], + "tabs": [] + } +} \ No newline at end of file diff --git a/open_stage_control/modules/custom_module.js b/open_stage_control/modules/custom_module.js new file mode 100644 index 0000000..0186829 --- /dev/null +++ b/open_stage_control/modules/custom_module.js @@ -0,0 +1,277 @@ +const {resolve} = nativeRequire("path"); +var fs = nativeRequire("fs"); + +stringifyToDepth = function(data, maxDepth){ + var prettyString = "" + var rCount = 0 + var writeArray + var indent; + + if(maxDepth === 0) { + JSON.stringify(data) + } else { + indent = function(size) {return Array.from({length: size}, () => " ").join("")} + writeArray = function(array) { + prettyString = prettyString + indent(rCount) + "[\n" + rCount = rCount + 1 + if(rCount < maxDepth) { + array.forEach(item => writeArray(item)) + } else { + var formmattedArray; + formattedArray = array.map(item => indent(rCount) + JSON.stringify(item)).join(",\n") + formattedArray = formattedArray.replaceAll("[", "[ ").replaceAll("]", " ]").replaceAll(",", ", ") + prettyString = prettyString + formattedArray + } + rCount = rCount - 1; + prettyString = prettyString + "\n" + indent(rCount) + "],\n"; + } + + writeArray(data) + prettyString = prettyString.replaceAll(",\n\n", "\n").slice(0, -2); + return prettyString + } +} + +module.exports = { + + init: function(){ + // this will be executed once when the osc server starts + }, + + oscInFilter:function(data) { + + var {host, port, address, args} = data + + //console.log(data) + + if (address === '/playing') { + + var modelPath = resolve(args[0].value) + var model = loadJSON(modelPath) + //receive('/STATE/OPEN', guiStatePath) + + receive("/ref_uid", model.ref_uid) + + receive("/order_seed", model.order_seed) + receive("/dur_seed", model.dur_seed) + receive("/weights_seed", model.motifs_seed) + + + var envValsFlat = model.entrances_probs_vals.slice(5) + var envSize = envValsFlat.length / 2 + var envVals = new Array(64).fill({type: 'f', value: 0}) + for (var i = 0; i < envSize; i++) { + envVals[i] = [envValsFlat[i * 2], envValsFlat[i * 2 + 1]] + } + receive("/entrances_probs_dur_env_size", envSize) + receive("/entrances_probs_chord_val_slider", model.entrances_probs_vals[0]) + receive("/entrances_probs_pad_val_rslider", model.entrances_probs_vals.slice(1, 3)) + receive("/entrances_probs_dur_env_rslider", ...model.entrances_probs_vals.slice(3, 5)) + receive("/entrances_probs_dur_env_canvas", ...envVals) + + var envValsFlat = model.passages_probs_vals.slice(5) + var envSize = envValsFlat.length / 2 + var envVals = new Array(64).fill({type: 'f', value: 0}) + for (var i = 0; i < envSize; i++) { + envVals[i] = [envValsFlat[i * 2], envValsFlat[i * 2 + 1]] + } + receive("/passages_probs_dur_env_size", envSize) + receive("/passages_probs_chord_val_slider", model.passages_probs_vals[0]) + receive("/passages_probs_pad_val_rslider", model.passages_probs_vals.slice(1, 3)) + receive("/passages_probs_dur_env_rslider", ...model.passages_probs_vals.slice(3, 5)) + receive("/passages_probs_dur_env_canvas", ...envVals) + + var envValsFlat = model.exits_probs_vals.slice(5) + var envSize = envValsFlat.length / 2 + var envVals = new Array(64).fill({type: 'f', value: 0}) + for (var i = 0; i < envSize; i++) { + envVals[i] = [envValsFlat[i * 2], envValsFlat[i * 2 + 1]] + } + receive("/exits_probs_dur_env_size", envSize) + receive("/exits_probs_chord_val_slider", model.exits_probs_vals[0]) + receive("/exits_probs_pad_val_rslider", model.exits_probs_vals.slice(1, 3)) + receive("/exits_probs_dur_env_rslider", ...model.exits_probs_vals.slice(3, 5)) + receive("/exits_probs_dur_env_canvas", ...envVals) + + // no idea why I need to call the range sliders twice + receive("/range_matrix/0_val_rslider", ...model.ranges[0]) + receive("/range_matrix/1_val_rslider", ...model.ranges[1]) + receive("/range_matrix/2_val_rslider", ...model.ranges[2]) + receive("/range_matrix/3_val_rslider", ...model.ranges[3]) + + receive("/passages_weights/0_val_slider", model.passages_weights[0]) + receive("/passages_weights/1_val_slider", model.passages_weights[1]) + receive("/passages_weights/2_val_slider", model.passages_weights[2]) + receive("/passages_weights/3_val_slider", model.passages_weights[3]) + receive("/passages_weights/4_val_slider", model.passages_weights[4]) + + receive("/order", stringifyToDepth(model.order, 1)) + + receive("/sus_weights/0_val_slider", model.sus_weights[0]) + receive("/sus_weights/1_val_slider", model.sus_weights[1]) + receive("/sus_weights/2_val_slider", model.sus_weights[2]) + + receive("/order_size_rslider", ...model.order_size) + receive("/passages_size_rslider", ...model.passages_size) + + receive("/mus_seq", stringifyToDepth(model.music_data, 3)) + receive("/cur_play_index", args[1].value) + } + + if (address === '/generated') { + + //var guiStatePath = resolve(__dirname + "/../../resources/tmp/tmp_gui_state.json") + //var musPath = resolve(__dirname + "/../../resources/tmp/tmp_music.json") + var ledgerPath = resolve(__dirname + "/../../resources/piece_ledger.json") + //var guiState = loadJSON(guiStatePath) + //var musState = loadJSON(musPath) + //guiState.mus_seq = musState.music_data + //saveJSON(guiStatePath, guiState) + var ledger = loadJSON(ledgerPath).ledger + ledger.push("tmp") + var model = JSON.parse(args[1].value); + receive("/ledger", JSON.stringify(ledger, null, ' ').replace(/['"]+/g, '')) + receive("/mus_seq", stringifyToDepth(model.music_data, 3)) + receive("/order", stringifyToDepth(model.order, 1)) + } + + if (address === '/committed') { + try { + /* + var guiStatePath = resolve(__dirname + "/../../resources/tmp/tmp_gui_state.json") + var curUID = args[0].value + var state = loadJSON(guiStatePath) + state.cur_uid = curUID + var dir = resolve(__dirname + "/../../resources/" + curUID) + if (!fs.existsSync(dir)){ + fs.mkdirSync(dir); + } + guiStatePath = resolve(__dirname + "/../../resources/" + curUID + "/" + curUID + "_gui_state.json") + saveJSON(guiStatePath, state) + */ + } catch (e) { + console.log(`error while committing`) + console.error(e) + } + + var ledgerPath = args[1].value + receive("/ledger", JSON.stringify(loadJSON(ledgerPath).ledger, null, ' ').replace(/['"]+/g, '')) + return + } + + if (address === '/load_state') { + /* + var ref_uid = args[0].value + loadState(loadJSON("../../resources/" + ref_uid + "/" + ref_uid + "_gui_state.json")) + receive('/commit') + */ + return + } + + return data + + }, + + oscOutFilter:function(data) { + + var {host, port, address, args} = data + + //console.log(data) + + if (address === '/generate') { + try { + var state = JSON.parse(args[0].value) + + //console.log(__dirname) + var modelPath = resolve(__dirname + "/../../resources/tmp/tmp_mus_model.json") + var model = {} + model.schema_version = "1.0" + model.cur_uid = "tmp" + model.ref_uid = state.ref_uid + if(model.ref_uid == "nil" || model.ref_uid == "" || model.ref_uid == "[" || model.ref_uid == "[]") {delete model["ref_uid"]} + model.order_seed = state.order_seed + model.dur_seed = state.dur_seed + model.motifs_seed = state.weights_seed + model.entrances_probs_vals = state.entrances_probs_vals + model.passages_probs_vals = state.passages_probs_vals + model.exits_probs_vals = state.exits_probs_vals + model.ranges = [ + state["range_matrix/0_val_rslider"], + state["range_matrix/1_val_rslider"], + state["range_matrix/2_val_rslider"], + state["range_matrix/3_val_rslider"] + ] + model.passages_weights = [ + state["passages_weights/0_val_slider"], + state["passages_weights/1_val_slider"], + state["passages_weights/2_val_slider"], + state["passages_weights/3_val_slider"], + state["passages_weights/4_val_slider"] + ] + if(state.order_lock == 1){ + model.order = JSON.parse(state.order) + } + model.sus_weights = [ + state["sus_weights/0_val_slider"], + state["sus_weights/1_val_slider"], + state["sus_weights/2_val_slider"] + ] + model.order_size = state.order_size_rslider + model.passages_size = state.passages_size_rslider + + model.motif_edited = false + model.order_edited = false + //console.log(model) + saveJSON(modelPath, model) + + /* + var ledgerPanelState = JSON.parse(args[1].value) + delete ledgerPanelState.ref_uid + var omitKeys = Object.keys(ledgerPanelState).concat(["generate", "commit"]) + //console.log(omitKeys[0]) + for(k in omitKeys) { + //console.log(omitKeys[k]) + delete state[omitKeys[k]] + } + var guiStatePath = resolve(__dirname + "/../../resources/tmp/tmp_gui_state.json.json") + saveJSON(guiStatePath, state) + */ + + args = args.slice(0, 1) + args[0].value = modelPath + return {host, port, address, args} + } catch (e) { + //console.log(`error while building model ${args[0].value}`) + console.log(`error while building model`) + console.error(e) + } + return + } + + if (address === '/load_ledger') { + //console.log(loadJSON(args[0].value)) + receive('/ledger', JSON.stringify(loadJSON(args[0].value).ledger, null, ' ').replace(/['"]+/g, '')) + return data + } + + if (address === '/commit') { + var model = {} + model.music = JSON.parse(args[0].value) + args[0].value = JSON.stringify(model) + return {host, port, address, args} + } + + if ([/*'/commit', */'/save_ledger', '/transport'].includes(address)) { + //console.log(data) + return data + } + + return + + }, + + unload: function(){ + // this will be executed when the custom module is reloaded + }, + +} diff --git a/open_stage_control/seeds_and_ledgers_gui.json b/open_stage_control/seeds_and_ledgers_gui.json new file mode 100644 index 0000000..3669ce8 --- /dev/null +++ b/open_stage_control/seeds_and_ledgers_gui.json @@ -0,0 +1,2529 @@ +{ + "createdWith": "Open Stage Control", + "version": "1.24.0", + "type": "session", + "content": { + "type": "root", + "lock": false, + "id": "root", + "visible": true, + "interaction": true, + "comments": "", + "width": "auto", + "height": "auto", + "colorText": "auto", + "colorWidget": "auto", + "alphaFillOn": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "hideMenu": false, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "panel", + "top": 10, + "left": 770, + "lock": false, + "id": "motif_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": 560, + "height": 640, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "textarea", + "top": 50, + "left": 10, + "lock": false, + "id": "mus_seq", + "visible": true, + "comments": "", + "width": 530, + "height": 570, + "expand": false, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": 0, + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "textarea {\n white-space: pre;\n line-height: 20rem;\n font-size: 12rem;\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "//set(\"this\", JSON.stringify(JSON.parse(value), null, 5))", + "interaction": true, + "typeTags": "s", + "ignoreDefaults": false, + "bypass": false + }, + { + "type": "text", + "top": 10, + "left": 10, + "lock": false, + "id": "motif_label", + "visible": true, + "comments": "", + "width": 90, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "motif", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "vertical": false, + "wrap": false + }, + { + "type": "button", + "top": 10, + "left": 110, + "lock": false, + "id": "commit", + "visible": true, + "interaction": true, + "comments": "", + "width": 90, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "value": "", + "default": 0, + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "if(value === 0){\n send('/commit', get(\"mus_seq\"))\n}\n ", + "colorTextOn": "auto", + "label": "auto", + "vertical": false, + "wrap": false, + "on": 1, + "off": 0, + "mode": "push", + "doubleTap": false, + "decoupled": false + } + ], + "tabs": [], + "tabsPosition": "top" + }, + { + "type": "panel", + "top": 10, + "left": 580, + "lock": false, + "id": "ledger_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": 190, + "height": 640, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": false, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "text", + "top": 10, + "left": 10, + "lock": false, + "id": "ledger_label", + "visible": true, + "comments": "", + "width": 70, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "value": "ledger", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "vertical": false, + "wrap": false, + "align": "center" + }, + { + "type": "file", + "top": 50, + "left": 10, + "lock": false, + "id": "load_ledger", + "visible": true, + "interaction": true, + "comments": "", + "width": 70, + "height": 30.000000000000004, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "value": "open", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "set(\"this\", \"open\", {send:false})", + "align": "center", + "hidePath": true, + "mode": "open", + "directory": "Sketches/seeds_and_ledgers/resources", + "extension": "*", + "allowDir": false + }, + { + "type": "panel", + "top": 130, + "left": 10, + "lock": false, + "id": "sequencer_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": 180, + "height": 600, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": 0, + "borderRadius": 0, + "padding": 0, + "html": "", + "css": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": false, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "widgets": [ + { + "type": "panel", + "top": 21, + "left": 0, + "lock": false, + "id": "ledger_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": 170, + "height": 460, + "expand": true, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": 0, + "borderRadius": 0, + "padding": 0, + "html": "", + "css": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": "auto", + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "widgets": [ + { + "type": "variable", + "lock": false, + "id": "ledger_switch_vals", + "comments": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "variable", + "lock": false, + "id": "ledger_switch_indices", + "comments": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "variable", + "lock": false, + "id": "ledger_size", + "comments": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "/*\nvar array = Array(value + 2).fill().map((element, index) => index)\nconsole.log(array)\nset('ledger_switch_vals', array)\n*/" + }, + { + "type": "textarea", + "top": 0, + "left": 40, + "lock": false, + "id": "ledger", + "visible": true, + "interaction": true, + "comments": "", + "width": 90, + "height": "VAR{\"height\", 100}", + "expand": true, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "textarea {\n overflow-y: hidden;\n line-height: VAR{\"line-height\", 20}rem;\n font-size: VAR{\"font-size\", 12}rem;\n padding-left: 10rem\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "setVar(\"this\", \"height\", 0)\nvar lines = get(\"this\").split(/\\r|\\r\\n|\\n/);\nsetVar(\"this\", \"height\", (lines.length * getVar(\"this\", \"line-height\") + 6));\n\nsetVar(\"cur_play_index\", \"height\", getVar(\"this\", \"height\"))\nsetVar(\"cur_play_index_switch\", \"height\", getVar(\"this\", \"height\"))\n\nsetVar(\"start_play_index\", \"height\", getVar(\"this\", \"height\"))\nsetVar(\"start_play_index_switch\", \"height\", getVar(\"this\", \"height\"))\n\nsetVar(\"ledger_panel\", \"height\", getVar(\"this\", \"height\"))\n\nsetVar(\"ref_uid\", \"height\", getVar(\"this\", \"height\"))\nsetVar(\"ref_uid_switch\", \"height\", getVar(\"this\", \"height\"))\n\nvar switchVals = lines.map((element, index) => element.trim().replace(',',''))\nvar switchIndices = lines.map((element, index) => index - 1)\nset(\"ledger_switch_vals\", switchVals)\nset(\"ledger_switch_indices\", switchIndices)" + }, + { + "type": "switch", + "top": 0, + "left": 0, + "lock": false, + "id": "ref_uid", + "visible": true, + "interaction": true, + "comments": "", + "width": 20, + "height": "VAR{\"height\", 100}", + "expand": "false", + "colorText": "rgba(216,222,233,1)", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": 2, + "html": "", + "css": ":host {\n font-size: 0\n}", + "colorTextOn": "auto", + "layout": "vertical", + "gridTemplate": "", + "wrap": false, + "values": "@{ledger_switch_vals}", + "mode": "tap", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "switch", + "top": 0, + "left": 0, + "lock": false, + "id": "ref_uid_switch", + "visible": true, + "interaction": true, + "comments": "", + "width": 20, + "height": "VAR{\"height\", 100}", + "expand": "false", + "colorText": "rgba(216,222,233,1)", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": 2, + "html": "", + "css": ":host {\n font-size: 0\n}", + "colorTextOn": "auto", + "layout": "vertical", + "gridTemplate": "", + "wrap": false, + "values": "@{ledger_switch_vals}", + "mode": "tap", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "if(value === get(\"ref_uid\")){\n set(\"ref_uid\", \"\")\n} else {\n set(\"ref_uid\", value)\n}\nset(\"this\", \"\")" + }, + { + "type": "switch", + "top": 0, + "left": 20, + "lock": false, + "id": "start_play_index", + "visible": true, + "interaction": true, + "comments": "", + "width": 20, + "height": "VAR{\"height\", 100}", + "expand": "false", + "colorText": "rgba(216,222,233,1)", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": 2, + "html": "", + "css": ":host {\n font-size: 0\n}", + "colorTextOn": "auto", + "layout": "vertical", + "gridTemplate": "", + "wrap": false, + "values": "@{ledger_switch_indices}", + "mode": "click", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "switch", + "top": 0, + "left": 20, + "lock": false, + "id": "start_play_index_switch", + "visible": true, + "interaction": true, + "comments": "", + "width": 20, + "height": "VAR{\"height\", 100}", + "expand": "false", + "colorText": "rgba(216,222,233,1)", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": 2, + "html": "", + "css": ":host {\n font-size: 0\n}", + "colorTextOn": "auto", + "layout": "vertical", + "gridTemplate": "", + "wrap": false, + "values": "@{ledger_switch_indices}", + "mode": "click", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "if(value === get(\"start_play_index\")){\n set(\"start_play_index\", \"\")\n} else {\n set(\"start_play_index\", value)\n}\nset(\"this\", \"\")" + }, + { + "type": "switch", + "top": 0, + "left": 130, + "lock": false, + "id": "cur_play_index", + "visible": true, + "comments": "", + "width": 20, + "height": "VAR{\"height\", 100}", + "expand": "false", + "colorText": "rgba(216,222,233,1)", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": 2, + "html": "", + "css": ":host {\n font-size: 0\n}", + "wrap": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorTextOn": "auto", + "mode": "click", + "typeTags": "", + "ignoreDefaults": false, + "bypass": false, + "layout": "vertical", + "gridTemplate": "", + "values": "@{ledger_switch_indices}" + }, + { + "type": "switch", + "top": 0, + "left": 130, + "lock": false, + "id": "cur_play_index_switch", + "visible": true, + "comments": "", + "width": 20, + "height": "VAR{\"height\", 100}", + "expand": "false", + "colorText": "rgba(216,222,233,1)", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": 2, + "html": "", + "css": ":host {\n font-size: 0\n}", + "wrap": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "locals.last = \"\"", + "onValue": "if(value === get(\"cur_play_index\")){\n set(\"cur_play_index\", \"\")\n} else {\n set(\"cur_play_index\", value)\n}\nset(\"this\", \"\")", + "interaction": true, + "colorTextOn": "auto", + "mode": "tap", + "typeTags": "", + "ignoreDefaults": false, + "bypass": false, + "layout": "vertical", + "gridTemplate": "", + "values": "@{ledger_switch_indices}" + } + ], + "tabs": [], + "tabsPosition": "top" + }, + { + "type": "button", + "top": 0, + "left": 0, + "lock": false, + "id": "ref_uid_lock", + "visible": true, + "comments": "", + "width": 20, + "height": 20.727272727272727, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorTextOn": "auto", + "label": "L", + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": true + }, + { + "type": "variable", + "lock": false, + "id": "current_uid", + "comments": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "", + "typeTags": "s", + "ignoreDefaults": false, + "bypass": true + } + ], + "tabs": [], + "tabsPosition": "top" + }, + { + "type": "file", + "top": 50, + "left": 90, + "lock": false, + "id": "save_ledger", + "visible": true, + "interaction": true, + "comments": "", + "width": 70, + "height": 30.000000000000004, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "value": "save", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "set(\"this\", \"save\", {send:false})", + "align": "center", + "hidePath": true, + "mode": "open", + "directory": "Sketches/seeds_and_ledgers/resources", + "extension": "*", + "allowDir": false + }, + { + "type": "button", + "top": 90, + "left": 10, + "lock": false, + "id": "transport", + "visible": true, + "interaction": true, + "comments": "", + "width": 150, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorTextOn": "auto", + "label": "#{@{this} == 0 ? \"play\" : \"stop\"}", + "vertical": false, + "wrap": false, + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 0, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "if(value === 1){\n send(false, \"/transport\", 1, get(\"start_play_index\"));\n} else {\n send(false, \"/transport\", 0, get(\"start_play_index\"));\n}" + } + ], + "tabs": [], + "tabsPosition": "top" + }, + { + "type": "panel", + "top": 10, + "left": 30, + "lock": false, + "id": "seeds_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": 550, + "height": 640, + "expand": false, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "text", + "top": 10, + "left": 10, + "lock": false, + "id": "seeds_label", + "visible": true, + "comments": "", + "width": 80, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "value": "seeds", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "vertical": false, + "wrap": false, + "align": "center" + }, + { + "type": "panel", + "top": 90, + "left": 10, + "lock": false, + "id": "seeds_tab_panel", + "visible": true, + "comments": "", + "width": "96.3%", + "height": "84.13%", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": 0, + "html": "", + "css": "> inner > .navigation {\n height: 35rem;\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": true, + "widgets": [], + "tabs": [ + { + "type": "tab", + "lock": false, + "id": "instrumentation", + "visible": true, + "interaction": true, + "comments": "", + "colorText": "auto", + "colorWidget": "auto", + "colorFill": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "label": "auto", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "textarea", + "top": 270, + "left": 290, + "lock": false, + "id": "order", + "visible": true, + "interaction": true, + "comments": "", + "width": "41.18%", + "height": "41.24%", + "expand": false, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "textarea {\n white-space: pre;\n line-height: 1.5;\n font-size: 12px;\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "s", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "button", + "top": 270, + "left": 480, + "lock": false, + "id": "order_lock", + "visible": true, + "comments": "", + "width": 20, + "height": 20, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorTextOn": "auto", + "label": "L", + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": false + }, + { + "type": "panel", + "top": 190, + "left": 290, + "lock": false, + "id": "order_size", + "visible": true, + "comments": "", + "width": 210, + "height": 40, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": false, + "widgets": [ + { + "type": "range", + "top": 0, + "left": 40, + "lock": false, + "id": "@{parent.id}_rslider", + "visible": true, + "interaction": true, + "comments": "", + "width": 120, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "design": "default", + "knobSize": "auto", + "horizontal": true, + "pips": false, + "dashed": false, + "gradient": [], + "snap": true, + "spring": false, + "doubleTap": false, + "range": { + "min": 1, + "max": 10 + }, + "logScale": false, + "sensitivity": 1, + "steps": 10, + "value": "[@{@{parent.id}_input_min.value}, @{@{parent.id}_input_max.value}]", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "i", + "decimals": 0, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "onTouch": "" + }, + { + "type": "input", + "top": 0, + "left": 160, + "lock": false, + "id": "@{parent.id}_input_max", + "visible": true, + "comments": "", + "width": 40, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "@{@{parent.id}_rslider.value.1}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "typeTags": "i", + "ignoreDefaults": false, + "bypass": false + }, + { + "type": "input", + "top": 0, + "left": 0, + "lock": false, + "id": "@{parent.id}_input_min", + "visible": true, + "comments": "", + "width": 40, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "@{@{parent.id}_rslider.value.0}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "typeTags": "i", + "ignoreDefaults": false, + "bypass": false + } + ], + "tabs": [], + "tabsPosition": "top" + }, + { + "type": "panel", + "top": 230, + "left": 290, + "lock": false, + "id": "passages_size", + "visible": true, + "interaction": true, + "comments": "", + "width": 210, + "height": 40, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "range", + "top": 0, + "left": 40, + "lock": false, + "id": "@{parent.id}_rslider", + "visible": true, + "interaction": true, + "comments": "", + "width": 120, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "design": "default", + "knobSize": "auto", + "horizontal": true, + "pips": false, + "dashed": false, + "gradient": [], + "snap": true, + "spring": false, + "doubleTap": false, + "range": { + "min": 0, + "max": 10 + }, + "logScale": false, + "sensitivity": 1, + "steps": 11, + "value": "[@{@{parent.id}_input_min.value}, @{@{parent.id}_input_max.value}]", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "i", + "decimals": 0, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "onTouch": "" + }, + { + "type": "input", + "top": 0, + "left": 160, + "lock": false, + "id": "@{parent.id}_input_max", + "visible": true, + "comments": "", + "width": 40, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "@{@{parent.id}_rslider.value.1}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "typeTags": "", + "ignoreDefaults": false, + "bypass": false + }, + { + "type": "input", + "top": 0, + "left": 0, + "lock": false, + "id": "@{parent.id}_input_min", + "visible": true, + "comments": "", + "width": 40, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "@{@{parent.id}_rslider.value.0}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "set(\"passages_size\", [value, get(\"passages_size_v2\")])", + "interaction": true, + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "typeTags": "", + "ignoreDefaults": false, + "bypass": false + } + ], + "tabs": [], + "tabsPosition": "top" + }, + { + "type": "matrix", + "top": 10, + "left": 290, + "lock": false, + "id": "sus_weights", + "visible": true, + "interaction": true, + "comments": "", + "width": "41.18%", + "height": "37.11%", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "horizontal", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "widgetType": "fragment", + "quantity": 3, + "props": "{\n \"file\": \"fragments/slider.json\",\n \"props\": {\n \"variables\": #{{\n \"n\": $, \"slider_label\": [\"1\", \"2\", \"3\"][$], \n \"min\": 0.0, \"max\": 1.0\n }}\n }\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [], + "tabs": [], + "tabsPosition": "top" + }, + { + "type": "matrix", + "top": 10, + "left": 10, + "lock": false, + "id": "range_matrix", + "visible": true, + "interaction": true, + "comments": "", + "width": "52%", + "height": "95.24%", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "horizontal", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "widgetType": "fragment", + "quantity": 4, + "props": "{\n \"file\": \"fragments/range_slider.json\",\n \"props\": {\n \"variables\": #{{\n \"n\": $, \"min\": -1200, \"max\": 2400, \n \"rslider_label\": [\"IV\", \"III\", \"II\", \"I\"][$], \n \"decimals\": 0\n }\n }}\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [], + "tabs": [], + "tabsPosition": "top" + } + ], + "tabs": [], + "tabsPosition": "top" + }, + { + "type": "tab", + "lock": false, + "id": "durations", + "visible": true, + "interaction": true, + "comments": "", + "colorText": "auto", + "colorWidget": "auto", + "colorFill": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": false, + "label": "auto", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "panel", + "top": 0, + "left": 0, + "lock": false, + "id": "dur_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": "100%", + "height": "100%", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "> inner > .navigation {\n height: 30rem;\n}", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [], + "tabs": [ + { + "type": "tab", + "lock": false, + "id": "entrances", + "visible": true, + "interaction": true, + "comments": "", + "colorText": "auto", + "colorWidget": "auto", + "colorFill": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "label": "auto", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "fragment", + "top": 50, + "left": 10, + "lock": false, + "id": "entrances", + "visible": true, + "interaction": true, + "comments": "", + "width": "96.46%", + "height": "86.09%", + "expand": "false", + "css": "", + "file": "fragments/dur_probs_panel.json", + "fallback": "", + "props": {}, + "address": "auto", + "variables": "@{parent.variables}" + }, + { + "type": "switch", + "top": 10, + "left": 10, + "lock": false, + "id": "entrances_probs_sync", + "visible": true, + "interaction": true, + "comments": "", + "width": 490, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorTextOn": "auto", + "layout": "horizontal", + "gridTemplate": "", + "wrap": false, + "values": { + "sync to entrances": "entrances", + "sync to passages": "passages", + "sync to exits": "exits" + }, + "mode": "tap", + "value": "", + "default": "entrances", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "set(\"@{parent.id}_probs_vals\", get(value + \"_probs_vals\"))" + } + ], + "tabs": [], + "tabsPosition": "top" + }, + { + "type": "tab", + "lock": false, + "id": "passages", + "visible": true, + "interaction": true, + "comments": "", + "colorText": "auto", + "colorWidget": "auto", + "colorFill": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "label": "auto", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "fragment", + "top": 50, + "left": 10, + "lock": false, + "id": "passages", + "visible": true, + "interaction": true, + "comments": "", + "width": "96.46%", + "height": "86.09%", + "expand": "false", + "css": "", + "file": "fragments/dur_probs_panel.json", + "fallback": "", + "props": {}, + "address": "auto", + "variables": "@{parent.variables}" + }, + { + "type": "switch", + "top": 10, + "left": 10, + "lock": false, + "id": "passages_probs_sync", + "visible": true, + "interaction": true, + "comments": "", + "width": 490, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorTextOn": "auto", + "layout": "horizontal", + "gridTemplate": "", + "wrap": false, + "values": { + "sync to entrances": "entrances", + "sync to passages": "passages", + "sync to exits": "exits" + }, + "mode": "tap", + "value": "", + "default": "passages", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "set(\"@{parent.id}_probs_vals\", get(value + \"_probs_vals\"))" + } + ], + "tabs": [], + "tabsPosition": "top" + }, + { + "type": "tab", + "lock": false, + "id": "exits", + "visible": true, + "interaction": true, + "comments": "", + "colorText": "auto", + "colorWidget": "auto", + "colorFill": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "label": "auto", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "fragment", + "top": 50, + "left": 10, + "lock": false, + "id": "exits", + "visible": true, + "interaction": true, + "comments": "", + "width": "96.46%", + "height": "86.09%", + "expand": "false", + "css": "", + "file": "fragments/dur_probs_panel.json", + "fallback": "", + "props": {}, + "address": "auto", + "variables": "@{parent.variables}" + }, + { + "type": "switch", + "top": 10, + "left": 10, + "lock": false, + "id": "exits_probs_sync", + "visible": true, + "interaction": true, + "comments": "", + "width": 490, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorTextOn": "auto", + "layout": "horizontal", + "gridTemplate": "", + "wrap": false, + "values": { + "sync to entrances": "entrances", + "sync to passages": "passages", + "sync to exits": "exits" + }, + "mode": "tap", + "value": "", + "default": "exits", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "set(\"@{parent.id}_probs_vals\", get(value + \"_probs_vals\"))" + } + ], + "tabs": [], + "tabsPosition": "top" + } + ], + "tabsPosition": "top" + } + ], + "tabs": [], + "tabsPosition": "top" + }, + { + "type": "tab", + "lock": false, + "id": "weights", + "visible": true, + "interaction": true, + "comments": "", + "colorText": "auto", + "colorWidget": "auto", + "colorFill": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": false, + "label": "melody weights", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "fragment", + "top": 10, + "left": 10, + "lock": false, + "id": "step_env", + "visible": true, + "interaction": true, + "comments": "", + "width": "96.53%", + "height": 260, + "expand": "false", + "css": "", + "file": "fragments/env.json", + "fallback": "", + "props": {}, + "address": "auto", + "variables": "@{parent.variables}" + }, + { + "type": "matrix", + "top": 280, + "left": 10, + "lock": false, + "id": "passages_weights", + "visible": true, + "interaction": true, + "comments": "", + "width": "96.53%", + "height": "40.57%", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "horizontal", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "widgetType": "fragment", + "quantity": 5, + "props": "{\n \"file\": \"fragments/slider.json\",\n \"props\": {\n \"variables\": #{{\n \"n\": $, \"slider_label\": [\"step\", \"dc\", \"range\", \"registration\", \"hd\"][$], \n \"min\": 0, \"max\": 1\n }}\n }\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [], + "tabs": [], + "tabsPosition": "top" + } + ], + "tabs": [], + "tabsPosition": "top" + } + ], + "tabsPosition": "top" + }, + { + "type": "button", + "top": 50, + "left": 130, + "lock": false, + "id": "order_seed_lock", + "visible": true, + "comments": "", + "width": 30.000000000000004, + "height": 30.000000000000004, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorTextOn": "auto", + "label": "L", + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": true + }, + { + "type": "input", + "top": 50, + "left": 50, + "lock": false, + "id": "order_seed", + "visible": true, + "interaction": true, + "comments": "", + "width": 80, + "height": 30.000000000000004, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "button", + "top": 50, + "left": 300, + "lock": false, + "id": "dur_seed_lock", + "visible": true, + "comments": "", + "width": 29.999999999999996, + "height": 29.999999999999996, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorTextOn": "auto", + "label": "L", + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": true + }, + { + "type": "input", + "top": 50, + "left": 220, + "lock": false, + "id": "dur_seed", + "visible": true, + "interaction": true, + "comments": "", + "width": 80, + "height": 30.000000000000004, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "button", + "top": 50, + "left": 460, + "lock": false, + "id": "weights_seed_lock", + "visible": true, + "comments": "", + "width": 29.999999999999996, + "height": 29.999999999999996, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorTextOn": "auto", + "label": "L", + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": true + }, + { + "type": "input", + "top": 50, + "left": 380, + "lock": false, + "id": "weights_seed", + "visible": true, + "interaction": true, + "comments": "", + "width": 80, + "height": 30.000000000000004, + "expand": false, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "button", + "top": 10, + "left": 100, + "lock": false, + "id": "generate", + "visible": true, + "interaction": true, + "comments": "", + "width": 90, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorTextOn": "auto", + "label": "generate", + "vertical": false, + "wrap": false, + "on": 1, + "off": 0, + "mode": "push", + "doubleTap": false, + "decoupled": false, + "value": "", + "default": 0, + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "if(value === 0){\n var minSeed = 100000\n var maxSeed = 999999\n \n if(get(\"dur_seed_lock\") === 0){\n set(\"dur_seed\", Math.floor(Math.random() * (maxSeed - minSeed) + minSeed))\n }\n \n if(get(\"order_seed_lock\") === 0){\n set(\"order_seed\", Math.floor(Math.random() * (maxSeed - minSeed) + minSeed))\n }\n \n if(get(\"weights_seed_lock\") === 0){\n set(\"weights_seed\", Math.floor(Math.random() * (maxSeed - minSeed) + minSeed))\n }\n \n set(\"entrances_probs_vals\", \"\")\n set(\"passages_probs_vals\", \"\")\n set(\"exits_probs_vals\", \"\")\n \n send('/generate', stateGet('root'), stateGet('ledger_panel'))\n\n}" + } + ], + "tabs": [], + "tabsPosition": "top" + } + ], + "tabs": [], + "tabsPosition": "top" + } +} \ No newline at end of file diff --git a/open_stage_control/seeds_and_ledgers_gui_bak.json b/open_stage_control/seeds_and_ledgers_gui_bak.json new file mode 100644 index 0000000..bb7088a --- /dev/null +++ b/open_stage_control/seeds_and_ledgers_gui_bak.json @@ -0,0 +1,2443 @@ +{ + "createdWith": "Open Stage Control", + "version": "1.22.0", + "type": "session", + "content": { + "type": "root", + "lock": false, + "id": "root", + "visible": true, + "interaction": true, + "comments": "", + "width": "auto", + "height": "auto", + "colorText": "auto", + "colorWidget": "auto", + "alphaFillOn": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "hideMenu": false, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "panel", + "top": 10, + "left": 770, + "lock": false, + "id": "motif_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": 560, + "height": 640, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "textarea", + "top": 40, + "left": 10, + "lock": false, + "id": "mus_seq", + "visible": true, + "comments": "", + "width": 530, + "height": 580, + "expand": false, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": 0, + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "textarea {\n white-space: pre;\n line-height: 20rem;\n font-size: 12rem;\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "//set(\"this\", JSON.stringify(JSON.parse(value), null, 5))", + "interaction": true, + "typeTags": "s", + "ignoreDefaults": false, + "bypass": false + }, + { + "type": "text", + "top": 10, + "left": 10, + "lock": false, + "id": "motif_label", + "visible": true, + "comments": "", + "width": 90, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "motif", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "vertical": false, + "wrap": false + } + ], + "tabs": [] + }, + { + "type": "panel", + "top": 10, + "left": 580, + "lock": false, + "id": "ledger_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": 190, + "height": 640, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": false, + "innerPadding": true, + "verticalTabs": false, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "text", + "top": 10, + "left": 10, + "lock": false, + "id": "ledger_label", + "visible": true, + "comments": "", + "width": 70, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "value": "ledger", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "vertical": false, + "wrap": false, + "align": "center" + }, + { + "type": "file", + "top": 10, + "left": 80, + "lock": false, + "id": "load_ledger", + "visible": true, + "interaction": true, + "comments": "", + "width": 80, + "height": 30.000000000000004, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "align": "center", + "hidePath": true, + "mode": "open", + "directory": "Sketches/seeds_and_ledgers/resources", + "extension": "*", + "allowDir": false + }, + { + "type": "panel", + "top": 50, + "left": 10, + "lock": false, + "id": "sequencer_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": 180, + "height": 600, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": 0, + "borderRadius": 0, + "padding": 0, + "html": "", + "css": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": false, + "innerPadding": true, + "verticalTabs": false, + "variables": "@{parent.variables}", + "traversing": false, + "widgets": [ + { + "type": "panel", + "top": 81, + "left": 0, + "lock": false, + "id": "ledger_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": 170, + "height": 480, + "expand": true, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": 0, + "borderRadius": 0, + "padding": 0, + "html": "", + "css": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": "auto", + "innerPadding": true, + "verticalTabs": false, + "variables": "@{parent.variables}", + "traversing": false, + "widgets": [ + { + "type": "switch", + "top": 0, + "left": 130, + "lock": false, + "id": "cur_play_uid", + "visible": true, + "comments": "", + "width": 20, + "height": "VAR{\"height\", 100}", + "expand": "false", + "colorText": "rgba(216,222,233,1)", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": 2, + "html": "", + "css": ":host {\n font-size: 0\n}", + "wrap": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorTextOn": "auto", + "mode": "tap", + "typeTags": "", + "ignoreDefaults": false, + "bypass": false, + "layout": "vertical", + "gridTemplate": "", + "values": "@{ledger_switch_vals}" + }, + { + "type": "variable", + "lock": false, + "id": "ledger_switch_vals", + "comments": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "variable", + "lock": false, + "id": "ledger_switch_indices", + "comments": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "variable", + "lock": false, + "id": "ledger_size", + "comments": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "/*\nvar array = Array(value + 2).fill().map((element, index) => index)\nconsole.log(array)\nset('ledger_switch_vals', array)\n*/" + }, + { + "type": "textarea", + "top": 0, + "left": 40, + "lock": false, + "id": "ledger", + "visible": true, + "interaction": true, + "comments": "", + "width": 90, + "height": "VAR{\"height\", 100}", + "expand": true, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "textarea {\n overflow-y: hidden;\n line-height: VAR{\"line-height\", 20}rem;\n font-size: VAR{\"font-size\", 12}rem;\n padding-left: 10rem\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "setVar(\"this\", \"height\", 0)\nvar lines = get(\"this\").split(/\\r|\\r\\n|\\n/);\nsetVar(\"this\", \"height\", (lines.length * getVar(\"this\", \"line-height\") + 6));\nsetVar(\"cur_play_uid\", \"height\", getVar(\"this\", \"height\"))\nsetVar(\"start_play\", \"height\", getVar(\"this\", \"height\"))\nsetVar(\"ledger_panel\", \"height\", getVar(\"this\", \"height\"))\nsetVar(\"ref_uid\", \"height\", getVar(\"this\", \"height\"))\nvar switchVals = lines.map((element, index) => element.trim().replace(',',''))\nvar switchIndices = lines.map((element, index) => index)\nset(\"ledger_switch_vals\", switchVals)\nset(\"ledger_switch_indices\", switchIndices)" + }, + { + "type": "switch", + "top": 0, + "left": 0, + "lock": false, + "id": "ref_uid", + "visible": true, + "interaction": true, + "comments": "", + "width": 20, + "height": "VAR{\"height\", 100}", + "expand": "false", + "colorText": "rgba(216,222,233,1)", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": 2, + "html": "", + "css": ":host {\n font-size: 0\n}", + "colorTextOn": "auto", + "layout": "vertical", + "gridTemplate": "", + "wrap": false, + "values": "@{ledger_switch_vals}", + "mode": "tap", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "console.log(get(\"ledger_switch_vals\"))\nconsole.log(value)" + }, + { + "type": "switch", + "top": 0, + "left": 20, + "lock": false, + "id": "start_play", + "visible": true, + "interaction": true, + "comments": "", + "width": 20, + "height": "VAR{\"height\", 100}", + "expand": "false", + "colorText": "rgba(216,222,233,1)", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": 2, + "html": "", + "css": ":host {\n font-size: 0\n}", + "colorTextOn": "auto", + "layout": "vertical", + "gridTemplate": "", + "wrap": false, + "values": "@{ledger_switch_indices}", + "mode": "tap", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + } + ], + "tabs": [] + }, + { + "type": "button", + "top": 60, + "left": 0, + "lock": false, + "id": "ref_uid_lock", + "visible": true, + "comments": "", + "width": 20, + "height": 20.727272727272727, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorTextOn": "auto", + "label": "L", + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": true + }, + { + "type": "input", + "top": 60, + "left": 40, + "lock": false, + "id": "current_uid", + "visible": true, + "comments": "", + "width": 90, + "height": 20, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "typeTags": "s", + "ignoreDefaults": false, + "bypass": true, + "unit": "", + "asYouType": true, + "numeric": true, + "validation": "", + "maxLength": "" + }, + { + "type": "button", + "top": 60, + "left": 130, + "lock": false, + "id": "current_uid_lock", + "visible": true, + "interaction": true, + "comments": "", + "width": 20, + "height": 20, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "colorTextOn": "auto", + "label": "L", + "vertical": false, + "wrap": false, + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false + }, + { + "type": "button", + "top": 30, + "left": 0, + "lock": false, + "id": "transport", + "visible": true, + "interaction": true, + "comments": "", + "width": 150, + "height": 20, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorTextOn": "auto", + "label": "#{@{this} == 0 ? \"play\" : \"stop\"}", + "vertical": false, + "wrap": false, + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 0, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "if(value === 1){\n console.log(get(\"start_play\"))\n send(false, \"/transport\", 1, get(\"start_play\") - 1);\n} else {\n send(false, \"/transport\", 0, get(\"start_play\") - 1);\n}" + }, + { + "type": "button", + "top": 0, + "left": 0, + "lock": false, + "id": "gen", + "visible": true, + "interaction": true, + "comments": "", + "width": 70, + "height": 20, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorTextOn": "auto", + "label": "generate", + "vertical": false, + "wrap": false, + "on": 1, + "off": 0, + "mode": "push", + "doubleTap": false, + "decoupled": false, + "value": "", + "default": 0, + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "if(value === 1){\n var sVal = 1\n var order = null\n var passage = null\n var rUID = get(\"ref_uid\")\n var durSeed;\n var orderSeed;\n var weightSeed\n \n if(get(\"ref_uid\")){\n rUID = get(\"ref_uid\")\n } else {\n rUID = 1\n }\n \n if(get(\"dur_seed_lock\") == 1){\n durSeed = get(\"dur_seed\")\n } else {\n durSeed = 1\n }\n \n if(get(\"order_seed_lock\") == 1){\n orderSeed = get(\"order_seed\")\n } else {\n orderSeed = 1\n }\n \n if(get(\"weights_seed_lock\") == 1){\n weightSeed = get(\"weights_seed\")\n } else {\n weightSeed = 1\n }\n \n /*\n if(get(\"order_lock\") == 1){\n order = get(\"order\").replace(/\\s/g, \"\")\n send(false, \"/gen\", rUID, durSeed, orderSeed, weightSeed, order)\n } else {\n order = get(\"order_size\")\n passage = get(\"passage_size\")\n send(false, \"/gen\", rUID, durSeed, orderSeed, weightSeed,\n {\"type\": \"i\", \"value\": order[0]}, \n {\"type\": \"i\", \"value\": order[1]}, \n {\"type\": \"i\", \"value\": passage[0]}, \n {\"type\": \"i\", \"value\": passage[1]});\n }\n */\n \n send('custom:module', '/gen', stateGet('root'))\n\n}" + }, + { + "type": "button", + "top": 0, + "left": 80, + "lock": false, + "id": "commit", + "visible": true, + "interaction": true, + "comments": "", + "width": 70, + "height": 20, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "value": "", + "default": 0, + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "if(value === 1){\n //send(false, \"/commit\");\n //set(\"reference_seed\", get(\"current_seed\"))\n //var lVals = get(\"ledger_switch_vals\")\n //if(get(\"ref_uid_lock\") === 0){\n // set(\"ref_uid\", lVals[lVals.length - 2])\n //}\n // set(\"current_uid\", \"\")\n send('custom:module', 'commit', get(\"current_uid\"), stateGet('root'), stateGet('ledger_panel'))\n}\n ", + "colorTextOn": "auto", + "label": "auto", + "vertical": false, + "wrap": false, + "on": 1, + "off": 0, + "mode": "push", + "doubleTap": false, + "decoupled": false + } + ], + "tabs": [] + } + ], + "tabs": [] + }, + { + "type": "panel", + "top": 10, + "left": 30, + "lock": false, + "id": "seeds_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": 550, + "height": 640, + "expand": false, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "text", + "top": 10, + "left": 10, + "lock": false, + "id": "seeds_label", + "visible": true, + "comments": "", + "width": 80, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "value": "seeds", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "vertical": false, + "wrap": false, + "align": "center" + }, + { + "type": "panel", + "top": 90, + "left": 10, + "lock": false, + "id": "seeds_tab_panel", + "visible": true, + "comments": "", + "width": "96.3%", + "height": "84.13%", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": 0, + "html": "", + "css": "> inner > .navigation {\n height: 35rem;\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "variables": "@{parent.variables}", + "traversing": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": true, + "widgets": [], + "tabs": [ + { + "type": "tab", + "lock": false, + "id": "instrumentation", + "visible": true, + "interaction": true, + "comments": "", + "colorText": "auto", + "colorWidget": "auto", + "colorFill": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "label": "auto", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "textarea", + "top": 270, + "left": 290, + "lock": false, + "id": "order", + "visible": true, + "interaction": true, + "comments": "", + "width": "41.18%", + "height": "41.24%", + "expand": false, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "textarea {\n white-space: pre;\n line-height: 1.5;\n font-size: 12px;\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "s", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "button", + "top": 270, + "left": 480, + "lock": false, + "id": "order_lock", + "visible": true, + "comments": "", + "width": 20, + "height": 20, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorTextOn": "auto", + "label": "L", + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": false + }, + { + "type": "panel", + "top": 190, + "left": 290, + "lock": false, + "id": "order_size_panel", + "visible": true, + "comments": "", + "width": 210, + "height": 40, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "variables": "@{parent.variables}", + "traversing": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": false, + "widgets": [ + { + "type": "range", + "top": 0, + "left": 40, + "lock": false, + "id": "order_size", + "visible": true, + "interaction": true, + "comments": "", + "width": 120, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "design": "default", + "knobSize": "auto", + "horizontal": true, + "pips": false, + "dashed": false, + "gradient": [], + "snap": true, + "spring": false, + "doubleTap": false, + "range": { + "min": 1, + "max": 10 + }, + "logScale": false, + "sensitivity": 1, + "steps": 10, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "i", + "decimals": 0, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "onTouch": "" + }, + { + "type": "input", + "top": 0, + "left": 160, + "lock": false, + "id": "order_size_v2", + "visible": true, + "comments": "", + "width": 40, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "@{order_size.value.1}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "set(\"order_size\", [get(\"order_size_v1\"), value])", + "interaction": true, + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "typeTags": "i", + "ignoreDefaults": false, + "bypass": false + }, + { + "type": "input", + "top": 0, + "left": 0, + "lock": false, + "id": "order_size_v1", + "visible": true, + "comments": "", + "width": 40, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "@{order_size.value.0}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "set(\"order_size\", [value, get(\"order_size_v2\")])", + "interaction": true, + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "typeTags": "i", + "ignoreDefaults": false, + "bypass": false + } + ], + "tabs": [] + }, + { + "type": "panel", + "top": 230, + "left": 290, + "lock": false, + "id": "passage_size_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": 210, + "height": 40, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "range", + "top": 0, + "left": 40, + "lock": false, + "id": "passage_size", + "visible": true, + "interaction": true, + "comments": "", + "width": 120, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "design": "default", + "knobSize": "auto", + "horizontal": true, + "pips": false, + "dashed": false, + "gradient": [], + "snap": true, + "spring": false, + "doubleTap": false, + "range": { + "min": 0, + "max": 10 + }, + "logScale": false, + "sensitivity": 1, + "steps": 11, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 0, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "onTouch": "" + }, + { + "type": "input", + "top": 0, + "left": 160, + "lock": false, + "id": "passage_size_v2", + "visible": true, + "comments": "", + "width": 40, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "@{passage_size.value.1}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "set(\"passage_size\", [get(\"passage_size_v1\"), value])", + "interaction": true, + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "typeTags": "", + "ignoreDefaults": false, + "bypass": false + }, + { + "type": "input", + "top": 0, + "left": 0, + "lock": false, + "id": "passage_size_v1", + "visible": true, + "comments": "", + "width": 40, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "@{passage_size.value.0}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "set(\"passage_size\", [value, get(\"passage_size_v2\")])", + "interaction": true, + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "typeTags": "", + "ignoreDefaults": false, + "bypass": false + } + ], + "tabs": [] + }, + { + "type": "matrix", + "top": 10, + "left": 290, + "lock": false, + "id": "sus_weights", + "visible": true, + "interaction": true, + "comments": "", + "width": "41.18%", + "height": "37.11%", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "horizontal", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "widgetType": "fragment", + "quantity": 3, + "props": "{\n \"file\": \"fragments/slider.json\",\n \"props\": {\n \"variables\": #{{\n \"n\": $, \"name\": [\"1\", \"2\", \"3\"][$], \n \"min\": -1200, \"max\": 2400,\n \"address\": \"/sus_weights\"\n }}\n }\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "console.log(\"test\")", + "widgets": [], + "tabs": [] + }, + { + "type": "matrix", + "top": 10, + "left": 10, + "lock": false, + "id": "range_matrix", + "visible": true, + "interaction": true, + "comments": "", + "width": "52%", + "height": "95.24%", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "horizontal", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "widgetType": "fragment", + "quantity": 4, + "props": "{\n \"file\": \"fragments/range_slider_responsive_2.json\",\n \"props\": {\n \"variables\": {\n \"n\": #{$}, \"min\": -1200, \"max\": 2400, \"address\": \"/range\"\n }\n }\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [], + "tabs": [] + } + ], + "tabs": [] + }, + { + "type": "tab", + "lock": false, + "id": "durations", + "visible": true, + "interaction": true, + "comments": "", + "colorText": "auto", + "colorWidget": "auto", + "colorFill": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": false, + "verticalTabs": false, + "label": "auto", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "panel", + "top": 0, + "left": 0, + "lock": false, + "id": "dur_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": "100%", + "height": "100%", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "> inner > .navigation {\n height: 30rem;\n}", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [], + "tabs": [ + { + "type": "tab", + "lock": false, + "id": "entrances", + "visible": true, + "interaction": true, + "comments": "", + "colorText": "auto", + "colorWidget": "auto", + "colorFill": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "label": "auto", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "fragment", + "top": 50, + "left": 10, + "lock": false, + "id": "entrances", + "visible": true, + "interaction": true, + "comments": "", + "width": "96.46%", + "height": "86.09%", + "expand": "false", + "css": "", + "file": "fragments/env_durs_frags.json", + "fallback": "", + "props": {}, + "address": "auto", + "variables": "@{parent.variables}" + }, + { + "type": "switch", + "top": 10, + "left": 10, + "lock": false, + "id": "entrances_probs_sync", + "visible": true, + "interaction": true, + "comments": "", + "width": 490, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorTextOn": "auto", + "layout": "horizontal", + "gridTemplate": "", + "wrap": false, + "values": { + "sync to entrances": "entrances", + "sync to passages": "passages", + "sync to exits": "exits" + }, + "mode": "tap", + "value": "", + "default": "passages", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "set(\"@{parent.id}_probs_vals\", get(value + \"_probs_vals\"))" + } + ], + "tabs": [] + }, + { + "type": "tab", + "lock": false, + "id": "passages", + "visible": true, + "interaction": true, + "comments": "", + "colorText": "auto", + "colorWidget": "auto", + "colorFill": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "label": "auto", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "fragment", + "top": 50, + "left": 10, + "lock": false, + "id": "passages", + "visible": true, + "interaction": true, + "comments": "", + "width": "96.46%", + "height": "86.09%", + "expand": "false", + "css": "", + "file": "fragments/env_durs_frags.json", + "fallback": "", + "props": {}, + "address": "auto", + "variables": "@{parent.variables}" + }, + { + "type": "switch", + "top": 10, + "left": 10, + "lock": false, + "id": "passages_probs_sync", + "visible": true, + "interaction": true, + "comments": "", + "width": 490, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorTextOn": "auto", + "layout": "horizontal", + "gridTemplate": "", + "wrap": false, + "values": { + "sync to entrances": "entrances", + "sync to passages": "passages", + "sync to exits": "exits" + }, + "mode": "tap", + "value": "", + "default": "passages", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "set(\"@{parent.id}_probs_vals\", get(value + \"_probs_vals\"))" + } + ], + "tabs": [] + }, + { + "type": "tab", + "lock": false, + "id": "exits", + "visible": true, + "interaction": true, + "comments": "", + "colorText": "auto", + "colorWidget": "auto", + "colorFill": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "label": "auto", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "fragment", + "top": 50, + "left": 10, + "lock": false, + "id": "exits", + "visible": true, + "interaction": true, + "comments": "", + "width": "96.46%", + "height": "86.09%", + "expand": "false", + "css": "", + "file": "fragments/env_durs_frags.json", + "fallback": "", + "props": {}, + "address": "auto", + "variables": "@{parent.variables}" + }, + { + "type": "switch", + "top": 10, + "left": 10, + "lock": false, + "id": "exits_probs_sync", + "visible": true, + "interaction": true, + "comments": "", + "width": 490, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorTextOn": "auto", + "layout": "horizontal", + "gridTemplate": "", + "wrap": false, + "values": { + "sync to entrances": "entrances", + "sync to passages": "passages", + "sync to exits": "exits" + }, + "mode": "tap", + "value": "", + "default": "passages", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "set(\"@{parent.id}_probs_vals\", get(value + \"_probs_vals\"))" + } + ], + "tabs": [] + } + ], + "verticalTabs": false + } + ], + "tabs": [] + }, + { + "type": "tab", + "lock": false, + "id": "weights", + "visible": true, + "interaction": true, + "comments": "", + "colorText": "auto", + "colorWidget": "auto", + "colorFill": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": false, + "verticalTabs": false, + "label": "melody weights", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "fragment", + "top": 10, + "left": 10, + "lock": false, + "id": "step_env", + "visible": true, + "interaction": true, + "comments": "", + "width": "96.53%", + "height": 260, + "expand": "false", + "css": "", + "file": "fragments/env.json", + "fallback": "", + "props": {}, + "address": "auto", + "variables": "@{parent.variables}" + }, + { + "type": "matrix", + "top": 280, + "left": 10, + "lock": false, + "id": "passages_weights", + "visible": true, + "interaction": true, + "comments": "", + "width": "96.53%", + "height": "40.57%", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "horizontal", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "widgetType": "fragment", + "quantity": 5, + "props": "{\n \"file\": \"fragments/slider.json\",\n \"props\": {\n \"variables\": #{{\n \"n\": $, \"name\": [\"step\", \"dc\", \"range\", \"registration\", \"hd\"][$], \n \"min\": -1200, \"max\": 2400,\n \"address\": \"/passages_weights\"\n }}\n }\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [], + "tabs": [] + }, + { + "type": "variable", + "lock": false, + "id": "passage_weights/2_val_share", + "comments": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "console.log(value)" + } + ], + "tabs": [] + } + ] + }, + { + "type": "input", + "top": 50, + "left": 50, + "lock": false, + "id": "order_seed", + "visible": true, + "interaction": true, + "comments": "", + "width": 80, + "height": 30.000000000000004, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "button", + "top": 50, + "left": 130, + "lock": false, + "id": "dur_seed_lock", + "visible": true, + "comments": "", + "width": 30.000000000000004, + "height": 30.000000000000004, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorTextOn": "auto", + "label": "L", + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": true + }, + { + "type": "button", + "top": 50, + "left": 300, + "lock": false, + "id": "order_seed_lock", + "visible": true, + "comments": "", + "width": 29.999999999999996, + "height": 29.999999999999996, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorTextOn": "auto", + "label": "L", + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": true + }, + { + "type": "input", + "top": 50, + "left": 220, + "lock": false, + "id": "dur_seed", + "visible": true, + "interaction": true, + "comments": "", + "width": 80, + "height": 30.000000000000004, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "button", + "top": 50, + "left": 460, + "lock": false, + "id": "weights_seed_lock", + "visible": true, + "comments": "", + "width": 29.999999999999996, + "height": 29.999999999999996, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorTextOn": "auto", + "label": "L", + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": true + }, + { + "type": "input", + "top": 50, + "left": 380, + "lock": false, + "id": "weights_seed", + "visible": true, + "interaction": true, + "comments": "", + "width": 80, + "height": 30.000000000000004, + "expand": false, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + } + ], + "tabs": [] + } + ], + "tabs": [] + } +} \ No newline at end of file diff --git a/resources/314491/314491_code.scd b/resources/314491/314491_code.scd new file mode 100644 index 0000000..2d77a32 --- /dev/null +++ b/resources/314491/314491_code.scd @@ -0,0 +1,581 @@ +( +// 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/314491/314491_gui_session.json b/resources/314491/314491_gui_session.json new file mode 100644 index 0000000..f0b1a0e --- /dev/null +++ b/resources/314491/314491_gui_session.json @@ -0,0 +1,1400 @@ +{ + "createdWith": "Open Stage Control", + "version": "1.22.0", + "type": "session", + "content": { + "type": "root", + "lock": false, + "id": "root", + "visible": true, + "interaction": true, + "comments": "", + "width": "auto", + "height": "auto", + "colorText": "auto", + "colorWidget": "auto", + "alphaFillOn": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "hideMenu": false, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "button", + "top": 460, + "left": 470, + "lock": false, + "id": "transport", + "visible": true, + "interaction": true, + "comments": "", + "width": 110, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorTextOn": "auto", + "label": "#{@{this} == 0 ? \"play\" : \"stop\"}", + "vertical": false, + "wrap": false, + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 0, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "if(value === 1){\n send(false, \"/transport\", 1, get(\"m_size\"));\n} else {\n send(false, \"/transport\", 0, get(\"m_size\"));\n}" + }, + { + "type": "button", + "top": 20, + "left": 470, + "lock": false, + "id": "gen", + "visible": true, + "interaction": true, + "comments": "", + "width": 290, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorTextOn": "auto", + "label": "generate", + "vertical": false, + "wrap": false, + "on": 1, + "off": 0, + "mode": "push", + "doubleTap": false, + "decoupled": false, + "value": "", + "default": 0, + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "if(value === 1){\n var sVal = 1\n var order = null\n var passage = null\n var rVal = get(\"reference_seed\")\n \n if(get(\"current_seed_lock\") == 1){\n sVal = get(\"seed\")\n } else {\n sVal = 1\n }\n \n if(get(\"order_lock\") == 1){\n order = get(\"order\").replace(/\\s/g, \"\")\n send(false, \"/gen\", rVal, sVal, order)\n } else {\n order = get(\"order_size\")\n passage = get(\"passage_size\")\n send(false, \"/gen\", rVal, sVal, \n {\"type\": \"i\", \"value\": order[0]}, \n {\"type\": \"i\", \"value\": order[1]}, \n {\"type\": \"i\", \"value\": passage[0]}, \n {\"type\": \"i\", \"value\": passage[1]});\n }\n\n}" + }, + { + "type": "matrix", + "top": 60, + "left": 120, + "lock": false, + "id": "range_matrix", + "visible": true, + "interaction": true, + "comments": "", + "width": 330, + "height": 260, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "horizontal", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "widgetType": "fragment", + "quantity": 4, + "props": "{\n \"file\": \"range_slider.json\",\n \"props\": {\"variables\": {\"n\": #{$} }}\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "widgets": [], + "tabs": [] + }, + { + "type": "input", + "top": 110, + "left": 590, + "lock": false, + "id": "current_seed", + "visible": true, + "interaction": true, + "comments": "", + "width": 130, + "height": "auto", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 0, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "", + "align": "center", + "unit": "", + "asYouType": true, + "numeric": true, + "validation": "", + "maxLength": "" + }, + { + "type": "button", + "top": 110, + "left": 730, + "lock": false, + "id": "current_seed_lock", + "visible": true, + "interaction": true, + "comments": "", + "width": 30, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorTextOn": "auto", + "label": "L", + "vertical": false, + "wrap": false, + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "" + }, + { + "type": "button", + "top": 500, + "left": 470, + "lock": false, + "id": "commit", + "visible": true, + "interaction": true, + "comments": "", + "width": 110, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "value": "", + "default": 0, + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": true, + "onCreate": "", + "onValue": "if(value === 1){\n send(false, \"/commit\");\n set(\"reference_seed\", get(\"current_seed\"))\n set(\"current_seed\", \"\")\n}\n ", + "colorTextOn": "auto", + "label": "auto", + "vertical": false, + "wrap": false, + "on": 1, + "off": 0, + "mode": "push", + "doubleTap": false, + "decoupled": false + }, + { + "type": "textarea", + "top": 290, + "left": 470, + "lock": false, + "id": "order", + "visible": true, + "interaction": true, + "comments": "", + "width": 250, + "height": 140, + "expand": false, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "textarea {\n white-space: pre;\n line-height: 1.5;\n font-size: 12px;\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "s", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "button", + "top": 400, + "left": 730, + "lock": false, + "id": "order_lock", + "visible": true, + "comments": "", + "width": 30, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorTextOn": "auto", + "label": "L", + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": false + }, + { + "type": "text", + "top": 110, + "left": 470, + "lock": false, + "id": "current_seed_label", + "visible": true, + "comments": "", + "width": 110, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "current seed", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "vertical": false, + "wrap": false + }, + { + "type": "input", + "top": 60, + "left": 590, + "lock": false, + "id": "reference_seed", + "visible": true, + "comments": "", + "width": 130, + "height": "auto", + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "", + "default": "nil", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "unit": "", + "asYouType": true, + "numeric": true, + "validation": "", + "maxLength": "", + "typeTags": "", + "ignoreDefaults": false, + "bypass": true + }, + { + "type": "text", + "top": 60, + "left": 470, + "lock": false, + "id": "reference_seed_label", + "visible": true, + "comments": "", + "width": 110, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "value": "reference seed", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "align": "center" + }, + { + "type": "button", + "top": 60, + "left": 730, + "lock": false, + "id": "reference_seed_lock", + "visible": true, + "comments": "", + "width": 30, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "colorTextOn": "auto", + "label": "L", + "on": 1, + "off": 0, + "mode": "toggle", + "doubleTap": false, + "decoupled": false, + "typeTags": "", + "ignoreDefaults": false, + "bypass": true + }, + { + "type": "text", + "top": 20, + "left": 120, + "lock": false, + "id": "range_label", + "visible": true, + "comments": "", + "width": 110, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "align": "center", + "value": "ranges", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "" + }, + { + "type": "text", + "top": 160, + "left": 470, + "lock": false, + "id": "orders_label", + "visible": true, + "comments": "", + "width": 110, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "align": "center", + "value": "orders", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "" + }, + { + "type": "text", + "top": 340, + "left": 120, + "lock": false, + "id": "dur_probs_label", + "visible": true, + "comments": "", + "width": 110, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "duration probs", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "vertical": false, + "wrap": false + }, + { + "type": "input", + "top": 460, + "left": 590, + "lock": false, + "id": "m_size", + "visible": true, + "comments": "", + "width": 50, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "", + "default": 3, + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "", + "interaction": true, + "typeTags": "", + "ignoreDefaults": false, + "bypass": true, + "unit": "", + "asYouType": true, + "numeric": false, + "validation": "", + "maxLength": "" + }, + { + "type": "text", + "top": 460, + "left": 650, + "lock": false, + "id": "play_label", + "visible": true, + "comments": "", + "width": 110, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "value": "motifs to play", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "", + "align": "center", + "vertical": false, + "wrap": false + }, + { + "type": "panel", + "top": 380, + "left": 120, + "lock": false, + "id": "dur_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": 330, + "height": 260, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [], + "tabs": [ + { + "type": "tab", + "lock": false, + "id": "entrances", + "visible": true, + "interaction": true, + "comments": "", + "colorText": "auto", + "colorWidget": "auto", + "colorFill": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "label": "auto", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [], + "tabs": [] + }, + { + "type": "tab", + "lock": false, + "id": "passage", + "visible": true, + "interaction": true, + "comments": "", + "colorText": "auto", + "colorWidget": "auto", + "colorFill": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "label": "auto", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "fragment", + "top": 0, + "left": 0, + "lock": false, + "id": "dur", + "visible": true, + "interaction": true, + "comments": "", + "width": 320, + "height": 210, + "expand": "false", + "css": "", + "file": "env.json", + "fallback": "", + "props": {}, + "address": "auto", + "variables": "@{parent.variables}" + } + ], + "tabs": [] + }, + { + "type": "tab", + "lock": false, + "id": "exits", + "visible": true, + "interaction": true, + "comments": "", + "colorText": "auto", + "colorWidget": "auto", + "colorFill": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "label": "auto", + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [], + "tabs": [] + } + ], + "verticalTabs": false + }, + { + "type": "panel", + "top": 200, + "left": 470, + "lock": false, + "id": "order_size_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": 250, + "height": 40, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "range", + "top": 0, + "left": 40, + "lock": false, + "id": "order_size", + "visible": true, + "interaction": true, + "comments": "", + "width": 160, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "design": "default", + "knobSize": "auto", + "horizontal": true, + "pips": false, + "dashed": false, + "gradient": [], + "snap": true, + "spring": false, + "doubleTap": false, + "range": { + "min": 1, + "max": 10 + }, + "logScale": false, + "sensitivity": 1, + "steps": 10, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "i", + "decimals": 0, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "onTouch": "" + }, + { + "type": "input", + "top": 0, + "left": 200, + "lock": false, + "id": "order_size_v2", + "visible": true, + "comments": "", + "width": 40, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "@{order_size.value.1}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "set(\"order_size\", [get(\"order_size_v1\"), value])", + "interaction": true, + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "typeTags": "i", + "ignoreDefaults": false, + "bypass": false + }, + { + "type": "input", + "top": 0, + "left": 0, + "lock": false, + "id": "order_size_v1", + "visible": true, + "comments": "", + "width": 40, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "@{order_size.value.0}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "set(\"order_size\", [value, get(\"order_size_v2\")])", + "interaction": true, + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "typeTags": "i", + "ignoreDefaults": false, + "bypass": false + } + ], + "tabs": [] + }, + { + "type": "textarea", + "top": 60, + "left": 780, + "lock": false, + "id": "mus_seq", + "visible": true, + "interaction": true, + "comments": "", + "width": 520, + "height": 570, + "expand": false, + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "textarea {\n white-space: pre;\n line-height: 1.5;\n font-size: 12px;\n}", + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "s", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "" + }, + { + "type": "text", + "top": 20, + "left": 780, + "lock": false, + "id": "motif_label", + "visible": true, + "comments": "", + "width": 110, + "height": 33.888888888888886, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "vertical": false, + "wrap": false, + "align": "center", + "value": "motif", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 2, + "target": "", + "onCreate": "", + "onValue": "" + }, + { + "type": "panel", + "top": 240, + "left": 470, + "lock": false, + "id": "passage_size_panel", + "visible": true, + "interaction": true, + "comments": "", + "width": 250, + "height": 40, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "colorBg": "auto", + "layout": "default", + "justify": "start", + "gridTemplate": "", + "contain": true, + "scroll": true, + "innerPadding": true, + "verticalTabs": false, + "variables": "@{parent.variables}", + "traversing": false, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 2, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "widgets": [ + { + "type": "range", + "top": 0, + "left": 40, + "lock": false, + "id": "passage_size", + "visible": true, + "interaction": true, + "comments": "", + "width": 160, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "design": "default", + "knobSize": "auto", + "horizontal": true, + "pips": false, + "dashed": false, + "gradient": [], + "snap": true, + "spring": false, + "doubleTap": false, + "range": { + "min": 0, + "max": 10 + }, + "logScale": false, + "sensitivity": 1, + "steps": 11, + "value": "", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "typeTags": "", + "decimals": 0, + "target": "", + "ignoreDefaults": false, + "bypass": false, + "onCreate": "", + "onValue": "", + "onTouch": "" + }, + { + "type": "input", + "top": 0, + "left": 200, + "lock": false, + "id": "passage_size_v2", + "visible": true, + "comments": "", + "width": 40, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "@{passage_size.value.1}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "set(\"passage_size\", [get(\"passage_size_v1\"), value])", + "interaction": true, + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "typeTags": "", + "ignoreDefaults": false, + "bypass": false + }, + { + "type": "input", + "top": 0, + "left": 0, + "lock": false, + "id": "passage_size_v1", + "visible": true, + "comments": "", + "width": 40, + "height": 30, + "expand": "false", + "colorText": "auto", + "colorWidget": "auto", + "colorStroke": "auto", + "colorFill": "auto", + "alphaStroke": "auto", + "alphaFillOff": "auto", + "alphaFillOn": "auto", + "lineWidth": "auto", + "borderRadius": "auto", + "padding": "auto", + "html": "", + "css": "", + "align": "center", + "value": "@{passage_size.value.0}", + "default": "", + "linkId": "", + "address": "auto", + "preArgs": "", + "decimals": 0, + "target": "", + "onCreate": "", + "onValue": "set(\"passage_size\", [value, get(\"passage_size_v2\")])", + "interaction": true, + "unit": "", + "asYouType": false, + "numeric": false, + "validation": "", + "maxLength": "", + "typeTags": "", + "ignoreDefaults": false, + "bypass": false + } + ], + "tabs": [] + } + ], + "tabs": [] + } +} \ No newline at end of file diff --git a/resources/314491/314491_gui_state.state b/resources/314491/314491_gui_state.state new file mode 100644 index 0000000..e251d50 --- /dev/null +++ b/resources/314491/314491_gui_state.state @@ -0,0 +1,177 @@ +{ + "transport": 0, + "rangeslider_0_v1": -837.209302325582, + "rangeslider_0": [ + -837.209302325582, + 1227.9069767441865 + ], + "rangeslider_0_v2": 1227.9069767441865, + "range_panel": -1, + "rangeslider_1_v1": -613.953488372093, + "rangeslider_1": [ + -613.953488372093, + 1395.348837209302 + ], + "rangeslider_1_v2": 1395.348837209302, + "rangeslider_2_v1": -1116.279069767442, + "rangeslider_2": [ + -1116.279069767442, + 753.4883720930229 + ], + "rangeslider_2_v2": 753.4883720930229, + "rangeslider_3_v1": -725.5813953488375, + "rangeslider_3": [ + -725.5813953488375, + 976.7441860465119 + ], + "rangeslider_3_v2": 976.7441860465119, + "range_matrix": [ + null, + null, + null, + null + ], + "current_seed": 314491, + "current_seed_lock": 1, + "commit": 0, + "order_lock": 0, + "current_seed_label": "current seed", + "reference_seed": "nil", + "reference_seed_label": "reference seed", + "reference_seed_lock": 1, + "range_label": "ranges", + "orders_label": "orders", + "dur_probs_label": "duration probs", + "m_size": 1, + "play_label": "motifs to play", + "entrances": [ + 0, + 0 + ], + "dur_probs_size": 3, + "dur_probs_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 + ], + "dur_probs_slider": [ + 0.6147540983606558, + 1.51639344262295 + ], + "dur_probs_rslider_v2": 1.51639344262295, + "dur_probs_rslider_v1": 0.6147540983606558, + "dur_probs_mpos": "", + "dur_probs_env": [ + 0.6147540983606558, + 1.51639344262295, + 0, + 0, + 0.5, + 0.5, + 0.5, + 1, + 0.5 + ], + "dur_probs_flatten": 0, + "dur_probs_chord_prob": 0, + "text_1": "chord prob", + "dur_probs": -1, + "passage": -1, + "exits": [ + 0, + 0 + ], + "order_size": [ + 2, + 6 + ], + "order_size_v2": 6, + "order_size_v1": 2, + "order_size_panel": -1, + "motif_label": "motif", + "passage_size": [ + 8, + 10 + ], + "passage_size_v2": 10, + "passage_size_v1": 8, + "passage_size_panel": -1, + "root": [ + 0, + 0 + ], + "mus_seq": "[\n [\n [\n [ [ [ 0, 0, 0, 0, 0, 0 ], [ \"Rest\" ], [ \"Rest\" ], [ \"Rest\" ] ], 0.875 ],\n [ [ [ 0, 0, 0, 0, 0, 0 ], [ \"Rest\" ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.625 ],\n [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ] ], 1.5 ],\n [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ],\n [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ],\n [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ] ], 1.0 ],\n [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ] ], 1.0 ],\n [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0 ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ] ], 1.25 ],\n [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1 ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ],\n [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ],\n [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ] ], 1.25 ],\n [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.75 ]\n ],\n [\n [ [ [ 0, 0, 0, 0, 0, 0 ], [ \"Rest\" ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ],\n [ [ [ 1, 0, 0, 0, 0, -1 ], [ \"Rest\" ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ] ], 1.5 ],\n [ [ [ 1, 0, 0, 0, 0, -1 ], [ \"Rest\" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.25 ],\n [ [ [ 0, 1, 0, 0, 0, 0 ], [ \"Rest\" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.375 ],\n [ [ [ 0, 0, 0, 1, 0, 0 ], [ \"Rest\" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.75 ],\n [ [ [ 0, 0, 0, 1, 0, 0 ], [ \"Rest\" ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.625 ],\n [ [ [ 0, 0, 0, 1, 0, 0 ], [ \"Rest\" ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.75 ],\n [ [ [ 0, 0, 0, 0, 0, 1 ], [ \"Rest\" ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.125 ],\n [ [ [ 1, 0, -1, 0, 0, 0 ], [ \"Rest\" ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.25 ],\n [ [ [ 0, 1, 0, 0, 0, 0 ], [ \"Rest\" ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.0 ],\n [ [ [ 1, -1, 0, 0, 0, 0 ], [ \"Rest\" ], [ 0, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ]\n ],\n [\n [ [ [ 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 ],\n [ [ [ 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 ],\n [ [ [ 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 ],\n [ [ [ 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 ],\n [ [ [ 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 ],\n [ [ [ 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 ],\n [ [ [ 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 ],\n [ [ [ 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 ],\n [ [ [ 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 ],\n [ [ [ 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 ],\n [ [ [ 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 ],\n [ [ [ 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 ]\n ],\n [\n [ [ [ 2, 0, 0, 0, -1, -1 ], [ 1, -1, 0, 0, -1, 0 ], [ \"Rest\" ], [ 1, 0, 0, -1, -1, 0 ] ], 0.75 ],\n [ [ [ 2, 0, 0, 0, -1, -1 ], [ 1, -1, 0, 0, -1, 0 ], [ \"Rest\" ], [ 0, -1, 0, 1, -1, 0 ] ], 1.0 ],\n [ [ [ 2, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ \"Rest\" ], [ 0, -1, 0, 1, -1, 0 ] ], 0.875 ],\n [ [ [ 2, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ \"Rest\" ], [ 0, -1, 0, 0, -1, 1 ] ], 1.25 ],\n [ [ [ 1, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ \"Rest\" ], [ 0, -1, 0, 0, -1, 1 ] ], 1.125 ],\n [ [ [ 1, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ \"Rest\" ], [ 1, -1, -1, 0, -1, 0 ] ], 1.0 ],\n [ [ [ 1, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ \"Rest\" ], [ 1, -1, -1, 0, -1, 0 ] ], 0.75 ],\n [ [ [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ \"Rest\" ], [ 1, -1, -1, 0, -1, 0 ] ], 0.625 ],\n [ [ [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ \"Rest\" ], [ 0, -1, 0, 0, 0, 0 ] ], 0.75 ],\n [ [ [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ \"Rest\" ], [ 1, -1, 0, 0, -2, 0 ] ], 1.375 ],\n [ [ [ 2, -2, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ \"Rest\" ], [ 1, -1, 0, 0, -2, 0 ] ], 0.875 ],\n [ [ [ 2, -2, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ \"Rest\" ], [ 0, -1, 0, 0, -1, 1 ] ], 1.375 ],\n [ [ [ 2, -2, 0, 0, -1, 0 ], [ \"Rest\" ], [ \"Rest\" ], [ 0, -1, 0, 0, -1, 1 ] ], 1.5 ],\n [ [ [ \"Rest\" ], [ \"Rest\" ], [ \"Rest\" ], [ 0, -1, 0, 0, -1, 1 ] ], 1.375 ],\n [ [ [ \"Rest\" ], [ \"Rest\" ], [ \"Rest\" ], [ \"Rest\" ] ], 1.0 ]\n ]\n ]\n]", + "order": "[\n [ [ 0, 3 ], [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], [ 2 ] ],\n [ [ 3 ], [ 0, 2, 0, 0, 2, 2, 0, 0, 0, 0 ], [ 1 ] ],\n [ [ 2 ], [ 1, 3, 0, 1, 1, 0, 3, 3, 1, 0, 0, 1 ], [ ] ],\n [ [ 1 ], [ 3, 0, 3, 0, 3, 0, 0, 3, 3, 0, 3 ], [ 2 ] ]\n]", + "dur_panel": 1, + "gen": 0 +} \ No newline at end of file diff --git a/resources/314491/314491_music.json b/resources/314491/314491_music.json new file mode 100644 index 0000000..ef5284d --- /dev/null +++ b/resources/314491/314491_music.json @@ -0,0 +1,75 @@ +{ +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 ] ], 1.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 ] ] +], +seed: 314491, +ref_seed: nil +} \ No newline at end of file diff --git a/resources/46b6952a/46b6952a_code.scd b/resources/46b6952a/46b6952a_code.scd new file mode 100644 index 0000000..65c17df --- /dev/null +++ b/resources/46b6952a/46b6952a_code.scd @@ -0,0 +1,719 @@ +( +// 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/46b6952a/46b6952a_gui_state.json b/resources/46b6952a/46b6952a_gui_state.json new file mode 100644 index 0000000..ea5446c --- /dev/null +++ b/resources/46b6952a/46b6952a_gui_state.json @@ -0,0 +1,1359 @@ +{ + "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": "46b6952a" +} \ No newline at end of file diff --git a/resources/46b6952a/46b6952a_mus_model.json b/resources/46b6952a/46b6952a_mus_model.json new file mode 100644 index 0000000..024062b --- /dev/null +++ b/resources/46b6952a/46b6952a_mus_model.json @@ -0,0 +1,57 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ 2, 0, 0, -1, 0, 0 ] ], 1.625 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 2, 0, 0, -2, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 0.875 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 0.625 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.625 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 1, 0, -1, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.25 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 2, 0, 0, -1, -1, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.375 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 1, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 2, -1, 0, 0, 0, -1 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.125 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 2, -2, 0, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.5 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.375 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 0.5 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 2 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 0.625 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 0.875 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ "Rest" ], [ 2, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 2, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0.75 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ] +], +"cur_uid": "46b6952a", +"ref_uid": "7e170ef8", +"order_seed": 969134, +"dur_seed": 384656, +"motifs_seed": 435714, +"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, 1, 3 ], [ 2, 2, 2, 2, 2, 2, 2, 2, 2 ], [ ] ], + [ [ 0, 2, 3 ], [ 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/4c01589b/4c01589b_code.scd b/resources/4c01589b/4c01589b_code.scd new file mode 100644 index 0000000..b11446a --- /dev/null +++ b/resources/4c01589b/4c01589b_code.scd @@ -0,0 +1,718 @@ +( +// 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/4c01589b/4c01589b_gui_state.json b/resources/4c01589b/4c01589b_gui_state.json new file mode 100644 index 0000000..2bc73d6 --- /dev/null +++ b/resources/4c01589b/4c01589b_gui_state.json @@ -0,0 +1,1359 @@ +{ + "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/4c01589b/4c01589b_mus_model.json b/resources/4c01589b/4c01589b_mus_model.json new file mode 100644 index 0000000..436b630 --- /dev/null +++ b/resources/4c01589b/4c01589b_mus_model.json @@ -0,0 +1,85 @@ +{ +"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/55930f4d/55930f4d_code.scd b/resources/55930f4d/55930f4d_code.scd new file mode 100644 index 0000000..caa982a --- /dev/null +++ b/resources/55930f4d/55930f4d_code.scd @@ -0,0 +1,757 @@ +( +// 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 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; + + +// 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; + var voices, durs, patterns, res, indices, sectionDurs, msg, ids, seq; + seq = inSeq.collect({arg mSeq; mSeq[0]}); + # voices, durs = seq.flatten2(seq.maxDepth - 5).flop; + 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}); + 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, 1), + //\seqPath, "/mus_seq", + //\seqMsg, Pseq(seq, 1), + \path, "/playing", + \msg, Pseq(msg, 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", + "motif_edited", "order_edited" + ]; + + modelItems = [ + seq, lastXChanges, + curUID, refUID, orderSeed, durSeed, motifSeed, + entrancesProbVals, passagesProbVals, exitsProbVals, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + + 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"}); + if((nameSpace == "ref_uid") && (modelItem == nil), {modelItem = "nil"}); + "\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(modelItem, 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 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", + "motif_edited", "order_edited" + ]; + + data = nameSpaces.collect({arg nS; msgInterpret.value(jsonObject[nS])}); + + //data.postln; + + # curUID, refUID, orderSeed, durSeed, motifSeed, + entrancesProbVals, passagesProbVals, exitsProbVals, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited = 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, durSeeds, 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; + 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; + + 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 ++ "_bak"); + File.copy(ledgerPath, ledgerPath ++ "_bak"); + File.delete(ledgerPath); + newLedger = File(ledgerPath, "w"); + ledger = ledger.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 path, file; + path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + pSeq = pSeq.add([msgInterpret.value(file.readAllString.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); + 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)); + //Out.ar([0, 1], sig1 * EnvGen.kr(Env.asr(dur, 0.3, 1), 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/55930f4d/55930f4d_mus_model.json b/resources/55930f4d/55930f4d_mus_model.json new file mode 100644 index 0000000..4fb909f --- /dev/null +++ b/resources/55930f4d/55930f4d_mus_model.json @@ -0,0 +1,105 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 3.75 ], + [ [ [ "Rest" ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1.125 ], + [ [ [ "Rest" ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ] ], 1.375 ], + [ [ [ "Rest" ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 1.75 ], + [ [ [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ] ], 0.875 ], + [ [ [ "Rest" ], [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ] ], 1 ], + [ [ [ "Rest" ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ] ], 0 ], + [ [ [ "Rest" ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ] ], 1.75 ], + [ [ [ "Rest" ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 1.625 ], + [ [ [ "Rest" ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 2 ], + [ [ [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 0.875 ], + [ [ [ "Rest" ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 5 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 1.375 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, -1, 0, 1 ], [ 0, 0, 0, -1, 0, 0 ] ], 0.875 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, -1, 1, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 1.875 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 1.875 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, -1, 0, -1, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 1.25 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 1, -1, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 0.875 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, 0, -1, 0, -1 ], [ 0, 0, 0, -1, 0, 0 ] ], 2 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 3.625 ] + ], + [ + [ [ [ 0, 0, 0, -1, 0, 1 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, -1, 0, 1 ], [ 0, -1, 0, 0, 0, 1 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 1 ], + [ [ [ 1, -1, 0, -1, 0, 0 ], [ 0, -1, 0, 0, 0, 1 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 0.875 ], + [ [ [ 1, -1, 0, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 1.75 ], + [ [ [ 1, -1, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 1.5 ], + [ [ [ 1, -1, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -1, 0, 0, 0, -1 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 1.25 ], + [ [ [ 0, 1, 0, -1, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 5.25 ] + ], + [ + [ [ [ 0, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 0, 0 ] ], 1.125 ], + [ [ [ 0, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, -1, 0, 0, 0, 0 ], [ 1, -1, 0, -1, -1, 0 ] ], 1.125 ], + [ [ [ 0, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, -1, 1, 0, -1, 0 ], [ 1, -1, 0, -1, -1, 0 ] ], 1.875 ], + [ [ [ 0, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -2, 0, 0, -1, 0 ], [ 1, -1, 0, -1, -1, 0 ] ], 1.25 ], + [ [ [ 0, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -2, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, -1 ] ], 1.625 ], + [ [ [ 0, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, -1 ] ], 0 ], + [ [ [ 0, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, -1, 1, 0, -1, 0 ] ], 1.5 ], + [ [ [ 0, -1, 0, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, -1, 1, 0, -1, 0 ] ], 0.625 ], + [ [ [ 0, -1, 0, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -2, 0, 0, -1, 0 ] ], 1.625 ], + [ [ [ 1, -1, -1, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -2, 0, 0, -1, 0 ] ], 1.625 ], + [ [ [ 1, -1, -1, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -2, 0 ] ], 1.875 ], + [ [ [ 1, -1, -1, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 5.125 ] + ], + [ + [ [ [ 1, -1, -1, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -2, 0 ], [ 0, -1, 0, 0, 0, 0 ] ], 0.75 ], + [ [ [ 1, -1, -1, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -2, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], 0 ], + [ [ [ 0, -1, 0, 1, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -2, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], 0.625 ], + [ [ [ 0, -1, 0, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -2, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], 1.375 ], + [ [ [ 0, -1, 0, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -2, 0 ], [ 1, -1, -1, 0, -1, 0 ] ], 4.875 ] + ], + [ + [ [ [ 0, -1, 0, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 1, -1, -1, 0, -1, 0 ] ], 0.875 ], + [ [ [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 1, -1, -1, 0, -1, 0 ] ], 1.75 ], + [ [ [ 0, -1, -1, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 1, -1, -1, 0, -1, 0 ] ], 1.375 ], + [ [ [ 0, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 1, -1, -1, 0, -1, 0 ] ], 4.375 ], + [ [ [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ], [ "Rest" ], [ 1, -1, -1, 0, -1, 0 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 1, -1, -1, 0, -1, 0 ] ], 1.875 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 5 ] + ] + ] +], +"last_changes": +[ + [ [ 0, -1, 0, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -2, 0 ], [ 0, 0, 0, 0, -1, 0 ] ], + [ [ 0, -1, 0, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -2, 0 ], [ 1, -1, -1, 0, -1, 0 ] ], + [ [ 0, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -2, 0 ], [ 1, -1, -1, 0, -1, 0 ] ], + [ [ 0, -1, -1, 0, -1, 1 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -2, 0 ], [ 1, -1, -1, 0, -1, 0 ] ], + [ [ 0, -1, 0, 0, 0, 0 ], [ 1, -1, 0, 0, -1, 0 ], [ 1, -1, 0, 0, -2, 0 ], [ 1, -1, -1, 0, -1, 0 ] ] +], +"cur_uid": "55930f4d", +"ref_uid": "nil", +"order_seed": 751178, +"dur_seed": 630355, +"motifs_seed": 318398, +"entrances_probs_vals": [ 0.33687943262411, 1.91, 4.44, 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.33687943262411, 1.91, 4.44, 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.33687943262411, 1.91, 4.44, 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 ] ], +"passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], +"order": +[ + [ [ 2 ], [ 1, 3, 3, 1, 3, 1, 3, 3, 3, 1, 1 ], [ 0 ] ], + [ [ 0, 1, 3 ], [ 2, 2, 2, 2, 2, 2, 2, 2, 2 ], [ ] ], + [ [ 3, 2 ], [ 0, 1, 0, 1, 1, 0, 1, 0 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 2, 3, 2, 3, 0, 3, 0, 3, 3 ], [ ] ], + [ [ 1 ], [ 2, 3, 0, 0, 3 ], [ ] ], + [ [ 1, 3 ], [ 0, 0, 0 ], [ 2 ] ] +], +"sus_weights": [ 0.75, 0.75, 0.75 ], +"order_size": [ 1, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/resources/5cf1e9ab/5cf1e9ab_code.scd b/resources/5cf1e9ab/5cf1e9ab_code.scd new file mode 100644 index 0000000..0af80d7 --- /dev/null +++ b/resources/5cf1e9ab/5cf1e9ab_code.scd @@ -0,0 +1,723 @@ +( +// 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, orderIndex, 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); + ins != sus.last; + }, { + i.postln; + flatOrder.postln; + if(i < (flatOrder.size - 1), {(isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not}, {false}); + }); + if((orderIndex == 0) && sus.includes(ins), { + dur = entrancesDurFunc.value(allowChord); + }, { + dur = passagesDurFunc.value(allowChord); + }); + //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(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"]})); + dur = exitsDurFunc.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, 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); + }; +}); + +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, 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, 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 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])}); + + //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; + 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 ++ "_bak"); + File.copy(ledgerPath, ledgerPath ++ "_bak"); + File.delete(ledgerPath); + newLedger = File(ledgerPath, "w"); + ledger = ledger.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; + 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/5cf1e9ab/5cf1e9ab_mus_model.json b/resources/5cf1e9ab/5cf1e9ab_mus_model.json new file mode 100644 index 0000000..c677fd8 --- /dev/null +++ b/resources/5cf1e9ab/5cf1e9ab_mus_model.json @@ -0,0 +1,41 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1 ], + [ [ [ "Rest" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], + [ [ [ 1, -1, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 2.625 ], + [ [ [ 1, -1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 2.875 ], + [ [ [ "Rest" ], [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ -1, 0, 0, 0, 0, 1 ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.25 ] + ] + ] +], +"last_changes": +[ + [ [ 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 ] ], + [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, -2, -1, 0 ] ], + [ [ 1, -1, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, -2, -1, 0 ] ], + [ [ 1, -1, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, -2, -1, 0 ] ] +], +"cur_uid": "5cf1e9ab", +"ref_uid": "640eeed3", +"order_seed": 747498, +"dur_seed": 968974, +"motifs_seed": 709945, +"entrances_probs_vals": [ 1, 0.5, 2, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.42746113989637, 0.77364864864865, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 1, 0.5 ], +"passages_probs_vals": [ 1, 1.87, 3.7996946564886, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 1, 0.5, 2, 0, 0.5, 0.26424870466321, 0.75675675675676, 0.42746113989637, 0.77364864864865, 0.5, 0.5, 0.58549222797927, 0.72635135135135, 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, 0, 1 ], [ 3 ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 1, 3 ], +"passages_size": [ 0, 2 ] +} \ No newline at end of file diff --git a/resources/5e947063/5e947063_code.scd b/resources/5e947063/5e947063_code.scd new file mode 100644 index 0000000..af06ede --- /dev/null +++ b/resources/5e947063/5e947063_code.scd @@ -0,0 +1,716 @@ +( +// 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/5e947063/5e947063_mus_model.json b/resources/5e947063/5e947063_mus_model.json new file mode 100644 index 0000000..a8164c4 --- /dev/null +++ b/resources/5e947063/5e947063_mus_model.json @@ -0,0 +1,48 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 2.875 ], + [ [ [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1.875 ], + [ [ [ 1, 0, 0, 0, -1, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 2.25 ] + ], + [ + [ [ [ 1, 0, 0, 0, -1, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, -2, -1, 0 ] ], 1.875 ], + [ [ [ 1, 0, 0, 0, -1, 0 ], [ "Rest" ], [ 2, 0, 1, -2, -1, 0 ], [ 2, 0, 0, -2, -1, 0 ] ], 3.5 ], + [ [ [ 3, 0, -1, -2, -1, 0 ], [ "Rest" ], [ 2, 0, 1, -2, -1, 0 ], [ 2, 0, 0, -2, -1, 0 ] ], 2.375 ], + [ [ [ 3, 0, -1, -2, -1, 0 ], [ 2, 0, -1, -2, -1, 0 ], [ 2, 0, 1, -2, -1, 0 ], [ 2, 0, 0, -2, -1, 0 ] ], 2.5 ], + [ [ [ 3, 0, -1, -2, -1, 0 ], [ "Rest" ], [ 2, 0, 1, -2, -1, 0 ], [ 2, 0, 0, -2, -1, 0 ] ], 3.625 ], + [ [ [ 3, 0, -1, -2, -1, 0 ], [ "Rest" ], [ "Rest" ], [ 2, 0, 0, -2, -1, 0 ] ], 2.75 ], + [ [ [ 3, 0, -1, -2, -1, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 3.625 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 2.125 ] + ] + ] +], +"last_changes": +[ + [ [ 1, 0, -1, 0, 0, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, -2, -1, 0 ] ], + [ [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 2, 0, 0, -2, -1, 0 ] ], + [ [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 2, 0, 1, -2, -1, 0 ], [ 2, 0, 0, -2, -1, 0 ] ], + [ [ 3, 0, -1, -2, -1, 0 ], [ 1, 0, 0, -1, -1, 0 ], [ 2, 0, 1, -2, -1, 0 ], [ 2, 0, 0, -2, -1, 0 ] ], + [ [ 3, 0, -1, -2, -1, 0 ], [ 2, 0, -1, -2, -1, 0 ], [ 2, 0, 1, -2, -1, 0 ], [ 2, 0, 0, -2, -1, 0 ] ] +], +"cur_uid": "5e947063", +"ref_uid": "640eeed3", +"order_seed": 190057, +"dur_seed": 196835, +"motifs_seed": 211273, +"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": +[ + [ [ 2 ], [ 0, 0 ], [ 3, 1 ] ], + [ [ 3 ], [ 2, 0, 1 ], [ ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 1, 3 ], +"passages_size": [ 0, 2 ] +} \ No newline at end of file diff --git a/resources/628d5c8b/628d5c8b_code.scd b/resources/628d5c8b/628d5c8b_code.scd new file mode 100644 index 0000000..90f0b1e --- /dev/null +++ b/resources/628d5c8b/628d5c8b_code.scd @@ -0,0 +1,741 @@ +( +// 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, seed; + 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, 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, 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); + ins != sus.last; + }, { + if(i < (flatOrder.size - 1), {(isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not}, {false}); + }); + if((orderIndex == 0) && sus.includes(ins), { + dur = entrancesDurFunc.value(allowChord); + }, { + dur = passagesDurFunc.value(allowChord); + }); + //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(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"]})); + dur = exitsDurFunc.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, 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; + var voices, durs, patterns, res, indices, sectionDurs, msg, ids, seq; + seq = inSeq.collect({arg mSeq; mSeq[0]}); + # voices, durs = seq.flatten2(seq.maxDepth - 5).flop; + 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}); + 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, 1), + //\seqPath, "/mus_seq", + //\seqMsg, Pseq(seq, 1), + \path, "/playing", + \msg, Pseq(msg, 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"}); + if((nameSpace == "ref_uid") && (modelItem == nil), {modelItem = "nil"}); + "\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(modelItem, 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 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])}); + + //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, durSeeds, 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; + 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[..2] ++ [entrancesProbVals[3..]] ++ [durSeeds[0]]); + passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..2] ++ [passagesProbVals[3..]] ++ [durSeeds[1]]); + exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..2] ++ [exitsProbVals[3..]] ++ [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; + + 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 ++ "_bak"); + File.copy(ledgerPath, ledgerPath ++ "_bak"); + File.delete(ledgerPath); + newLedger = File(ledgerPath, "w"); + ledger = ledger.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 path, file; + path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + pSeq = pSeq.add([msgInterpret.value(file.readAllString.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); + 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/628d5c8b/628d5c8b_mus_model.json b/resources/628d5c8b/628d5c8b_mus_model.json new file mode 100644 index 0000000..a7c647e --- /dev/null +++ b/resources/628d5c8b/628d5c8b_mus_model.json @@ -0,0 +1,56 @@ +{ +"music_data": +[ + [ + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0.625 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 0, 0 ] ], 1.75 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, 0, -1, 0 ] ], 1.875 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 0, 0, 1, 0 ] ], 1.5 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 0, 1, 0, 0, 0 ] ], 0.75 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.25 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ], [ -1, 0, 0, 1, 0, 0 ] ], 1.625 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 0, 0 ] ], 1.875 ] + ], + [ + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1.125 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 0.75 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], 1.5 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 1 ], [ 0, 1, 0, 0, 0, 0 ] ], 1.5 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 0, 0 ] ], 1.75 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 1, 0, 0, 0, 0 ] ], 1.125 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ] ], 0.5 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.25 ] + ] + ] +], +"last_changes": +[ + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0, 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 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, -1, 0 ], [ 0, 1, 0, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 1 ], [ 0, 1, 0, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 0, 1, 0, 0, 0, 0 ] ] +], +"cur_uid": "628d5c8b", +"ref_uid": "7e170ef8", +"order_seed": 227004, +"dur_seed": 357129, +"motifs_seed": 170994, +"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": [ [ 65, 727 ], [ 799, 1758 ], [ -282, 1013 ], [ -282, 799 ] ], +"passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], +"order": +[ + [ [ 0 ], [ 3, 2, 3, 3, 3, 3, 3, 3 ], [ 1 ] ], + [ [ 0, 3, 1 ], [ 2, 2, 2, 2, 2 ], [ ] ] +], +"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/62b894e8/62b894e8_code.scd b/resources/62b894e8/62b894e8_code.scd new file mode 100644 index 0000000..70e0740 --- /dev/null +++ b/resources/62b894e8/62b894e8_code.scd @@ -0,0 +1,735 @@ +( +// 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, seed; + 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, 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, 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); + ins != sus.last; + }, { + if(i < (flatOrder.size - 1), {(isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not}, {false}); + }); + if((orderIndex == 0) && sus.includes(ins), { + dur = entrancesDurFunc.value(allowChord); + }, { + dur = passagesDurFunc.value(allowChord); + }); + //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(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"]})); + dur = exitsDurFunc.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, 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; + var voices, durs, patterns, res, indices, sectionDurs, msg, ids, seq; + seq = inSeq.collect({arg mSeq; mSeq[0]}); + # voices, durs = seq.flatten2(seq.maxDepth - 5).flop; + 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}); + 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, 1), + //\seqPath, "/mus_seq", + //\seqMsg, Pseq(seq, 1), + \path, "/playing", + \msg, Pseq(msg, 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"}); + if((nameSpace == "ref_uid") && (modelItem == nil), {modelItem = "nil"}); + "\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(modelItem, 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 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])}); + + //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, durSeeds, 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; + 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[..2] ++ [entrancesProbVals[3..]] ++ [durSeeds[0]]); + passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..2] ++ [passagesProbVals[3..]] ++ [durSeeds[1]]); + exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..2] ++ [exitsProbVals[3..]] ++ [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; + + 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 ++ "_bak"); + File.copy(ledgerPath, ledgerPath ++ "_bak"); + File.delete(ledgerPath); + newLedger = File(ledgerPath, "w"); + ledger = ledger.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 path, file; + path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), path, 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/62b894e8/62b894e8_mus_model.json b/resources/62b894e8/62b894e8_mus_model.json new file mode 100644 index 0000000..3b411ce --- /dev/null +++ b/resources/62b894e8/62b894e8_mus_model.json @@ -0,0 +1,91 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 0.75 ], + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 1.625 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 1.375 ], + [ [ [ 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.75 ], + [ [ [ 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.625 ], + [ [ [ 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.5 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.25 ], + [ [ [ 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.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 ] ], 1.625 ], + [ [ [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.375 ] + ], + [ + [ [ [ -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 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 1.375 ], + [ [ [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 1.625 ], + [ [ [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 0 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 0 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 1, 0 ] ], 1.5 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 1.5 ] + ], + [ + [ [ [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0 ], + [ [ [ "Rest" ], [ 1, 0, 0, 0, -2, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, -1, 0, 0, 0, 0 ] ], 0.625 ], + [ [ [ "Rest" ], [ 1, 0, 0, 0, -2, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 1, -1, 0 ] ], 1.375 ], + [ [ [ "Rest" ], [ 1, 0, 0, 0, -2, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, -1, 1 ] ], 0.625 ], + [ [ [ "Rest" ], [ 1, 0, 0, 0, -2, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 1, 0, 0, -1, 0 ] ], 1.875 ], + [ [ [ "Rest" ], [ 1, 0, 0, 0, -2, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], + [ [ [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.375 ], + [ [ [ "Rest" ], [ 1, -1, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -2, 0 ] ], 0 ], + [ [ [ "Rest" ], [ 1, 0, 0, 0, -1, -1 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -2, 0 ] ], 1.75 ], + [ [ [ "Rest" ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -2, 0 ] ], 1.875 ] + ], + [ + [ [ [ -1, 0, 0, 0, 0, 1 ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ 1, 0, 0, 0, -2, 0 ] ], 1.125 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ 1, 0, 0, -1, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ], [ -1, 0, 1, 0, 0, 1 ] ], 0 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, -1, 0, 1 ], [ 1, 0, 0, 0, -1, 0 ], [ -1, 0, 1, 0, 0, 1 ] ], 1.875 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, -1, 0, 1 ], [ -1, 0, 0, 1, 0, 1 ], [ -1, 0, 1, 0, 0, 1 ] ], 1.5 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, -1, 0, 1 ], [ 0, 0, -1, 0, 0, 1 ], [ -1, 0, 1, 0, 0, 1 ] ], 0 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, -1, 0, 1 ], [ 0, 0, -1, 0, 0, 1 ], [ 0, -1, 0, 0, 0, 1 ] ], 0.75 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, -1, 0, 1 ], [ 0, 0, -1, 0, 0, 1 ], [ -1, 1, 0, 0, 0, 1 ] ], 0 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 0, 1, 0, 0, 1 ], [ 0, 0, -1, 0, 0, 1 ], [ -1, 1, 0, 0, 0, 1 ] ], 1.75 ] + ], + [ + [ [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 0, 1, 0, 0, 1 ], [ 0, 0, -1, 0, 0, 1 ], [ "Rest" ] ], 0 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 0, 1, 0, 0, 1 ], [ -1, 0, 1, 0, 1, 1 ], [ "Rest" ] ], 1.25 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 0, 1, 0, 0, 1 ], [ -1, 0, 0, 0, 0, 2 ], [ "Rest" ] ], 1.5 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 0, 1, 0, 0, 1 ], [ 0, 0, 0, 0, -1, 1 ], [ "Rest" ] ], 1.75 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 0, 1, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.75 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 0, 1, 0, 0, 1 ], [ 0, -1, 0, 0, 0, 1 ], [ "Rest" ] ], 1.75 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 0, 1, 0, 0, 1 ], [ "Rest" ], [ "Rest" ] ], 1 ], + [ [ [ -1, 0, 0, 0, 0, 1 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0.75 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.25 ] + ] + ] +], +"last_changes": +[ + [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 0, 1, 0, 0, 1 ], [ -1, 0, 1, 0, 1, 1 ], [ -1, 1, 0, 0, 0, 1 ] ], + [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 0, 1, 0, 0, 1 ], [ -1, 0, 0, 0, 0, 2 ], [ -1, 1, 0, 0, 0, 1 ] ], + [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 0, 1, 0, 0, 1 ], [ 0, 0, 0, 0, -1, 1 ], [ -1, 1, 0, 0, 0, 1 ] ], + [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 0, 1, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 1 ] ], + [ [ -1, 0, 0, 0, 0, 1 ], [ -1, 0, 1, 0, 0, 1 ], [ 0, -1, 0, 0, 0, 1 ], [ -1, 1, 0, 0, 0, 1 ] ] +], +"cur_uid": "62b894e8", +"ref_uid": "nil", +"order_seed": 684642, +"dur_seed": 712392, +"motifs_seed": 330807, +"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": +[ + [ [ 3, 1, 0 ], [ 2, 2, 2, 2, 2, 2, 2 ], [ ] ], + [ [ 1 ], [ 0, 3, 2, 3, 3, 0, 2, 3 ], [ ] ], + [ [ 2 ], [ 1, 3, 3, 3, 3, 1, 3, 1, 1 ], [ 0 ] ], + [ [ 0 ], [ 3, 1, 2, 2, 3, 3, 1 ], [ ] ], + [ [ 1, 0 ], [ 2, 2, 2, 2, 2 ], [ 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/640eeed3/640eeed3_code.scd b/resources/640eeed3/640eeed3_code.scd new file mode 100644 index 0000000..af06ede --- /dev/null +++ b/resources/640eeed3/640eeed3_code.scd @@ -0,0 +1,716 @@ +( +// 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/640eeed3/640eeed3_mus_model.json b/resources/640eeed3/640eeed3_mus_model.json new file mode 100644 index 0000000..79d175f --- /dev/null +++ b/resources/640eeed3/640eeed3_mus_model.json @@ -0,0 +1,38 @@ +{ +"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/7aa8c429/7aa8c429_code.scd b/resources/7aa8c429/7aa8c429_code.scd new file mode 100644 index 0000000..b6ff291 --- /dev/null +++ b/resources/7aa8c429/7aa8c429_code.scd @@ -0,0 +1,734 @@ +( +// 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, seed; + 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, 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, 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); + ins != sus.last; + }, { + if(i < (flatOrder.size - 1), {(isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not}, {false}); + }); + if((orderIndex == 0) && sus.includes(ins), { + dur = entrancesDurFunc.value(allowChord); + }, { + dur = passagesDurFunc.value(allowChord); + }); + //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(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"]})); + dur = exitsDurFunc.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, 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; + var voices, durs, patterns, res, indices, sectionDurs, msg, ids, seq; + seq = inSeq.collect({arg mSeq; mSeq[0]}); + # voices, durs = seq.flatten2(seq.maxDepth - 5).flop; + 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}); + 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, 1), + //\seqPath, "/mus_seq", + //\seqMsg, Pseq(seq, 1), + \path, "/playing", + \msg, Pseq(msg, 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, 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 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])}); + + //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, durSeeds, 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; + 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[..2] ++ [entrancesProbVals[3..]] ++ [durSeeds[0]]); + passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..2] ++ [passagesProbVals[3..]] ++ [durSeeds[1]]); + exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..2] ++ [exitsProbVals[3..]] ++ [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; + + 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 ++ "_bak"); + File.copy(ledgerPath, ledgerPath ++ "_bak"); + File.delete(ledgerPath); + newLedger = File(ledgerPath, "w"); + ledger = ledger.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 path, file; + path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), path, 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/7aa8c429/7aa8c429_mus_model.json b/resources/7aa8c429/7aa8c429_mus_model.json new file mode 100644 index 0000000..35572e0 --- /dev/null +++ b/resources/7aa8c429/7aa8c429_mus_model.json @@ -0,0 +1,46 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 1 ], + [ [ [ "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 ], [ 1, 0, 0, 0, 0, -1 ] ], 0.75 ] + ], + [ + [ [ [ "Rest" ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.875 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0 ], + [ [ [ 0, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ "Rest" ] ], 0.75 ], + [ [ [ 0, 1, 0, 0, 0, 0 ], [ "Rest" ], [ 0, 1, 0, 0, 0, -1 ], [ "Rest" ] ], 1 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 1, 0, 0, 0, -1 ], [ "Rest" ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 0.625 ] + ] + ] +], +"last_changes": +[ + [ [ 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, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], + [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], + [ [ 0, 1, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 1, 0, 0, 0, -1 ], [ 1, 0, 0, 0, 0, -1 ] ] +], +"cur_uid": "7aa8c429", +"ref_uid": "4c01589b", +"order_seed": 367527, +"dur_seed": 393265, +"motifs_seed": 960266, +"entrances_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"passages_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.5, 0.5, 1, 0.5 ], +"exits_probs_vals": [ 0.75, 0.5, 2, 0, 0.5, 0.5, 0.5, 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 ] ], + [ [ 0 ], [ 2 ], [ 3, 1 ] ] +], +"sus_weights": [ 1, 0, 0 ], +"order_size": [ 1, 3 ], +"passages_size": [ 0, 2 ] +} \ No newline at end of file diff --git a/resources/7ac10d34/7ac10d34_code.scd b/resources/7ac10d34/7ac10d34_code.scd new file mode 100644 index 0000000..65c17df --- /dev/null +++ b/resources/7ac10d34/7ac10d34_code.scd @@ -0,0 +1,719 @@ +( +// 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/7ac10d34/7ac10d34_gui_state.json b/resources/7ac10d34/7ac10d34_gui_state.json new file mode 100644 index 0000000..84e6edd --- /dev/null +++ b/resources/7ac10d34/7ac10d34_gui_state.json @@ -0,0 +1,1359 @@ +{ + "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/7ac10d34/7ac10d34_mus_model.json b/resources/7ac10d34/7ac10d34_mus_model.json new file mode 100644 index 0000000..73f197b --- /dev/null +++ b/resources/7ac10d34/7ac10d34_mus_model.json @@ -0,0 +1,59 @@ +{ +"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/7e170ef8/7e170ef8_code.scd b/resources/7e170ef8/7e170ef8_code.scd new file mode 100644 index 0000000..b11446a --- /dev/null +++ b/resources/7e170ef8/7e170ef8_code.scd @@ -0,0 +1,718 @@ +( +// 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/7e170ef8/7e170ef8_gui_state.json b/resources/7e170ef8/7e170ef8_gui_state.json new file mode 100644 index 0000000..704cf3a --- /dev/null +++ b/resources/7e170ef8/7e170ef8_gui_state.json @@ -0,0 +1,1359 @@ +{ + "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/7e170ef8/7e170ef8_mus_model.json b/resources/7e170ef8/7e170ef8_mus_model.json new file mode 100644 index 0000000..c9b8807 --- /dev/null +++ b/resources/7e170ef8/7e170ef8_mus_model.json @@ -0,0 +1,79 @@ +{ +"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/7ead41c3/7ead41c3_code.scd b/resources/7ead41c3/7ead41c3_code.scd new file mode 100644 index 0000000..b6ff291 --- /dev/null +++ b/resources/7ead41c3/7ead41c3_code.scd @@ -0,0 +1,734 @@ +( +// 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, seed; + 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, 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, 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); + ins != sus.last; + }, { + if(i < (flatOrder.size - 1), {(isInChord[flatOrder[i + 1]] || (ins == flatOrder[i + 1])).not}, {false}); + }); + if((orderIndex == 0) && sus.includes(ins), { + dur = entrancesDurFunc.value(allowChord); + }, { + dur = passagesDurFunc.value(allowChord); + }); + //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(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"]})); + dur = exitsDurFunc.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, 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; + var voices, durs, patterns, res, indices, sectionDurs, msg, ids, seq; + seq = inSeq.collect({arg mSeq; mSeq[0]}); + # voices, durs = seq.flatten2(seq.maxDepth - 5).flop; + 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}); + 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, 1), + //\seqPath, "/mus_seq", + //\seqMsg, Pseq(seq, 1), + \path, "/playing", + \msg, Pseq(msg, 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, 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 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])}); + + //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, durSeeds, 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; + 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[..2] ++ [entrancesProbVals[3..]] ++ [durSeeds[0]]); + passagesDurFunc = genDurFunc.valueArray(passagesProbVals[..2] ++ [passagesProbVals[3..]] ++ [durSeeds[1]]); + exitsDurFunc = genDurFunc.valueArray(exitsProbVals[..2] ++ [exitsProbVals[3..]] ++ [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; + + 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 ++ "_bak"); + File.copy(ledgerPath, ledgerPath ++ "_bak"); + File.delete(ledgerPath); + newLedger = File(ledgerPath, "w"); + ledger = ledger.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 path, file; + path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + pSeq = pSeq.add([msgInterpret.value(file.readAllString.parseJSON["music_data"]), path, 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/7ead41c3/7ead41c3_mus_model.json b/resources/7ead41c3/7ead41c3_mus_model.json new file mode 100644 index 0000000..9528437 --- /dev/null +++ b/resources/7ead41c3/7ead41c3_mus_model.json @@ -0,0 +1,77 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 2, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ "Rest" ], [ 2, -1, 0, -1, 0, 0 ], [ "Rest" ], [ 2, 0, 0, -1, 0, 0 ] ], 0.625 ], + [ [ [ "Rest" ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.875 ], + [ [ [ 0, -1, 2, 0, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 0.75 ], + [ [ [ 2, -2, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 0.75 ], + [ [ [ 2, -1, 0, -1, -1, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.125 ], + [ [ [ 1, -1, 0, -1, 0, 1 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.75 ], + [ [ [ 1, -2, 1, 0, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 0.5 ], + [ [ [ 1, 0, 0, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.5 ], + [ [ [ 2, -1, -1, -1, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.125 ], + [ [ [ 0, 0, 1, 0, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.625 ], + [ [ [ 0, -1, 1, 0, 1, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.75 ], + [ [ [ 1, -1, 0, -1, 0, 1 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 2, 0, 0, -1, 0, 0 ] ], 1.625 ] + ], + [ + [ [ [ 1, -1, 0, -1, 0, 1 ], [ 2, -1, 0, -1, 0, 0 ], [ "Rest" ], [ 2, 0, 0, -1, 0, 0 ] ], 0 ], + [ [ [ 1, -1, 0, -1, 0, 1 ], [ 2, -1, 0, -1, 0, 0 ], [ "Rest" ], [ 2, -1, 0, -1, 0, 1 ] ], 0 ], + [ [ [ 1, -1, 0, -1, 0, 1 ], [ 2, -2, 0, -1, 0, 1 ], [ "Rest" ], [ 2, -1, 0, -1, 0, 1 ] ], 1.125 ], + [ [ [ 1, -1, 0, -1, 0, 1 ], [ 2, -2, 0, -1, 0, 1 ], [ "Rest" ], [ 1, -1, 0, 0, 0, 1 ] ], 0.875 ], + [ [ [ 1, -1, 0, -1, 0, 1 ], [ 1, -1, 1, -1, 0, 1 ], [ "Rest" ], [ 1, -1, 0, 0, 0, 1 ] ], 0 ], + [ [ [ 1, -1, 0, -1, 0, 1 ], [ 1, -1, 1, -1, 0, 1 ], [ "Rest" ], [ 1, -1, 0, -1, 0, 2 ] ], 0.75 ], + [ [ [ 1, -1, 0, -1, 0, 1 ], [ 2, -1, 0, -2, 0, 1 ], [ "Rest" ], [ 1, -1, 0, -1, 0, 2 ] ], 1.25 ], + [ [ [ 1, -1, 0, -1, 0, 1 ], [ 2, -1, 0, -1, 0, 0 ], [ "Rest" ], [ 1, -1, 0, -1, 0, 2 ] ], 1.75 ] + ], + [ + [ [ [ 1, -1, 0, -1, 0, 1 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], 1.625 ], + [ [ [ 0, 0, 1, 0, 0, 0 ], [ 2, -1, 0, -1, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], 0 ], + [ [ [ 0, 0, 1, 0, 0, 0 ], [ 0, -1, 1, 0, 0, 1 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], 0.625 ], + [ [ [ 0, -1, 1, -1, 0, 2 ], [ 0, -1, 1, 0, 0, 1 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], 0.625 ], + [ [ [ 0, -1, 1, 0, 1, 0 ], [ 0, -1, 1, 0, 0, 1 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], 0 ], + [ [ [ 0, -1, 1, 0, 1, 0 ], [ 0, 0, 1, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], 1.5 ], + [ [ [ 0, -1, 1, 0, 1, 0 ], [ 1, -2, 1, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], 0.75 ], + [ [ [ 1, -1, 1, 0, -1, 0 ], [ 1, -2, 1, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], 1.25 ], + [ [ [ 1, -1, 1, 0, -1, 0 ], [ -1, -1, 0, 0, 0, 2 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], 1.75 ], + [ [ [ 1, -1, 0, -1, 0, 1 ], [ -1, -1, 0, 0, 0, 2 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], 0 ], + [ [ [ 1, -1, 0, -1, 0, 1 ], [ 0, -1, -1, -1, 0, 2 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], 0.75 ], + [ [ [ 1, -1, 0, -1, 0, 1 ], [ -1, 0, 0, -1, 0, 2 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], 1.25 ], + [ [ [ 1, -1, 0, -1, 0, 1 ], [ -1, 0, 0, -1, 0, 2 ], [ "Rest" ], [ 1, -1, 0, -1, 0, 2 ] ], 0 ], + [ [ [ 1, -1, 0, -1, 0, 1 ], [ "Rest" ], [ "Rest" ], [ 1, -1, 0, -1, 0, 2 ] ], 0.75 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 1, -1, 0, -1, 0, 2 ] ], 0 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.875 ] + ] + ] +], +"last_changes": +[ + [ [ 1, -1, 1, 0, -1, 0 ], [ 1, -2, 1, 0, 0, 0 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], + [ [ 1, -1, 1, 0, -1, 0 ], [ -1, -1, 0, 0, 0, 2 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], + [ [ 1, -1, 0, -1, 0, 1 ], [ -1, -1, 0, 0, 0, 2 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], + [ [ 1, -1, 0, -1, 0, 1 ], [ 0, -1, -1, -1, 0, 2 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ], + [ [ 1, -1, 0, -1, 0, 1 ], [ -1, 0, 0, -1, 0, 2 ], [ 1, -1, 1, 0, 0, 0 ], [ 1, -1, 0, -1, 0, 2 ] ] +], +"cur_uid": "7ead41c3", +"ref_uid": "46b6952a", +"order_seed": 941210, +"dur_seed": 186474, +"motifs_seed": 450931, +"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": +[ + [ [ 3, 1, 2 ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ ] ], + [ [ 0 ], [ 3, 1, 3, 1, 3, 1, 1 ], [ 2 ] ], + [ [ 2, 3 ], [ 0, 1, 0, 0, 1, 1, 0, 1, 0, 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.json b/resources/piece_ledger.json new file mode 100644 index 0000000..7fa31dc --- /dev/null +++ b/resources/piece_ledger.json @@ -0,0 +1,17 @@ +{ +"ledger": +[ + "4c01589b", + "7e170ef8", + "46b6952a", + "7ac10d34", + "640eeed3", + "5e947063", + "5cf1e9ab", + "7aa8c429", + "7ead41c3", + "62b894e8", + "628d5c8b", + "55930f4d" +] +} \ No newline at end of file diff --git a/resources/piece_ledger.json_bak b/resources/piece_ledger.json_bak new file mode 100644 index 0000000..2e489ab --- /dev/null +++ b/resources/piece_ledger.json_bak @@ -0,0 +1,16 @@ +{ +"ledger": +[ + "4c01589b", + "7e170ef8", + "46b6952a", + "7ac10d34", + "640eeed3", + "5e947063", + "5cf1e9ab", + "7aa8c429", + "7ead41c3", + "62b894e8", + "628d5c8b" +] +} \ No newline at end of file diff --git a/resources/piece_ledger.json_bak_bak b/resources/piece_ledger.json_bak_bak new file mode 100644 index 0000000..aa529be --- /dev/null +++ b/resources/piece_ledger.json_bak_bak @@ -0,0 +1,17 @@ +{ +ledger: +[ + 314491, + 314491, + 314491, + 314491, + 127947, + 389839, + 333441, + 175649, + 936089, + 936089, + 947477, + 947477 +] +} \ No newline at end of file diff --git a/resources/tmp/tmp_gui_state.json.json b/resources/tmp/tmp_gui_state.json.json new file mode 100644 index 0000000..b388a1d --- /dev/null +++ b/resources/tmp/tmp_gui_state.json.json @@ -0,0 +1,603 @@ +{ + "mus_seq": "[\n [\n [\n [ [ [ \"Rest\" ], [ \"Rest\" ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ] ], 0 ], \n [ [ [ \"Rest\" ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.75 ], \n [ [ [ 0, 0, 1, 0, 0, 0 ], [ \"Rest\" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.5 ], \n [ [ [ 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.75 ], \n [ [ [ 0, 0, 1, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.5 ], \n [ [ [ 0, 0, 1, 0, 0, 0 ], [ -1, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.875 ], \n [ [ [ 0, 0, 1, 0, 0, 0 ], [ 0, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.625 ], \n [ [ [ 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 ], \n [ [ [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.5 ]\n ],\n [\n [ [ [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.125 ], \n [ [ [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 1, 0, -1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1 ], \n [ [ [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, -1, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ], \n [ [ [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.75 ], \n [ [ [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ 0, 0, 0, -1, 0, 1 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.625 ], \n [ [ [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ -1, 0, 1, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.75 ], \n [ [ [ 0, 0, 0, 0, 1, 0 ], [ 1, 0, 0, -1, 0, 0 ], [ -1, 0, 1, 0, 1, 0 ], [ \"Rest\" ] ], 0 ], \n [ [ [ \"Rest\" ], [ 1, 0, 0, -1, 0, 0 ], [ -1, 0, 1, 0, 1, 0 ], [ \"Rest\" ] ], 0 ], \n [ [ [ \"Rest\" ], [ \"Rest\" ], [ -1, 0, 1, 0, 1, 0 ], [ \"Rest\" ] ], 0 ], \n [ [ [ \"Rest\" ], [ \"Rest\" ], [ \"Rest\" ], [ \"Rest\" ] ], 1.375 ]\n ]\n ]\n]", + "motif_label": "motif", + "motif_panel": -1, + "seeds_label": "seeds", + "order": "[\n [ [ 3, 2 ], [ 0, 1, 1, 1, 1, 1, 0 ], [ ] ], \n [ [ 1, 0, 3 ], [ 2, 2, 2, 2, 2, 2 ], [ ] ]\n]", + "order_lock": 0, + "order_size_rslider": [ + 2, + 6 + ], + "order_size_input_max": 6, + "order_size_input_min": 2, + "order_size": -1, + "passages_size_rslider": [ + 0, + 10 + ], + "passages_size_input_max": 10, + "passages_size_input_min": 0, + "passages_size": -1, + "sus_weights": [ + null, + null, + null + ], + "range_matrix": [ + null, + null, + null, + null + ], + "instrumentation": -1, + "entrances_probs_sync": "entrances", + "entrances": -1, + "passages_probs_sync": "passages", + "passages": -1, + "exits_probs_sync": "exits", + "exits": -1, + "dur_panel": 0, + "durations": -1, + "passages_weights": [ + null, + null, + null, + null, + null + ], + "weights": -1, + "seeds_tab_panel": 1, + "order_seed_lock": 0, + "order_seed": 684642, + "dur_seed_lock": 0, + "dur_seed": 712392, + "weights_seed_lock": 0, + "weights_seed": 330807, + "seeds_panel": -1, + "root": -1, + "sus_weights/0_val_slider": 0.75, + "sus_weights/0_val_input": 0.75, + "sus_weights/0_val_label": 1, + "sus_weights/0_val": -1, + "sus_weights/1_val_slider": 0.69, + "sus_weights/1_val_input": 0.69, + "sus_weights/1_val_label": 2, + "sus_weights/1_val": -1, + "sus_weights/2_val_slider": 0.75, + "sus_weights/2_val_input": 0.75, + "sus_weights/2_val_label": 3, + "sus_weights/2_val": -1, + "passages_weights/0_val_slider": 0.75, + "passages_weights/0_val_input": 0.75, + "passages_weights/0_val_label": "step", + "passages_weights/0_val": -1, + "passages_weights/1_val_slider": 0.75, + "passages_weights/1_val_input": 0.75, + "passages_weights/1_val_label": "dc", + "passages_weights/1_val": -1, + "passages_weights/2_val_slider": 0.75, + "passages_weights/2_val_input": 0.75, + "passages_weights/2_val_label": "range", + "passages_weights/2_val": -1, + "passages_weights/3_val_slider": 0.75, + "passages_weights/3_val_input": 0.75, + "passages_weights/3_val_label": "registration", + "passages_weights/3_val": -1, + "passages_weights/4_val_slider": 0.75, + "passages_weights/4_val_input": 0.75, + "passages_weights/4_val_label": "hd", + "passages_weights/4_val": -1, + "range_matrix/0_val_input_min": -384, + "range_matrix/0_val_rslider": [ + -384, + 2400 + ], + "range_matrix/0_val_input_max": 2400, + "range_matrix/0_val": -1, + "range_matrix/1_val_input_min": -507, + "range_matrix/1_val_rslider": [ + -507, + 2400 + ], + "range_matrix/1_val_input_max": 2400, + "range_matrix/1_val": -1, + "range_matrix/2_val_input_min": -282, + "range_matrix/2_val_rslider": [ + -282, + 2237 + ], + "range_matrix/2_val_input_max": 2237, + "range_matrix/2_val": -1, + "range_matrix/3_val_input_min": -1200, + "range_matrix/3_val_rslider": [ + -1200, + 2053 + ], + "range_matrix/3_val_input_max": 2053, + "range_matrix/3_val": -1, + "entrances_probs_chord_val_slider": 0.75, + "entrances_probs_chord_val_input": 0.75, + "entrances_probs_chord_val_label": "chord prob", + "entrances_probs_chord_val": -1, + "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 + ], + "entrances_probs": -1, + "passages_probs_chord_val_slider": 0.75, + "passages_probs_chord_val_input": 0.75, + "passages_probs_chord_val_label": "chord prob", + "passages_probs_chord_val": -1, + "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 + ], + "passages_probs": -1, + "exits_probs_chord_val_slider": 0.75, + "exits_probs_chord_val_input": 0.75, + "exits_probs_chord_val_label": "chord prob", + "exits_probs_chord_val": -1, + "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 + ], + "exits_probs": -1, + "step_env_env_vals": [ + 0.5, + 2, + 0, + 0.5, + 0.5, + 0.5, + 1, + 0.5 + ], + "step_env_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 + ], + "step_env_env_size": 3, + "step_env_env_flatten": 0, + "step_env_env_rslider": [ + 0.5, + 2 + ], + "step_env_env_input_max": 2, + "step_env_env_input_min": 0.5, + "step_env_env_mpos": "", + "step_env_env": -1, + "entrances_probs_dur_env_vals": [ + 0.5, + 2, + 0, + 0.5, + 0.26424870466321, + 0.75675675675676, + 0.5, + 0.5, + 0.58549222797927, + 0.72635135135135, + 1, + 0.5 + ], + "entrances_probs_dur_env_canvas": [ + [ + 0, + 0.5 + ], + [ + 0.26424870466321, + 0.75675675675676 + ], + [ + 0.5, + 0.5 + ], + [ + 0.58549222797927, + 0.72635135135135 + ], + [ + 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 + ], + "entrances_probs_dur_env_size": 5, + "entrances_probs_dur_env_flatten": 0, + "entrances_probs_dur_env_rslider": [ + 0.5, + 2 + ], + "entrances_probs_dur_env_input_max": 2, + "entrances_probs_dur_env_input_min": 0.5, + "entrances_probs_dur_env_mpos": "", + "entrances_probs_dur_env": -1, + "passages_probs_dur_env_vals": [ + 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_dur_env_canvas": [ + [ + 0, + 0.5 + ], + [ + 0.20725388601036, + 0.68581081081081 + ], + [ + 0.24093264248705, + 0.34121621621622 + ], + [ + 0.5, + 0.5 + ], + [ + 0.67616580310881, + 0.81081081081081 + ], + [ + 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 + ], + "passages_probs_dur_env_size": 6, + "passages_probs_dur_env_flatten": 0, + "passages_probs_dur_env_rslider": [ + 0.5, + 2 + ], + "passages_probs_dur_env_input_max": 2, + "passages_probs_dur_env_input_min": 0.5, + "passages_probs_dur_env_mpos": "", + "passages_probs_dur_env": -1, + "exits_probs_dur_env_vals": [ + 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_dur_env_canvas": [ + [ + 0, + 0.5 + ], + [ + 0.20725388601036, + 0.68581081081081 + ], + [ + 0.24093264248705, + 0.34121621621622 + ], + [ + 0.5, + 0.5 + ], + [ + 0.67616580310881, + 0.81081081081081 + ], + [ + 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 + ], + "exits_probs_dur_env_size": 6, + "exits_probs_dur_env_flatten": 0, + "exits_probs_dur_env_rslider": [ + 0.5, + 2 + ], + "exits_probs_dur_env_input_max": 2, + "exits_probs_dur_env_input_min": 0.5, + "exits_probs_dur_env_mpos": "", + "exits_probs_dur_env": -1 +} \ No newline at end of file diff --git a/resources/tmp/tmp_mus_model.json b/resources/tmp/tmp_mus_model.json new file mode 100644 index 0000000..13de2c1 --- /dev/null +++ b/resources/tmp/tmp_mus_model.json @@ -0,0 +1,113 @@ +{ +"music_data": +[ + [ + [ + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ] ], 1.75 ], + [ [ [ "Rest" ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 4.625 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 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 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 0.875 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 4.5 ] + ], + [ + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ] ], 1.375 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 1, 0, 0 ] ], 1.25 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ -1, 0, 0, 0, 0, 1 ] ], 1.875 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, -1, -1, 0, 0 ] ], 1.875 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 1.625 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, -1, 0, 1, 0 ] ], 0.5 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0 ] ], 1.875 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, -1, 0, 0 ] ], 0.75 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 1.875 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 0, 0, -1 ] ], 0.875 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 4.375 ] + ], + [ + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 0, 0, -1, 0, 1, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ 1, -1, -1, 0, 1, 0 ], [ 0, 0, -1, 0, 1, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 1.5 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 0, 1, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 0.625 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, 0, -1, 0, -1, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 1.75 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, 0, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 1.25 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 2, -1, -1, 0, 0, -1 ], [ 1, -1, -1, 0, 0, 0 ] ], 0.75 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, -1, -1, 0, 1, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 1.625 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ 1, 0, -2, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 3.375 ] + ], + [ + [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ 1, 0, -2, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 1.125 ], + [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, -1, 1, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 0.75 ], + [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 1, -1, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 0.875 ], + [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 0.625 ], + [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ 1, 0, -1, 0, -1, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 3.625 ] + ], + [ + [ [ [ "Rest" ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, -1, -1, 0, 0, 0 ] ], 2 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ 1, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, -1, -1, 0, 0, 0 ] ], 0 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ 2, -1, -2, 0, 0, 0 ], [ "Rest" ], [ 1, -1, -1, 0, 0, 0 ] ], 5 ] + ], + [ + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 1, -1, -1, 0, 0, 0 ] ], 1.125 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, -1, 0, -1, 0 ], [ 1, -1, -1, 0, 0, 0 ] ], 1 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, -1, 0, -1, 0 ], [ 0, 0, -1, 0, 1, 0 ] ], 1.875 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, -1, 0, -1, 0 ], [ 0, 1, -1, 0, 0, 0 ] ], 1.125 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, -1, 0, -1, 0 ], [ 1, 0, -2, 0, 0, 0 ] ], 1.875 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, -1, 0, -1, 0 ], [ 0, 0, -1, 0, 0, 1 ] ], 0.625 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ 1, 0, -1, 0, -1, 0 ], [ 0, 0, -1, 1, 0, 0 ] ], 4.25 ] + ], + [ + [ [ [ 0, 0, -1, 0, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 0, 0, -1, 1, 0, 0 ] ], 1.25 ], + [ [ [ 0, 0, -1, 0, 0, 0 ], [ 2, -1, -2, 0, 0, 0 ], [ "Rest" ], [ 0, 0, -1, 1, 0, 0 ] ], 1 ], + [ [ [ 1, -1, -2, 0, 0, 0 ], [ 2, -1, -2, 0, 0, 0 ], [ "Rest" ], [ 0, 0, -1, 1, 0, 0 ] ], 1.875 ], + [ [ [ 0, -1, -2, 1, 0, 0 ], [ 2, -1, -2, 0, 0, 0 ], [ "Rest" ], [ 0, 0, -1, 1, 0, 0 ] ], 3.125 ] + ], + [ + [ [ [ 0, -1, -2, 1, 0, 0 ], [ 2, -1, -2, 0, 0, 0 ], [ 1, 0, -1, 0, -1, 0 ], [ 0, 0, -1, 1, 0, 0 ] ], 3.75 ], + [ [ [ 0, -1, -2, 1, 0, 0 ], [ 1, 0, -1, 0, -1, 1 ], [ 1, 0, -1, 0, -1, 0 ], [ 0, 0, -1, 1, 0, 0 ] ], 1.375 ], + [ [ [ 0, -1, -2, 1, 0, 0 ], [ 1, 0, -1, 0, -1, 1 ], [ 1, 0, -1, 0, -1, 0 ], [ 1, 0, 0, 0, -1, 0 ] ], 0.75 ], + [ [ [ 0, -1, -2, 1, 0, 0 ], [ 1, 0, -1, 0, -1, 1 ], [ 1, 0, -1, 0, -1, 0 ], [ 1, -1, -2, 1, 0, 0 ] ], 1.5 ], + [ [ [ 0, -1, -2, 1, 0, 0 ], [ 1, 0, -1, 0, -1, 1 ], [ 1, 0, -1, 0, -1, 0 ], [ 2, 0, -1, 0, -2, 0 ] ], 1 ], + [ [ [ 0, -1, -2, 1, 0, 0 ], [ 1, 0, -1, 0, -1, 1 ], [ 1, 0, -1, 0, -1, 0 ], [ 2, -1, -2, 0, 0, 0 ] ], 1.125 ], + [ [ [ 0, -1, -2, 1, 0, 0 ], [ 1, 0, -1, 0, -1, 1 ], [ 1, 0, -1, 0, -1, 0 ], [ 2, -1, -1, 0, -1, 0 ] ], 1.125 ], + [ [ [ 0, -1, -2, 1, 0, 0 ], [ 1, 0, -1, 0, -1, 1 ], [ 1, 0, -1, 0, -1, 0 ], [ 2, 0, -1, 0, -1, -1 ] ], 5.25 ], + [ [ [ 0, -1, -2, 1, 0, 0 ], [ 1, 0, -1, 0, -1, 1 ], [ "Rest" ], [ 2, 0, -1, 0, -1, -1 ] ], 0 ], + [ [ [ 0, -1, -2, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ 2, 0, -1, 0, -1, -1 ] ], 1.5 ], + [ [ [ 0, -1, -2, 1, 0, 0 ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 1.75 ], + [ [ [ "Rest" ], [ "Rest" ], [ "Rest" ], [ "Rest" ] ], 4.625 ] + ] + ] +], +"last_changes": +[ + [ [ 0, -1, -2, 1, 0, 0 ], [ 1, 0, -1, 0, -1, 1 ], [ 1, 0, -1, 0, -1, 0 ], [ 1, -1, -2, 1, 0, 0 ] ], + [ [ 0, -1, -2, 1, 0, 0 ], [ 1, 0, -1, 0, -1, 1 ], [ 1, 0, -1, 0, -1, 0 ], [ 2, 0, -1, 0, -2, 0 ] ], + [ [ 0, -1, -2, 1, 0, 0 ], [ 1, 0, -1, 0, -1, 1 ], [ 1, 0, -1, 0, -1, 0 ], [ 2, -1, -2, 0, 0, 0 ] ], + [ [ 0, -1, -2, 1, 0, 0 ], [ 1, 0, -1, 0, -1, 1 ], [ 1, 0, -1, 0, -1, 0 ], [ 2, -1, -1, 0, -1, 0 ] ], + [ [ 0, -1, -2, 1, 0, 0 ], [ 1, 0, -1, 0, -1, 1 ], [ 1, 0, -1, 0, -1, 0 ], [ 2, 0, -1, 0, -1, -1 ] ] +], +"cur_uid": "tmp", +"ref_uid": "nil", +"order_seed": 739163, +"dur_seed": 513075, +"motifs_seed": 310413, +"entrances_probs_vals": [ 0.33687943262411, 1.91, 4.44, 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.33687943262411, 1.91, 4.44, 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.33687943262411, 1.91, 4.44, 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 ] ], +"passages_weights": [ 0.75, 0.75, 0.75, 0.75, 0.75 ], +"order": +[ + [ [ 3, 2 ], [ 0, 1, 1 ], [ ] ], + [ [ 2, 0 ], [ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 ], [ 1 ] ], + [ [ 3, 0 ], [ 2, 1, 1, 2, 2, 2, 2, 2, 2 ], [ ] ], + [ [ 3, 1 ], [ 2, 2, 2, 2 ], [ 0 ] ], + [ [ 0, 3 ], [ 1 ], [ 2 ] ], + [ [ 2, 0 ], [ 3, 3, 3, 3, 3 ], [ 1 ] ], + [ [ 1, 3 ], [ 0, 0 ], [ 2 ] ], + [ [ 0, 2 ], [ 1, 3, 3, 3, 3, 3, 3 ], [ ] ] +], +"sus_weights": [ 0, 0.82, 0 ], +"order_size": [ 1, 10 ], +"passages_size": [ 0, 10 ], +"motif_edited": "false", +"order_edited": "false" +} \ No newline at end of file diff --git a/supercollider/seeds_and_ledgers_main.scd b/supercollider/seeds_and_ledgers_main.scd new file mode 100644 index 0000000..caa982a --- /dev/null +++ b/supercollider/seeds_and_ledgers_main.scd @@ -0,0 +1,757 @@ +( +// 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 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; + + +// 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; + var voices, durs, patterns, res, indices, sectionDurs, msg, ids, seq; + seq = inSeq.collect({arg mSeq; mSeq[0]}); + # voices, durs = seq.flatten2(seq.maxDepth - 5).flop; + 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}); + 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, 1), + //\seqPath, "/mus_seq", + //\seqMsg, Pseq(seq, 1), + \path, "/playing", + \msg, Pseq(msg, 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", + "motif_edited", "order_edited" + ]; + + modelItems = [ + seq, lastXChanges, + curUID, refUID, orderSeed, durSeed, motifSeed, + entrancesProbVals, passagesProbVals, exitsProbVals, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited + ]; + + 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"}); + if((nameSpace == "ref_uid") && (modelItem == nil), {modelItem = "nil"}); + "\"" ++ nameSpace ++ "\":" ++ insert ++ stringifyToDepth.value(modelItem, 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 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", + "motif_edited", "order_edited" + ]; + + data = nameSpaces.collect({arg nS; msgInterpret.value(jsonObject[nS])}); + + //data.postln; + + # curUID, refUID, orderSeed, durSeed, motifSeed, + entrancesProbVals, passagesProbVals, exitsProbVals, + ranges, passagesWeights, orders, susWeights, orderSize, passagesSize, + motifEdited, orderEdited = 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, durSeeds, 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; + 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; + + 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 ++ "_bak"); + File.copy(ledgerPath, ledgerPath ++ "_bak"); + File.delete(ledgerPath); + newLedger = File(ledgerPath, "w"); + ledger = ledger.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 path, file; + path = (dir +/+ ".." +/+ "resources" +/+ uid +/+ uid ++ "_mus_model" ++ ".json").standardizePath; + file = File(path, "r"); + pSeq = pSeq.add([msgInterpret.value(file.readAllString.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); + 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)); + //Out.ar([0, 1], sig1 * EnvGen.kr(Env.asr(dur, 0.3, 1), 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/supercollider/seeds_and_ledgers_main_dict.scd b/supercollider/seeds_and_ledgers_main_dict.scd new file mode 100644 index 0000000..5b87524 --- /dev/null +++ b/supercollider/seeds_and_ledgers_main_dict.scd @@ -0,0 +1,727 @@ +( +// 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; + +// 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, seed; + 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, model["dur_seed"]); +}; + +genOrders = {arg minMotifLength = 1, maxMotifLength = 5, minProgLength = 0, maxProgLength = 5; + ((maxMotifLength - minMotifLength).rand + minMotifLength).collect({ + var noProgIns, noSusIns, noSilentIns, prog, sus, silent; + 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 ranges, stepScore, recentlySoundedScore, isInRangeScore, regScore, hdScore; + + ranges = model["ranges"]; + //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 = model["passages_weights"]; + + //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 = []; + + model["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}); + model = Dictionary.with(*nameSpaces.collect({arg nS; 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, refUID, musPath, modelString; + msg.postln; + + path = msg[1].asString; + + loadModelFile.value(path); + + //refUID.postln; + refUID = model["ref_uid"]; + + 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"]); + }); + + # entrancesDurFunc, passagesDurFunc, exitsDurFunc = ["entrances", "passages", "exits"].collect({arg nsPre; + var probsVals = model[nsPre + "_probs_vals"]; + genDurFunc.valueArray(probsVals[..2] ++ [probsVals[3..]]); + }); + + /* + 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, model["order_seed"]).valueArray(orderSize ++ passagesSize); + //addr.sendMsg("/order", stringifyToDepth.value(orders, 1)); + }); + seq = seedFunc.value(genMotif, model["motif_seed"]).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; + model["cur_uid"] = curUID; + 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/supercollider/seeds_and_ledgers_transcriber.scd b/supercollider/seeds_and_ledgers_transcriber.scd new file mode 100644 index 0000000..4288a42 --- /dev/null +++ b/supercollider/seeds_and_ledgers_transcriber.scd @@ -0,0 +1,324 @@ +( +var formatMusicData, spellingDict, lyNoteNameStr, lyOctStr, lyFinalizeMusic, lyMeasureDef, +lyRelMark, lyRelMarkNote, lyHBracket, lyStaffDef, lyTie, +lyNoteName, lyCentDev, lyFreqRatio, lyDur, lyNote, lyBeamOpen, lyBeamClosed, +consolidateNotes, consolidateRests, +primes, hsArrayToFreq, hsArraysToFreqRatio; + +primes = [[2, 1], [3, 2], [5, 4], [7, 4], [11, 8], [13, 8]]; + +hsArrayToFreq = { + arg array; + array.collect({arg dim, d; pow(primes[d][0]/primes[d][1], dim)}).product +}; + +hsArraysToFreqRatio = { + arg array1, array2; + var fArray, num, den, gcd; + fArray = array2 - array1; + num = 1; + den = 1; + fArray.do({arg dim, d; + if(dim > 0, { + num = num * pow(primes[d][0], dim.abs); + den = den * pow(primes[d][1], dim.abs); + }); + if(dim < 0, { + num = num * pow(primes[d][1], dim.abs); + den = den * pow(primes[d][0], dim.abs); + }); + }); + gcd = gcd(num.asInteger, den.asInteger); + [num / gcd, den / gcd].asInteger +}; + +// formats the data for the transcriber +formatMusicData = {arg seq; + var maxSize, voices, durs, baseData, musicData; + maxSize = 0; + # voices, durs = seq.flatten2(seq.maxDepth - 5).flop; + + baseData = voices.flop.collect({arg voice, v; + var clumps, hdScores, freqs, fDurs, refs; + + //this gets the reference instrument and is another way to check things + refs = voice.collect({arg item, i; + var ref = [-1, [1, 1]]; + if((i > 0), { + if((item != voice[i - 1]) && (item != ["Rest"]), { + var ins; + ins = voices[i].minIndex({arg hsArray, h; + var res = 100000; + if((h != v) && (hsArray != ["Rest"]), {res = (hsArray.drop(1) - item.drop(1)).abs.sum}); + res + }); + if(voices[i][ins] != ["Rest"], { + ref = [ins, hsArraysToFreqRatio.value(voices[i][ins], item)] + }, { + ref = [ins, [100, 100]] + }) + }); + }); + ref + }); + + clumps = voice.separate({arg a, b; a != b }); + freqs = clumps.collect({arg clump; if(clump[0] != ["Rest"], {(60.midicps * hsArrayToFreq.value(clump[0]))/*.cpsmidi.round(0.25).midicps*/}, {-1})}); + fDurs = durs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump.sum}); + refs = refs.clumps(clumps.collect({arg clump; clump.size})).collect({arg clump; clump[0]}); + [freqs, (fDurs / 0.125).round, refs].flop; + }); + + musicData = baseData.collect({arg partData, p; + var res; + res = partData.collect({arg item, i; + var freq, dur, ref, amp, sus, note; + //# freq, dur, amp, mult, insRef = item; + # freq, dur, ref = item; + sus = dur.asInteger; + note = sus.collect({[freq, ref, i]}); + //rest = if(p < rawMusicData.size, {(dur - sus).collect({[-1, -1, -1, i]})}, {[]}); + //note ++ rest + note + }).flatten; + if(res.size > maxSize, {maxSize = res.size}); + res + }); + + //make them all the same length + maxSize = maxSize.trunc(64) + 64; + musicData = musicData.collect({arg partData, p; partData.extend(maxSize, partData.last)}); + musicData +}; + +// constants (spelling dictionary note names and octaves) +spellingDict = Dictionary.with(* + [ + \major -> Dictionary.with(* + [0, 7, 2, 9, 4, 11].collect({arg pc; pc->\sharps}) ++ + [5, 10, 3, 8, 1, 6].collect({arg pc; pc->\flats}) + ), + \minor -> Dictionary.with(* + [9, 4, 11, 6, 1, 8].collect({arg pc; pc->\sharps}) ++ + [2, 7, 0, 5, 10, 3].collect({arg pc; pc->\flats}) + ) + ] +); + +//define staff +lyStaffDef = {arg name, nameShort, nameMidi; + "\\new Staff = \"" ++ name ++ "\" \\with { \n" ++ + "instrumentName = \"" ++ name ++ "\" \n" ++ + "shortInstrumentName = \"" ++ nameShort ++ "\" \n" ++ + "midiInstrument = #\"" ++ nameMidi ++ "\" \n" ++ + "\n}\n" +}; + +// add music preamble +lyFinalizeMusic = {arg lyStr, part, name, nameShort, nameMidi, clef; + "\\new StaffGroup \\with {\\remove \"System_start_delimiter_engraver\"}\n<<\n" ++ + lyStaffDef.value(name, nameShort, nameMidi) ++ + "<<\n\n{ " + + "\n\\set Score.markFormatter = #format-mark-box-numbers " + + "\\tempo 2 = 60\n" + + "\\numericTimeSignature \\time 2/2\n" + + "\\clef " ++ clef ++ "\n" ++ lyStr + "\\fermata" + + " }>> \\bar \"|.\" \n} \n\n>>" ++ + "\n>>" +}; + +// barline and ossia definition +lyMeasureDef = {arg insName, part, beat; + var barline = "|", break = ""; + barline = "\\bar \"|\""; + if((beat % 16) == 0, {break = "\\break \\noPageBreak"}); + if((beat % (16 * 3)) == 0, {break = "\\pageBreak"}); + if(beat != 0, {"}\n>>\n" + barline + break}, {""}) + "\n<<\n" /*++ ossia*/ + "{" +}; + +lyNoteNameStr = Dictionary.with(* + [ + \sharps -> ["c", "cis", "d", "dis","e", "f", "fis", "g", "gis", "a", "ais", "b"], + \flats -> ["c", "des", "d", "ees","e", "f", "ges", "g", "aes", "a", "bes", "b"], + ] +); + +lyOctStr = [",,", ",", "", "'", "''", "'''", "''''"]; + +lyTie = {"~"}; + +lyNoteName = {arg freq, spellingPref = \sharps; + if(freq != -1, { + lyNoteNameStr[spellingPref][((freq.cpsmidi).round(1) % 12)] ++ + lyOctStr[(((freq).cpsmidi).round(1) / 12).asInteger - 2]; + },{"r"}); +}; + +lyDur = {arg noteLength; + switch(noteLength, 1, {"16"}, 2, {"8"}, 3, {"8."}, 4, {"4"}); +}; + +lyBeamOpen = {"["}; + +lyBeamClosed = {"]"}; + +lyCentDev = {arg freq, padding = true; + var centDev; + centDev = ((freq.cpsmidi - (freq.cpsmidi).round(1)) * 100).round(1).asInteger; + "^\\markup { " ++ if(padding, {"\\pad-markup #0.2 \""}, {"\""}) ++ + if(centDev >= 0, {"+"}, {""}) ++ centDev.asString ++ "\"}" +}; + +lyFreqRatio = {arg freqRatioMult, ref, padding = true, lower = 3, attachedToNote = true; + var res, ratio; + res = "\\markup {" + if(attachedToNote, {""}, {"\\normalsize"}) + + "\\lower #" ++ lower + if(padding, {"\\pad-markup #0.2 "}, {" "}); + ratio = "\"" ++ freqRatioMult[0].asInteger ++ "/" ++ freqRatioMult[1].asInteger ++ "\" }"; + res = if(ref != nil, + { + res ++ "\\concat{ \"" ++ ["IV", "III", "II", "I"][ref] ++ "\"\\normal-size-super " ++ ratio ++ "}" + }, { + res ++ ratio + } + ); + if(attachedToNote, {"_" ++ res}, {res}) +}; + +lyNote = {arg freq, noteLength, freqRatioMult, ref, spellingPref = \sharps, addMarkup = true, frHide = false, padding = true; + lyNoteName.value(freq, spellingPref) ++ + lyDur.value(noteLength) ++ + if(addMarkup, { + "" + }, {""}) +}; + +consolidateNotes = {arg lyStr, part; + var noteRegex, markupRegex, fullNoteRegex, restRegex, fullRestRegex, res; + noteRegex = "(?[a-g](?:es|is)?(?:[,']*?)?4)"; + markupRegex = if(part != 0, {"()?"}, {"()?"}); + fullNoteRegex = noteRegex ++ markupRegex ++ "(?:\\h+~\\h+\\k)"; + restRegex = "(?r4)"; + fullRestRegex = "(?r4)(?:(\\h+)\\k)"; + res = lyStr; + [6, 4, 3, 2].do({arg len; + [fullNoteRegex, fullRestRegex].do({arg regex; + res.findRegexp(regex ++ "{" ++ (len-1) ++ "}").clump(3).do({arg match; + var word, note, markup, lyDur; + word = match[0][1]; + note = match[1][1]; + markup = match[2][1]; + lyDur = switch(len, 6, {"1."}, 4, {"1"}, 3, {"2."}, 2, {"2"}); + res = res.replace(word, note.replace("4", lyDur) ++ markup)}); + }); + }); + res.replace("", ""); +}; + +~transcribe = {arg rawMusicData; + var basePath, scoreFile, musicData, insData, insNames, insNamesShort, insMidi, insClef; + + basePath = thisProcess.nowExecutingPath.dirname +/+ "lilypond"; + basePath.mkdir; + (basePath +/+ "includes").mkdir; + + //scoreFile = File(basePath +/+ "tkam_score.ly".standardizePath,"w"); + //scoreFile.write(File.readAllString(basePath +/+ ".." +/+ "template" +/+ "tkam_score_template.ly").replace("seed: xxx", "seed: " ++ seed)); + //scoreFile.close; + + musicData = formatMusicData.value(rawMusicData); + + insData = [ + ["IV", "IV", "clarinet", "bass"], + ["III", "III", "clarinet", "alto"], + ["II", "II", "clarinet", "treble"], + ["I", "I", "clarinet", "treble"] + ]; + + insNames = insData.slice(nil, 0); + insNamesShort = insData.slice(nil, 1); + insMidi = insData.slice(nil, 2); + insClef = insData.slice(nil, 3); + + musicData.do({arg part, p; + var lyFile, lyStr, lastMusAtom, measureCount, spellingPref, + tmpSectionData, pcRoot, partLookup, quality; + + //create file + lyFile = File((basePath +/+ "includes" +/+ "part_" ++ ["IV", "III", "II", "I"][p] ++ ".ly").standardizePath,"w"); + + //start lypond directives + lyStr = ""; + lastMusAtom = nil; + measureCount = 0; + spellingPref = \sharps; + tmpSectionData = nil; + part.clump(4).do({arg beat, i; + var gSum; + gSum = 0; + beat.separate({arg a, b; + ((a[0] != -1) || (b[0] != -1)) && (a != b)}).do({arg group, g; + var noteLength, curMusAtom, freq, freqRatioMult, ref, isSame, isRest, isFirst, isLast, + isTied, isMeasureBound, isBeamStart, isBeamEnd; + + noteLength = group.size; + gSum = gSum + noteLength; + curMusAtom = group[0]; + freq = curMusAtom[0]; + //freqRatioMult = curMusAtom[1]; + ref = curMusAtom[1][0]; + freqRatioMult = curMusAtom[1][1]; + # isSame, isRest, isFirst, isLast = [curMusAtom == lastMusAtom, freq == -1, g == 0, gSum == 4]; + # isTied, isMeasureBound = [isSame && isRest.not, isFirst && ((i % 4) == 0)]; + # isBeamStart, isBeamEnd = [(noteLength != 4) && isFirst, (noteLength != 4) && isLast]; + + //add ties + if(isTied, {lyStr = lyStr + lyTie.value}); + + //add barline and ossia definition + //if(isMeasureBound, {lyStr = lyStr + "\\bar \"|.|\""}); //lyMeasureDef.value(sectionData[i], insNames[p], p, i)}); + if(isMeasureBound, {lyStr = lyStr + lyMeasureDef.value(insNames[p], p, i)}); + + //add note data + /* + if(sectionData[i] != nil, { + tmpSectionData = sectionData[i]; + }); + if(isTied.not, { + partLookup = if((p != 0) || [1, 2, 3].includes(ref).not , {p}, {ref}); + pcRoot = ((tmpSectionData[0][partLookup][3].cpsmidi).round(1) % 12).asInteger; + quality = if(tmpSectionData[0][partLookup][1][2] == [[ 1, 5 ], [ 1, 2, 2 ]], {\major}, {\minor}); + spellingPref = spellingDict[quality][pcRoot]; + if(p == 0, {[(i / 4).asInteger, partLookup, pcRoot, quality]}); + }); + */ + + //lyStr = lyStr + lyNote.value(freq, noteLength, freqRatioMult, ref, spellingPref, isSame.not && isRest.not); + lyStr = lyStr + lyNote.value(freq, noteLength, freqRatioMult, ref, \sharps, isSame.not && isRest.not); + + //beam group + if(isBeamStart, {lyStr = lyStr ++ lyBeamOpen.value}); + if(isBeamEnd, {lyStr = lyStr ++ lyBeamClosed.value}); + + lastMusAtom = curMusAtom; + }); + }); + + //wrap music and add staff definitions + lyStr = lyFinalizeMusic.value(lyStr, p, insNames[p], insNamesShort[p], insMidi[p], insClef[p]); + + //consolidate notes and rests + lyStr = consolidateNotes.value(lyStr, p); + + //write file + lyFile.write(lyStr); + lyFile.close; + }); +}; + + +~transcribe.value(~seq); + +) \ No newline at end of file