├── .gitignore ├── 22nds-maja-kraljic ├── samples │ ├── air │ │ └── air.wav │ ├── drop │ │ └── drop.wav │ └── sonar │ │ └── sonar.wav └── scratch.tidal ├── CODE_OF_CONDUCT.md ├── README.md ├── alexandra-cardenas └── FromScratchBehindTheScreensCCU.tidal ├── alicef └── source.orca ├── cappelnord ├── Readme.md ├── mc-behind-the-screens.scd └── mc-init.scd ├── digitalselves └── from-scratch.tidal ├── earth_to_abigail └── LiveCodingEarthToAbigail - BehindTheScreen.rb ├── eerie_ear └── ccu.tidal ├── eloi └── code.tidal ├── heavy-lifting └── 210609 behind the screens.tidal ├── hellocatfood ├── README.md └── hellocatfood.tidal ├── jia-liu ├── ireadthat.scd └── iwrite.scd ├── joana-chicau ├── README.md └── choreo-code-in-10-minutes.js ├── jobi ├── README.md ├── ccu.js └── ccu.tidal ├── jon ├── 10minuteCCU.scd ├── 10minute_plumbing.scd └── README.md ├── jonreus └── README.md ├── kesson ├── README.md └── s_200601_livecoding_3 │ ├── s_200601_livecoding_3.pde │ └── sketch.properties ├── luka-princic └── behind_the_screens_performance_notes.scd ├── narcode ├── 10-min-narcodish.sc ├── README.md └── pz_beat_machine.sc ├── nescivi ├── code-livecode-live-29-06-2020-performance-code-buffer.scd └── code-livecode-live-29-06-2020-performance-history-transcript.scd ├── raphael-bastide ├── README.md ├── bts.html ├── css │ └── cascade.css └── js │ ├── Tone.js │ ├── cascade.js │ ├── debug.js │ ├── download.js │ ├── instruments.js │ ├── interface.js │ └── live-shortcut.js ├── roald-vandillewijn ├── Mercury.txt └── README.md ├── sasj ├── .DS_Store ├── CCU_10minlivecoding.js └── README.md ├── sonologico ├── README.md ├── gen.ml ├── helper.ml └── m10.ml └── t.mo └── 10-min-session-in-mercury.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | **/.DS_Store -------------------------------------------------------------------------------- /22nds-maja-kraljic/samples/air/air.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netherlands-coding-live/community-code/9c717ea94e27e2891de1afee6643b8e6ec89daaa/22nds-maja-kraljic/samples/air/air.wav -------------------------------------------------------------------------------- /22nds-maja-kraljic/samples/drop/drop.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netherlands-coding-live/community-code/9c717ea94e27e2891de1afee6643b8e6ec89daaa/22nds-maja-kraljic/samples/drop/drop.wav -------------------------------------------------------------------------------- /22nds-maja-kraljic/samples/sonar/sonar.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netherlands-coding-live/community-code/9c717ea94e27e2891de1afee6643b8e6ec89daaa/22nds-maja-kraljic/samples/sonar/sonar.wav -------------------------------------------------------------------------------- /22nds-maja-kraljic/scratch.tidal: -------------------------------------------------------------------------------- 1 | -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | -- Hello from sunny Slovenia. 3 | -- We just started our third lockdown ;) 4 | 5 | -- Playing live: 22nds / Maja Kraljic 6 | -- Instructions: Close your eyes and listen 7 | -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 | 9 | setcps(130/60/4) 10 | 11 | xfadeIn 1 8 $ loopAt 1 $ s "sonar" # orbit 1 # gain 1.4 # room 0.4 #delay 0.1 12 | xfadeIn 2 8 $ loopAt 2 $ s "sonar" # orbit 2 # gain 1.4 # room 1 13 | 14 | xfadeIn 1 6 $ silence 15 | xfadeIn 2 6 $ silence 16 | 17 | xfadeIn 3 6 $ loopAt 32 $ chop 32 $ s "air" # delay 0.4 # room 0.2 18 | xfadeIn 3 6 $ loopAt 16 $ chop 16 $ s "air" # delay 0.4 # room 0.2 19 | xfadeIn 3 6 $ loopAt 2 $ chop 2 $ s "air" # delay 0.4 # room 1 20 | 21 | setcps(130/60/4) 22 | setcps(20/60/4) 23 | 24 | xfadeIn 3 6 $ silence 25 | 26 | xfadeIn 4 12 $ loopAt 24 $ chop 24 $ s "air" # delay 0.8 # room 0.3 # hpf 500 27 | 28 | xfadeIn 4 6 $ loopAt 8 $ chop 8 $ s "drop" # room 0.6 29 | 30 | xfadeIn 4 16 $ silence 31 | 32 | xfadeIn 6 4 $ loopAt 3 $ s "sonar" # delay 1 # room 0.9 33 | 34 | xfadeIn 6 16 $ silence -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at netherlands-coding-live@protonmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 💻 Community Code 2 | 3 | A repository filled with code shared by the community during coding sessions and from-scratch challenges as part of the *Behind the Screens* series. 4 | 5 | ## ⌛️ Coming soon... 6 | 7 | Behind the Screens Season 3 will continue [**here**](https://github.com/creativecodingutrecht/community-code) 8 | 9 | 10 | ## 👋 The Community 11 | 12 | - Raphaël Bastide: [*@raphaelbastide*](https://raphaelbastide.com/) 13 | - Lucy Cheesman : [*@Heavy Lifting*](https://heavy-lifting.org/) 14 | - Jia Liu : [*@luiiuuuiiiii*](https://twitter.com/luiiuuuiiiii) 15 | - Francesco Corvi : [@nesso](https://www.instagram.com/nesso.xyz/) 16 | - Alfonsofonso : [*@alfonsofonso*](https://alfonsofonso.bandcamp.com/) 17 | - Eloi Isern : [*@eloielbonnoi*](https://twitter.com/eloielbonnoi) 18 | - Patrick Borgeat : [*@cappelnord*](https://twitter.com/cappelnord) 19 | - Luka Prinčic : [*lukaprincic.si*](https://lukaprincic.si) / [*@luka@sonomu.club*](https://sonomu.club/@luka) 20 | - Alexandra Cárdenas: [*@tiemposdelruido*](https://www.instagram.com/tiemposdelruido/) 21 | - Maja Kraljic: [*22nds*](https://www.22nds.com) / [*22nds* on GitHub](https://github.com/22nds) 22 | - d͓̽i͓̽g͓̽i͓̽t͓̽a͓̽l͓̽ ͓̽s͓̽e͓̽l͓̽v͓̽e͓̽s͓̽ : [*@dgtlselves*](https://www.instagram.com/dgtlselves/) 23 | - Riccardo Ancona: [*@olbos_*](https://www.instagram.com/olbos_/) 24 | - Carolien Teunisse: [*@lucidlien*](https://www.deframe.nl/about/carolien-teunisse/) 25 | - Sabrina Verhage: [*@SabrinaVerhage*](http://www.sabrinaverhage.com/) 26 | - Rafaele Andrade: [*@rafaeleandrade*](https://www.rafaeleandrade.com/) 27 | - Marije Baalman: [*@nescivi*](https://marijebaalman.eu) / [*@sensestage* on github](https://github.com/sensestage/) 28 | - Roald van Dillewijn : [*@roaldvdillewijn*](https://www.roaldvandillewijn.nl) 29 | - Saskia Freeke : [*@sasj_nl*](https://www.instagram.com/sasj_nl/) 30 | - Giovanni Muzio : [*@kesson*](https://kesson.io) 31 | - Joana Chicau : [@BChicau](https://www.joanachicau.com/) 32 | - Jo Kroese : [*@jobi*](https://jokroese.com) 33 | - Jonathan Reus : [@jc_reus](https://twitter.com/jc_reus) 34 | - Felipe Ignacio Noriega : [*@0felipeignaci0*](https://twitter.com/0felipeignaci0) 35 | - Raphael Sousa Santos : [*@sonologico*](https://sonologi.co) 36 | - Timo Hoogland : [*@tmhglnd*](https://www.timohoogland.com) 37 | - Sebastian Pappalardo : [*@eerieear*](https://www.instagram.com/eerieear/) 38 | - Antonio Roberts : [*hellocatfood*](https://hellocatfood.com) 39 | - Devine Lu Linvega : [*@alicef*](https://wiki.xxiivv.com/) 40 | 41 | ## 💬 Behind the Screens (Interviews) 42 | 43 | - [Lucy Cheesman (Heavy Lifting)](https://medium.com/behind-the-screens-challenge/behind-the-screens-heavy-lifting-ddcbda2d374) 44 | - [Jia Liu](https://medium.com/behind-the-screens-challenge/behind-the-screens-jia-liu-44aa001b48cf) 45 | - [Francesco Corvi (Nesso)](https://medium.com/behind-the-screens-challenge/behind-the-screens-nesso-7b68cb70d594) 46 | - [Alfonsofonso](https://medium.com/behind-the-screens-challenge/behind-the-screens-alfonsofonso-d972b786493) 47 | - [Eloi Isern (Eloi el Bon Noi](https://medium.com/behind-the-screens-challenge/behind-the-screens-eloi-el-bon-noi-90a84019966) 48 | - [Patrick Borgeat](https://medium.com/behind-the-screens-challenge/behind-the-screens-patrick-borgeat-2df8e86751e8) 49 | - [Luka Prinčic](https://medium.com/behind-the-screens-challenge/behind-the-screens-luka-prin%C4%8Di%C4%8D-ef748e9096d4) 50 | - [Alexandra Cárdenas](https://medium.com/behind-the-screens-challenge/behind-the-screens-alexandra-c%C3%A1rdenas-faef92150f7f) 51 | - [Maja Kraljic](https://medium.com/behind-the-screens-challenge/behind-the-screens-maja-kralji%C4%8D-74ce12b14fbf) 52 | - [Lizzy Wilson (Digital Selves)](https://medium.com/behind-the-screens-challenge/behind-the-screens-digital-selves-8d89460baa61) 53 | - [Riccardo Ancona (Olbos)](https://medium.com/behind-the-screens-challenge/behind-the-screens-olbos-2d30f8eae0be) 54 | - [Carolien Teunisse](https://medium.com/the-aesthetics-of-creative-coding/behind-the-screens-carolien-teunisse-10c079edd10a) 55 | - [Sabrina Verhage](https://medium.com/the-aesthetics-of-creative-coding/behind-the-screens-sabrina-verhage-5548fcbb811b) 56 | - [Rafaele Andrade](https://medium.com/the-aesthetics-of-creative-coding/behind-the-screens-rafaele-andrade-6e622467750d) 57 | - [Marije Baalman](https://medium.com/the-aesthetics-of-creative-coding/behind-the-screens-marije-baalman-559ca3f1696b) 58 | - [Roald van Dillewijn](https://medium.com/the-aesthetics-of-creative-coding/behind-the-screens-roald-van-dillewijn-f42de690c86) 59 | - [Saskia Freeke](https://medium.com/the-aesthetics-of-creative-coding/behind-the-screens-sasj-cf739281cb9f) 60 | - [Giovanni Muzio (Kesson)](https://medium.com/the-aesthetics-of-creative-coding/behind-the-screens-kesson-a7f8e0a870e4) 61 | - [Joana Chicau](https://medium.com/the-aesthetics-of-creative-coding/behind-the-screens-joana-chicau-867d46a273d4) 62 | - [Jo Kroese (Jobi)](https://medium.com/the-aesthetics-of-creative-coding/behind-the-screens-jobi-f899f73ee420) 63 | - [Jonathan Reus](https://medium.com/the-aesthetics-of-creative-coding/behind-the-screens-jonathan-reus-f9126d4b5462) 64 | - [Felipe Ignacio Noriega](https://medium.com/the-aesthetics-of-creative-coding/behind-the-screens-narcode-df6737fc6941) 65 | - [Raphael Sousa Santos (Sonologico)](https://medium.com/the-aesthetics-of-creative-coding/behind-the-screens-sonologico-13fc200fe26e) 66 | - [Timo Hoogland](https://medium.com/the-aesthetics-of-creative-coding/behind-the-screens-t-mo-c139e3de2a0) 67 | - [Sebastian Pappalardo (Eerie_ear)](https://medium.com/the-aesthetics-of-creative-coding/behind-the-screens-eerieear-5582b6775f8a) 68 | 69 | ## 📟 Behind the Screens (Videos) 70 | 71 | - [Behind the Screens Season 1](https://www.youtube.com/playlist?list=PLPkgr1U1fB_6yQ5tBff927auOUnu57Uhf) 72 | - [Behind the Screens Seaons 2](https://www.youtube.com/playlist?list=PLPkgr1U1fB_5fofmP6osJM0nvxUvRG3_N) 73 | 74 | ## 📝 Contribution 75 | 76 | 1. Fork this repository (click `fork` in the top right) 77 | 2. Clone the repository to your computer `git clone https://github.com//.git` 78 | 3. Branch the Fork `git checkout -b ` 79 | 4. Add a folder with your `name-lastname` or `artistname` and put in all your coded files 80 | 5. Add your name and link to the `README.md` under [The Community](#the-community) section 81 | 6. Add, commit and push your changes `git add .` `git commit -a` `git push origin ` 82 | 7. Go to your forked repo in the browser and click `compare & pull request`, then `create pull request` 83 | 84 | [All steps with examples and images](https://github.com/firstcontributions/first-contributions/blob/master/README.md) 85 | 86 | ## 📄 Code of Conduct 87 | 88 | **Our Pledge** 89 | 90 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. 91 | 92 | [Read the full Code of Conduct](/CODE_OF_CONDUCT.md) 93 | -------------------------------------------------------------------------------- /alexandra-cardenas/FromScratchBehindTheScreensCCU.tidal: -------------------------------------------------------------------------------- 1 | 2 | setcps 1.5 3 | 4 | d1 $ stack [ whenmod 4 2 (const silence) $ sometimes (juxBy 0.3 (iter 4)) $ sometimes (density 0.5) $ sound "scratch*2" 5 | # n (irand 30) 6 | # speed (choose [-1]) 7 | # pan rand 8 | # vowel "u o i a" 9 | # gain 1.2, 10 | whenmod 5 1 (const silence) $ sound "dmsynth" 11 | # speed (choose [-1]) 12 | # sustain (choose [1]) 13 | # pan (rand)] 14 | 15 | hush 16 | -------------------------------------------------------------------------------- /alicef/source.orca: -------------------------------------------------------------------------------- 1 | seq 2 | 3 | ........wC8.................................... 4 | .gC5.....38TCFEDDBAB........................... 5 | ..0B3......D................................... 6 | ...33T024..J................................... 7 | .....0YYY0AD................................... 8 | ........aVD.................................... 9 | 10 | drm0 11 | 12 | ................................ 13 | ...Cg......2Cg.................. 14 | ...eF4......fF2................. 15 | ...J.:42C.....:22e.............. 16 | ...eF6.......................... 17 | .....:42c....................... 18 | ................................ 19 | ...C8.........C4................ 20 | ...6B4........2B2............... 21 | ....2.X*.......0.X*............. 22 | ........*........*..:02f........ 23 | ........J.:82f....:02a.......... 24 | ........*:92g................... 25 | ................................ 26 | ................................ 27 | 28 | drm1 29 | 30 | ................................ 31 | .C8............................. 32 | .0B4............................ 33 | ..4XE......gC2....D4............ 34 | .......E...:12e...*:42C......... 35 | ......E.E..:22e................. 36 | .....E...E.:12g................. 37 | ....E....*.:22e................. 38 | ...E......*:22e................. 39 | ................................ 40 | ................................ 41 | ................................ 42 | ................................ 43 | ................................ 44 | ................................ 45 | 46 | drm2 47 | 48 | ................................ 49 | ......2Cg....................... 50 | ..3U8..egTAaEa.E.AE..aDgE....... 51 | ....Y.:c2E...................... 52 | .......Cg....................... 53 | ..aUg..cgTAaEa.E.Aa.gae.a....... 54 | ...*Y*:52e...................... 55 | ................................ 56 | ......2Cg....................... 57 | ..3Ug..egTAaEa.E.Aac.ae.a....... 58 | ....Y.:62a...................... 59 | ......4Cg....................... 60 | ..2U6..7gTAaEa.E.Aa.faeca....... 61 | ....Y.:92A...................... 62 | ................................ 63 | 64 | drm3 65 | 66 | ................................ 67 | ................................ 68 | ........gC8..........4C8........ 69 | .......2M3C8........2M6C8....... 70 | ......3A6A5C6......3AcA6C6...... 71 | .....4A9AbA4Cg....4AfAiA2Cg..... 72 | ......dAkAfAe......jAxAkAc...... 73 | ....C4.xAzAt....2Cg.gAhAw....... 74 | ....1D4.wAs......cUg.xAd........ 75 | .2Cg..:02o....4Cg..:81a......... 76 | ..cYcUw..J.....eYeUg..J......... 77 | ......:a7o.........:c2a......... 78 | ................................ 79 | ................................ 80 | ................................ 81 | 82 | syn0 83 | 84 | ................................ 85 | ................................ 86 | ......2C8....................... 87 | .....3X6........................ 88 | ..C8............................ 89 | ..48T*.**.**.................... 90 | .......Va....................... 91 | ....:16C........................ 92 | ..3U4.JJ........................ 93 | ...*:c6C........................ 94 | ................................ 95 | ................................ 96 | ................................ 97 | ................................ 98 | ................................ 99 | 100 | syn1 101 | 102 | ................................ 103 | ......C3.....4C3................ 104 | ......2A4.....0A4............... 105 | .....1X6.....4X4................ 106 | ...D2..Va....................... 107 | ...*:c6D........................ 108 | ................Va.............. 109 | ...........D4.2AD............... 110 | ............:04F................ 111 | ................................ 112 | ................................ 113 | ................................ 114 | ................................ 115 | ................................ 116 | ................................ 117 | 118 | syn2 119 | 120 | ................................ 121 | ....C6.......................... 122 | ....3B3......................... 123 | .....0M2........................ 124 | ......0......................... 125 | ......J.Va...................... 126 | ......0AE....................... 127 | .....3XE........................ 128 | ...C6........................... 129 | ...3B3.......................... 130 | ..D20A3......................... 131 | ...:73E......................... 132 | ..D4..J......................... 133 | ...:35E......................... 134 | ................................ 135 | 136 | syn3 137 | 138 | ................................................ 139 | ..Cg............................................ 140 | ..9B8........................................... 141 | ...1M7.......................................... 142 | ....7.XS........................................ 143 | .............S.................................. 144 | ......S......................................... 145 | .............S.................................. 146 | ................Va..S........................Va. 147 | .............:93E..........S..Va...........2AE.. 148 | ...............Va......Va..:35E...S......:36G... 149 | ............:35E....:35E..............Va........ 150 | .........Va........*.........Va.....2AE......... 151 | ......:06E............Va..:37E....:07G.......... 152 | ...................:37E......................... 153 | -------------------------------------------------------------------------------- /cappelnord/Readme.md: -------------------------------------------------------------------------------- 1 | # A stochastic improvisation with fungal textures 2 | 3 | ## What you will need 4 | 5 | * [SuperCollider](https://supercollider.github.io/) + [sc3-plugins](http://supercollider.github.io/sc3-plugins/) 6 | * A clone of the [mushroom-clouds](https://github.com/cappelnord/mushroom-clouds) repository as a subfolder in this folder 7 | 8 | ## How to run the code 9 | 10 | * Open mc-behind-the-screens.scd 11 | * Execute the lines/brackets one after another. The last line (with ~runAgents) should start the music. You can now change the agents code while the piece is running. 12 | 13 | ## I want the visualizer as well 14 | 15 | * Open mc-init.scd and uncomment the two lines under VISUALIZER 16 | * Open MushroomCloudsViz in Processing 17 | * Run code as explained above 18 | 19 | If you have any questions or problems just get in touch! -------------------------------------------------------------------------------- /cappelnord/mc-behind-the-screens.scd: -------------------------------------------------------------------------------- 1 | // load the engine and fungi 2 | "mc-init.scd".loadRelative; 3 | 4 | //boot scsynth 5 | s.boot; 6 | 7 | // prepare synthdef and audio effects 8 | ( 9 | var times = 0!128; 10 | var thresh = 0.125; 11 | 12 | 13 | Ndef(\eno, {DC.ar(0!2)}).ar(2); 14 | 15 | Ndef(\mix, { 16 | var sig = Ndef(\eno).ar(2) * 2; 17 | var verb; 18 | sig = FbC({|fb| sig + (fb * 0.25)}, 2, 3/4/2) + sig; 19 | verb = JPverb.ar(sig, 5); 20 | sig + (verb * 0.2); 21 | }); 22 | 23 | Ndef(\mix).fadeTime = 5; 24 | Ndef(\mix).play; 25 | 26 | ~eno = {|num, vel=64, dur=1, x, y, p, agent| 27 | ((times[num] + thresh) <= TempoClock.default.beats).if({ 28 | 29 | Synth(\fmPling, [ 30 | \freq, num.midicps, 31 | \amp, vel.linexp(0, 128, -60.dbamp, 1) * num.linexp(50, 128, 1, -18.dbamp) * num.linexp(0, 60, -18.dbamp, 1), 32 | \pan, num.linlin(20, 90, 0, 0.6) * (num*0.2).sin, 33 | \len, dur, 34 | \modIndex, vel.linlin(0, 128, 2, 6), 35 | \attack, agent[\attMap].value(x, y, p, agent), 36 | \out, Ndef(\eno).bus 37 | ]); 38 | times[num] = TempoClock.default.beats; 39 | }); 40 | }; 41 | 42 | SynthDef(\fmPling, {|freq=440, out=0, pan=0, amp=0.1, len=8, modIndex=5, attack=0.001| 43 | var randomizedFreq = freq * Rand(0.995, 1.005); 44 | var mod = SinOsc.ar(freq*4.45 + Rand(0, 0.1)) * XLine.ar(freq * modIndex, 0.001, 0.1); 45 | var mod2 = SinOsc.ar(randomizedFreq*2) * XLine.ar(freq * 0.4, 0.001, 5); 46 | var sig = SinOsc.ar(randomizedFreq + mod + mod2, phase: 0.5pi) * AmpCompA.kr(randomizedFreq, (21+12).midicps); 47 | var ampModEnv = EnvGen.kr(Env([0, 0, 0.7], [1, len])); 48 | var ampMod = (1.0 - ampModEnv) + (SinOsc.ar(Rand(0.1, 0.8)) * ampModEnv); 49 | var env = EnvGen.ar(Env.perc(attack, len, 1, -2), doneAction: 2); 50 | Out.ar(out, Pan2.ar(sig * env * amp * ampMod, pan)); 51 | }).add; 52 | ) 53 | 54 | // program stochastic agents 55 | ( 56 | var activeAgents = 32; 57 | 58 | ~storeAllAgents.(); 59 | 60 | ~wAgents.do {|agent, i| 61 | 62 | var p1 = ~pFungus.("Sparassis crispa").pow(2); 63 | var p2 = ~pFungus.("Coprinellus disseminatus"); 64 | var p3 = ~pFungus.("Coprinellus micaceus"); 65 | 66 | var p = ~pPart.(0.5, p1, p2) * 1.4; 67 | 68 | p = p * ~pSineWindow.(0.4, 0.7) * ~pScale.([0, 5, 7]); 69 | 70 | p = p + (p2 * ~pSineWindow.(0.5, 0.2) * ~pScale.([0, 2, 7]) * 0.8 * ~pFungus.("Tremella mesenterica")); 71 | p = p + (p3 * ~pSineWindow.(0.8, 0.15) * ~pScale.(Scale.minorPentatonic) * 0.3); 72 | 73 | 74 | agent[\pPlay] = p; 75 | 76 | agent[\durMap] = Prand([0.5, 0.25, 2], inf); 77 | agent[\velMap] = ~defaultVelMap * 1.25 + {[5, 0, 0, 0, 0, 10 + 5.rand].choose}; 78 | agent[\quant] = 0.25; 79 | 80 | agent[\attMap] = {|x, y, p, agent| y.linexp(0, 1, 0.002, 0.0005) * 4 }; 81 | agent[\lenMap] = Prand([0.125, 0.5, 1, 0.75], inf) * 4; 82 | 83 | agent[\pRetry] = {|x, y, p, agent| 0.94 }; 84 | 85 | agent[\act] = ~eno; 86 | agent[\echo] = false; 87 | agent[\active] = i < activeAgents; 88 | }; 89 | ) 90 | 91 | // run for 10 minutes 92 | ~runAgents.(60 * 10, {|i| i * 0.5}); 93 | 94 | /* 95 | "Agaricus sp." "Sparassis crispa" "Lycoperdon excipuliforme" 96 | "Coprinellus micaceus" "Coprinellus disseminatus" "Pleurotus ostreatus" 97 | "Clathrus archeri" "Coprinopsis picacea" 98 | "Laetiporus sulphureus" "Trametes versicolor" 99 | "Amanita rubescens" "Macrolepiota fuliginosa" 100 | "Fomitopsis pinicola" "Helvella lacunosa" "Pleurotus ostreatus Mycel" 101 | "Lepiota aspera" "Russula sp." "Xerocomellus sp." 102 | "Schizophyllum commune" "Tremella mesenterica" 103 | */ 104 | 105 | -------------------------------------------------------------------------------- /cappelnord/mc-init.scd: -------------------------------------------------------------------------------- 1 | ( 2 | "mushroom-clouds/mc-engine.scd".loadRelative; 3 | 4 | ~initWorld.(); 5 | 6 | // VISUALIZER 7 | // "mushroom-clouds/mc-viz.scd".loadRelative; 8 | // ~initViz.value("127.0.0.1", 57140, 6, 0.04, ~scanYFunc.value(1080)); 9 | 10 | ~initLoadFungi.(Document.current.dir ++ "/mushroom-clouds/fungi"); 11 | ~initAgents.(32); 12 | ) -------------------------------------------------------------------------------- /digitalselves/from-scratch.tidal: -------------------------------------------------------------------------------- 1 | setcps(155/120/2) 2 | 3 | -- choppy vocals 4 | d1 5 | $ striate "< 2 4 8 12 24 32 1 2>" 6 | $ sometimes (#acc "<-2 0.4>") 7 | $ sound "tekken-annoucer/4" 8 | #n (irand 8) 9 | 10 | 11 | -- drum pattern 12 | d2 13 | $ every 8 ((#hpf "400 800 1200 800").loopAt 1) 14 | $ stack [ 15 | sound "[k, bmkd:2](3,8,<0 1 4>)" #shape 0.45 #speed 0.8 #gain 1.1, 16 | gain "1*8?" #sound "amencutup" #n (irand 16), 17 | off 0.125 (+| n "0 1 2 5") $ struct "t(3,8)@2" 18 | $ n "<0 1 4>" # sound "[jung5 jung6 jung7]/8" #speed 8 #unit "c" #gain 1.1, 19 | stz 3 0.125 0.75 $ often (slow 4) $ sound "" #speed "<0.6 1>" 20 | #gain 0.8, 21 | gain "1 ~ [~ 1 ] ~" # sound "hatys" #n (irand 8), 22 | sometimes (fast 2 ) $ sound "cosmic:1(7,8,<0 1>)" #gain 1.1 #speed 0.5 23 | ] 24 | 25 | 26 | 27 | -- bass, melody etc 28 | do 29 | let notePat = "{[a4 c5] [~ a4] [d5 ] [a4 e5] [~ a4] [f5] [e5 d5] ~ [e5 f5] [~ d5] [e5] [c5 d5] [~ c5] [d5] [c5 b4] ~}%4" 30 | bassPat = "{a3 b3 [ ]}%1" 31 | highPat = "{e6 e6 [f6 f6] [~ e6] ~ ~ ~ ~ c6 c6 [d6 d6] [~ c6] ~ ~ ~ ~ }%4" 32 | pitch = 0 33 | all $ id 34 | -- all $ (#lpf "800 1200 2400 6000 4000") 35 | d3 36 | $ note (bassPat) # s "[ser2:1, ser2:0]" 37 | #end 0.8 #shape 0.45 |+| note "12" 38 | d3 39 | -- $ rarely (palindrome) 40 | $ often (off 0.125 (|+ note "12" )) 41 | $ note ( notePat ) 42 | # s "bmsy:2" 43 | #sus 0.4 #rel 0.4 #speed "[1,1.02]" 44 | |+| note (pitch) 45 | #lpf 2800 46 | d5 47 | -- $ rarely (palindrome) 48 | $ whenmod 24 20 (# speed "[1,1.02]") 49 | $ note (highPat) # s "ser:2" 50 | |+| note (pitch-24) 51 | -------------------------------------------------------------------------------- /earth_to_abigail/LiveCodingEarthToAbigail - BehindTheScreen.rb: -------------------------------------------------------------------------------- 1 | # Live Coding with Earth to Abigail 2 | 3 | # The voice samples used during the performance are taken 4 | # from YouTube videos created by Ted Nelson. 5 | 6 | # All sample names written in all caps are samples from my own collection, so 7 | # you'll need to replace them with other samples if you'd like to play around with the code :) 8 | 9 | 10 | UNSORTED_LIST = [96, 62, 98, 69, 84, 76, 82, 64, 74, 77, 94, 67, 53, 60, 55, 11 | 57, 81, 89, 79, 72, 52, 70, 58, 86] 12 | 13 | 14 | define :bubble_sort do |list, amp, sleep| 15 | 16 | arr = list.dup 17 | swapped = false 18 | r = arr.length - 2 19 | 20 | use_synth :sine 21 | while true 22 | for i in 0..r 23 | play arr[i], amp: rrand(0.4, amp), release: 0.1, 24 | decay: 0.1, pan: [-1, 1].tick, cutoff: 80 25 | sleep sleep 26 | if arr[i] > arr[i+1] 27 | arr[i], arr[i+1] = arr[i+1], arr[i] 28 | swapped = true if !swapped 29 | play arr[i], amp: amp, release: 0.1, 30 | pan: [-1, 1].tick, cutoff: 80 31 | sleep sleep 32 | end 33 | end 34 | 35 | swapped ? swapped = false : break 36 | end 37 | end 38 | 39 | use_bpm 90 40 | 41 | live_loop :time do 42 | sleep 1 43 | end 44 | 45 | with_fx :reverb, room: 0.9 do 46 | 47 | live_loop :sorting_sounds, sync: :harmonies do stop 48 | bubble_sort(UNSORTED_LIST, 0.5, 0.25) 49 | end 50 | 51 | live_loop :harmonies, sync: :pulsing do stop 52 | cue "speak_Ted" 53 | chords = [(chord :d4, :minor), (chord :f3, :major, invert: 2), 54 | (chord, :c4, :major), (chord :g3, :minor, invert: 2)] 55 | chords.each do |ch| 56 | with_fx :slicer, phase: [0.25, 0.5].choose, phase_slide: 8 do |sl| 57 | synth :beep, note: ch, sustain: 6, release: 1, 58 | decay: 1, attack: 0.2, amp: 0.7 59 | control sl, phase: [0.25, 0.5].choose 60 | sleep 8 61 | end 62 | end 63 | end 64 | 65 | live_loop :low_vibrations, sync: :harmonies do stop 66 | notes = [:d1, :f1, :c1, :g1] 67 | notes.each do |n| 68 | in_thread do 69 | p = synth :prophet, note: n, amp: 0, 70 | sustain: 8, cutoff: 60, cutoff_slide: 8 71 | control p, cutoff: 110 72 | 32.times do 73 | control p, note: (octs n, 3).tick 74 | sleep 0.25 75 | end 76 | end 77 | synth :dsaw, cutoff: 50, note: n, sustain: 6, 78 | release: 1, attack: 1 79 | sleep 8 80 | end 81 | end 82 | 83 | end 84 | 85 | with_fx :reverb, room: 0.5 do 86 | with_fx :compressor, pre_amp: 3 do 87 | 88 | live_loop :Ted_Nelson_speaks, sync: :time do stop 89 | sync "speak_Ted" 90 | t = TED.tick 91 | with_fx :echo, mix: 0.3, decay: 0.5 do 92 | sample t, amp: 1.2, attack: 0.5, release: 0.5 93 | sleep sample_duration(t) + rrand_i(16, 30) 94 | end 95 | end 96 | 97 | 98 | live_loop :pulsing, sync: :sorting_sounds do stop 99 | tick 100 | if look % 7 == 0 101 | sleep 16 102 | else 103 | 104 | in_thread do 105 | with_fx :bitcrusher, sample_rate: 1000, sample_rate_slide: 8 do |bc| 106 | sample DL[7], amp: 0, beat_stretch: 8 107 | control bc, sample_rate: 5000 108 | sleep 8 109 | end 110 | end 111 | in_thread do 112 | 2.times do 113 | 8.times do 114 | sample DL[7], amp: rrand(0.8, 1.2), onset: pick, 115 | rate: [1,1,1,1,1,-1].choose, pan: rrand(-1, 1) 116 | sleep [0.5, 1].choose 117 | end 118 | end 119 | end 120 | in_thread do 121 | 4.times do 122 | sample :bd_haus, cutoff: 90, amp: 1.2 123 | sleep 1.75 124 | sample :bd_haus, cutoff: 90, amp: 1 if one_in(3) 125 | sleep 0.25 126 | end 127 | end 128 | at [0.25, 0.75, 1.5, 2.25, 2.5, 2.75, 3.5, 4, 4.25, 4.75] do 129 | sample HH_CLOSED[0], rate: 2, amp: rrand(0.8, 1.2) 130 | end 131 | sleep 4 132 | end 133 | end 134 | 135 | end 136 | end 137 | 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /eerie_ear/ccu.tidal: -------------------------------------------------------------------------------- 1 | xfadeIn 1 2 silence 2 | -- $every 4 (juxBy 0.75 (|*speed "[2.5 4.5]")) 3 | -- $every 3 (juxBy 0.25 (|*speed "[0.5 1.5]")) 4 | -- $slow"[1 2 1 3]" 5 | $slow 8 6 | $ s"cinematic_score/[8 4]" 7 | |*shape 0.2 8 | |*gain 0.4 9 | 10 | d2 silence 11 | $ slow 4 12 | $ s "[iso_bss_bs_af*[16 8]]" 13 | |+n (run(16)) 14 | |*speed "[0.5 1 1.2 1]" 15 | |+ lpf 600 16 | |*shape 0.4 17 | |* speed "-0.2" 18 | |*gain 0.65 19 | 20 | xfadeIn 3 16 silence 21 | $slow "[2 1 4]" 22 | $s "[ee_ab_nm_s]" 23 | |+n (run(16)) 24 | |*speed "[0.5 -1 0.4 1]" 25 | -- |+ cut 1 26 | |+legato 4 27 | |+ lpf 1200 28 | |*shape 0.4 29 | |*gain 0.6 30 | -------------------------------------------------------------------------------- /eloi/code.tidal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netherlands-coding-live/community-code/9c717ea94e27e2891de1afee6643b8e6ec89daaa/eloi/code.tidal -------------------------------------------------------------------------------- /heavy-lifting/210609 behind the screens.tidal: -------------------------------------------------------------------------------- 1 | linput = pI "linput" 2 | 3 | lname = pS "lname" 4 | 5 | 6 | d2 $ slow 8 $ s "looper" # n "<0 5 2 4 3 7 6 1>" 7 | 8 | d2 silence 9 | 10 | d5 $ striate 4 $ sound "loop*4" # n "<0 1 2 3 4 5 6 7>" # gain 1.4 # speed "[1,0.8]" # cut 1 11 | 12 | d1 $ loopAt "<8 4>" $ chop "[<1 2 8>,4]" $ sound "vkloop:1*4" #cut 1 13 | 14 | d4 $ degradeBy 0.2 $ every 2 (fast 2) $ iter 4 $ sound "[bottle(<3 5 6>,8), ~ ~ bsperc:3 ~]" # cut 2 15 | 16 | d5 $ loopAt "[8,<4 16>]" $ chop 300 $ sound "zip" 17 | 18 | d5 silence 19 | 20 | hush 21 | -------------------------------------------------------------------------------- /hellocatfood/README.md: -------------------------------------------------------------------------------- 1 | The kick sample can be found in the spicule extra samples repository https://github.com/yaxu/spicule/tree/master/extra-samples 2 | -------------------------------------------------------------------------------- /hellocatfood/hellocatfood.tidal: -------------------------------------------------------------------------------- 1 | setcps(135/60/4) 2 | 3 | d1 4 | $ chunk 4 (fast 2) 5 | $ sound "bd bd bd bd" 6 | # shape 0.7 7 | # gain 0.9 8 | 9 | d2 10 | $ fast 4 11 | $ sound "~ hh*2" 12 | 13 | d3 14 | $ mask "< [f t] t f>" 15 | $ slow "2 1" 16 | $ jux ((rev) . (slow 2)) 17 | $ stutWith 3 (1/4) ((fast 2) . (# gain 0.7) . (# speed "1 2")) 18 | $ sound "~ perc:2(5,8)" 19 | # pan (perlin) 20 | # gain 0.98 21 | 22 | d4 23 | $ sometimes ((ply "<8 4>") . (# gain 0.8)) 24 | $ off 0.25 ((|+ note "12 7") . (# gain 0.8) . (slow 2)) 25 | $ slow "<2 1 [2 <1 0.125 1>]> 1" 26 | $ whenmod 8 4 ((|+ note "7") . (fast "[1 [8 2]] 1")) 27 | $ stut 3 0.25 0.75 28 | $ chunk 4 ((fast 2) . (|+ note "7")) 29 | $ note "c4 c d*2 c" 30 | # sound "gtr" 31 | # legato (fast 12 $ range 0.1 2.4 $ perlin) 32 | # gain 0.97 33 | 34 | d4 35 | $ sometimes ((ply "2 8") . (fast 4) . (# pan 0.6)) 36 | $ fast "<2 1 [2 1]> <1 2>" 37 | $ whenmod 8 4 ((|+ note "7") . (fast "1 2 1")) 38 | $ stut 3 0.25 0.35 39 | $ chunk 4 ((fast "4 2") .(|+ note "12 7")) 40 | $ note (slow "2 4" $ "[d >] [c [c e]] [e ] ") 41 | # sound "gtr" 42 | # legato (fast 3 $ range 0.5 2.4 $ sine) 43 | # gain 0.97 44 | 45 | d5 46 | $ juxBy (fast (range 1 8.3 $ sine) $ sine) ((hurry 2) . (# gain "0.6") . (# vowel "a e")) 47 | $ superimpose ((# gain 0.8) . (1.25 ~>) . (|+ note 12) . (# speed "<-1 -2>") . (fast "<2 [1 2 [<8 4> 1 1] 1] [4 2]>" ) . (stut 3 0.25 0.25) . (# pan (fast 9.2 $ perlin) )) 48 | $ whenmod 8 4 (|+ note "7") 49 | $ note "~ c d ~" 50 | # sound "bass1" 51 | # shape 0.4 52 | |+ note 12 53 | # legato 1 54 | 55 | d6 56 | $ chunk 4 (|+ note 12) 57 | $ whenmod 8 4 (|+ note "7") 58 | $ every 3 (fast 2) 59 | $ note "c/1.2 ~ d/1.8 ~" 60 | # sound "ade" 61 | # n (choose [0,1]) 62 | # gain (slow 1 $ range 0.3 0.85 $ sine) 63 | # pan (slow 5 $ range 0.2 0.75 $ sine) 64 | # gate 2 65 | 66 | d6 67 | $ slow 4 68 | $ note (arp "" "c'maj'<3 3 3 7>") 69 | # sound "ade:2" 70 | # size 0.3 71 | # speed (choose [1, 0.5, 0.25]) 72 | 73 | 74 | d4 75 | -- $ sometimesBy "<0.2 0.9 0.2 0.1 0.8>" (# sound "gtr:1") 76 | $ whenmod 16 8 ((|+ note "-5") . (chunk 2 (|+ note "12 24")) . (fast "2 [4 2]")) 77 | -- $ stut 3 0.65 0.73 78 | $ note "d e" 79 | # sound "[gtr:0]" 80 | -- # gain 0.7 81 | -- # size 0.9 82 | -- # room 0.9 83 | 84 | do 85 | d5 86 | $ juxBy (fast 2 $ sine) ((hurry 2) . (# gain "0.7") . (# vowel "a e")) 87 | $ whenmod 16 8 (|+ note "[[~ 12] -12] 7") 88 | $ superimpose ((1.25 ~>) . (|+ note 12) . (# speed "<-1 -2>")) 89 | $ sound "bass1*4" 90 | # gain (slow 3 $ range 0 1 saw) 91 | # note "d d d e" 92 | # shape 0.4 93 | # legato 1 94 | d1 silence 95 | 96 | do 97 | d2 98 | $ stack [ 99 | (0.5 ~>) $ stut 4 0.25 0.25 $ sound "kick:4(5,8)" # lpf 900, 100 | chunk 4 (fast 2) $ sound "[amencutup*<[4 8 2 4 16] 8 16>, drum*8]" # n (irand 32) # shape 0.2 # pan (fast 24 $ perlin), 101 | slow "2 1" $ sometimesBy (sine) (stutWith 4 (1/16) (# accelerate 2)) $ sound "~ ~ cr [~ cr]" # gain 0.75 102 | ] 103 | d3 silence 104 | 105 | d5 silence 106 | 107 | d6 silence 108 | 109 | d2 silence 110 | 111 | d4 silence 112 | -------------------------------------------------------------------------------- /jia-liu/ireadthat.scd: -------------------------------------------------------------------------------- 1 | i = File.open(Document.current.path, "r").readAllString();"" 2 | 3 | (Task{ 4 | 1.do{ 5 | i.do{|i| 6 | i.post; 7 | case 8 | {i.ascii == 10}{2.wait;} 9 | {i.ascii == 32}{1.wait;} 10 | {[10,32].includes(i.ascii).not}{ 11 | {SinOsc.ar(i.ascii.linlin(32,127,24,60).floor.midicps*2,0,0.1).dup*Env([0,1,1,0],[1,0.2,1]).kr(2)}.play; 12 | 1.wait; 13 | } 14 | } 15 | } 16 | }.play) 17 | 18 | (Task{ 19 | 1.do{ 20 | u.do{|i| 21 | i.post; 22 | case 23 | {i.ascii == 10}{1.wait;} 24 | {i.ascii == 32}{0.4.wait;} 25 | {[10,32].includes(i.ascii).not}{ 26 | {SinOsc.ar(i.ascii.linlin(32,127,200,10000),0,0.1).dup*Env([0,1,1,0],[0.4,0.2,1.21]).kr(2)}.play; 27 | 0.4.wait; 28 | } 29 | } 30 | } 31 | }.play) -------------------------------------------------------------------------------- /jia-liu/iwrite.scd: -------------------------------------------------------------------------------- 1 | !"#$%&'()*+,-./ 2 | 3 | ABC 4 | DEFG 5 | HIJKLMN 6 | OPQRSTUVWXYZ 7 | 8 | 0 1 2 3 4 5 6 7 8 9 9 | 10 | a b c d e f g 11 | h i j k l m n 12 | o p q 13 | r s t 14 | u v w x y z 15 | 16 | 17 | 18 | (32..48).asAscii.post 19 | u = File.open(Document.current.path, "r").readAllString();"" -------------------------------------------------------------------------------- /joana-chicau/README.md: -------------------------------------------------------------------------------- 1 | _Choreo-Graphic-Coding by [Joana Chicau](joanachicau.com/)_ ^ _ ^ see inside the [javascript file](choreo-code-in-10-minutes.js) ~ you can open the file with a text editor of your choice; please read the comments, they carry important messages on how and where to play with the code. thank you for coding and dancing along! 2 | -------------------------------------------------------------------------------- /joana-chicau/choreo-code-in-10-minutes.js: -------------------------------------------------------------------------------- 1 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - // 2 | // - - - - - Choreo-Graphic-Coding by Joana Chicau - - - \\ 3 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - // 4 | 5 | // stage: https://www.google.com/search?q=all+the+movements 6 | // open the webconsole copy and paste the code below 7 | // call each of the functions and tweak the code as you please! 8 | // note: id's and classes may change, inspect each of the elements when using the code; 9 | 10 | function Warning() { 11 | alert("This is a silent piece, listen to it carefully."); 12 | } 13 | 14 | var delay="10"; 15 | var count='0'; 16 | var Texts=new Array(); 17 | Texts[0]="Choreography"; 18 | Texts[1]="as a moving language,"; 19 | Texts[2]="words to define"; 20 | Texts[3]="space and time"; 21 | Texts[4]="expand and contract"; 22 | Texts[5]="or remain still."; 23 | 24 | 25 | function NewSequence(){ 26 | document.querySelector('#logocont').innerHTML=Texts[count]; 27 | count++; 28 | if(count==Texts.length){count='0';} 29 | setTimeout("NewSequence()",delay*1000); 30 | 31 | document.querySelector("#logocont").style.width="1000px" 32 | document.querySelector("#logocont").style.fontSize="42pt" 33 | } 34 | 35 | var textarray = [ 36 | "Ritualistic, repetitive", 37 | "Simultaneously", 38 | "A thing called a body.", 39 | "Breathing until its enough.", 40 | "Substitution.", 41 | "A supermposition of rhythms", 42 | "(variation)", 43 | "Accumulation", 44 | "No time for breathing." 45 | ]; 46 | 47 | 48 | function Elements_of_Chance(n) { 49 | 50 | var rannum= Math.floor(Math.random()*textarray.length); 51 | var r =document.querySelector(".g:nth-child("+n+")"), 52 | r = r.querySelector(".r"); 53 | r.innerHTML=textarray[rannum]; 54 | r.style.fontSize="24pt" 55 | r.style.color="#000" 56 | }; 57 | 58 | // set Interval("Elements_of_Chance(n)", 1500) - - > n = number starting from 1 59 | 60 | // in the webconsole experiment with switching the values of the images element, using: 61 | // transform: matrix3d(1, 1, 0, 0, 10, 1, 0, 10, 10, 0, 1, 0, 200, 10, 0, 1); 62 | // width: 500px; 63 | // filter: grayscale(100%) 64 | // opacity: 0.25; 65 | 66 | 67 | function leave_the_stage (n){ 68 | 69 | var r =document.querySelector(".g:nth-child("+n+")"); 70 | r.style.visibility="hidden"; 71 | }; 72 | 73 | function offstage () { 74 | document.body.innerHTML = ''; 75 | document.head.innerHTML = ''; 76 | } 77 | 78 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - // 79 | // - - - - thank you for coding and dancing along! - - - \\ 80 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - // 81 | 82 | -------------------------------------------------------------------------------- /jobi/README.md: -------------------------------------------------------------------------------- 1 | # [Jobi](https://jokroese.com) 10-minute Live Coding Challenge 2 | 3 | I used [TidalCycles](tidalcycles.org/) and [SuperCollider](https://supercollider.github.io/) for the audio and [Hydra](https://hydra-editor.glitch.me/) for the visuals. 4 | 5 | ## Guide to the Samples Used 6 | 7 | I am slightly wary of the legal implications of hosting some of the samples in this repository. Instead, here's a guide to them. 8 | 9 | - `goldeneye`: sounds from James Bond Goldeneye PS1 game. 10 | - `ff1`: sounds from [Final Fantasy](https://en.wikipedia.org/wiki/Final_Fantasy_(video_game)). I think the ones used in this set were from the 2004 Game Boy Advance release. 11 | - `more`: backing vocals from Britney Spears' [Gimme More](https://www.youtube.com/watch?v=elueA2rofoo). 12 | - `freak-vocals`: the vocal track of Missy Elliot's [Get Ur Freak On](https://www.youtube.com/watch?v=FPoKiGQzbSQ). 13 | - `i-wud-never`: vocal track from 100 Gecs' [xXXi_wud_nvrstøp_ÜXXx](https://www.youtube.com/watch?v=fQAjveYLtHQ). 14 | - `hard`: a hardcore style kick coded in SuperCollider that was based on [snappizz](http://sccode.org/snappizz)'s [gabber](http://sccode.org/1-5aV). -------------------------------------------------------------------------------- /jobi/ccu.js: -------------------------------------------------------------------------------- 1 | s0.initCam() 2 | src(s0).out() 3 | 4 | osc(8, 0.3, 1.5) 5 | .modulate(src(s0).rotate(3, 0.4, 0.5)) 6 | .modulate(src(s0).rotate(-1, 0.2, 0.1)) 7 | .diff(src(s0).rotate(3, 0.3, 0.5)) 8 | .diff(shape(2).rotate(-1, 0.2, 0.3).scale(({time}) => Math.sin(time))) 9 | .out() 10 | -------------------------------------------------------------------------------- /jobi/ccu.tidal: -------------------------------------------------------------------------------- 1 | bpm 135 2 | 3 | d1 4 | $ whenmod 4 3 (# coarse 20) 5 | $ sometimesBy 0.05 (slow 2) 6 | $ struct "1(<11 13 15>,16)" $ s "goldeneye" +| n (run 16) + 1 7 | 8 | d2 9 | $ whenmod 1 0 (# coarse 20) 10 | $ struct "1(7,16)" $ s "ff1" 11 | 12 | d3 13 | $ struct "1 _ _ 1 _ _ 1 _" 14 | $ s "hard" # n "c2" 15 | # accelerate "-2 0 2" 16 | # lowhi "2 200 2" # coarse 20 # crush 3 17 | 18 | d4 19 | $ whenmod 8 7 (# hpf 1000) 20 | $ whenmod 4 3 (# coarse 20) 21 | $ loopLength 16 16 $ s "freak-vocals" 22 | # n "2" 23 | 24 | d5 $ loopLength 8 8 $ s "i-wud-never" 25 | 26 | d6 $ s "~ snare ~ snare" 27 | -------------------------------------------------------------------------------- /jon/10minuteCCU.scd: -------------------------------------------------------------------------------- 1 | // Hi CCU! Let's get started... :-) 2 | a.countdown(60*10); 3 | 4 | a.sacred.gen; // generates a sequence of 4-part Sacred Harp harmonies 5 | ( // Oh yeah! 6 | Pdef(\harp, Pbind(*[ 7 | instrument: \play, 8 | amp: 0.7, 9 | buf: b, 10 | rfreq: \fs6.notecps, // playback (changed from original code \f6.f 11 | sac: Pfunc({ a.sacred.gen }), 12 | dur: 1/2, 13 | delta: Pfunc({|e| e.sac.dur }), 14 | degree: Pfunc({|e| e.sac.voices }), 15 | root: \fs0.notemidi, // changed from original code \fs0.m 16 | scale: Scale.minor, 17 | out: ~bus, 18 | ])).play(quant: 1); 19 | TempoClock.tempo = 120/60; 20 | ); 21 | 22 | ~bus = Bus.audio(s, 2); 23 | b = Buffer.alloc(s, 44100, 1); 24 | ( // recording... 25 | Ndef(\post, { 26 | var sig1, in, in2, mix; 27 | in = SoundIn.ar(0); // my voice (into the mic) 28 | in2 = In.ar(~bus, 2); 29 | RecordBuf.ar(in, b, run: 1, loop: 1); 30 | sig1 = Impulse.ar(LFNoise1.ar(10).range(1, 20)) * SinOsc.ar(0.1); 31 | sig1 = Ringz.ar(sig1, MouseY.kr(60, 10000), LFNoise0.ar(20).range(0.01, 0.001)) * 0.5; 32 | sig1 = [sig1, CombL.ar(sig1, 2, 0.2, 1.0)]; 33 | sig1 = sig1 * Line.ar(1.0, 0, 10); 34 | mix = in2 + sig1; 35 | mix = (mix*0.6) + (JPverb.ar(mix, 10, 0.2, 2.0, 0.6, 0.5, 0.4, 0.5, 0.5, 0.5) * 0.5); 36 | mix; 37 | }).play(out: 0, numChannels: 2, group: s, addAction: \addToTail); 38 | 39 | ); 40 | 41 | Pbindef(\harp, \amp, {Line.ar(1.0, 0, 10)}.ndef(\fade)); 42 | 43 | out we go... 44 | Thanks! 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /jon/10minute_plumbing.scd: -------------------------------------------------------------------------------- 1 | // Additional SynthDefs Used 2 | ( 3 | SynthDef('sin1', {|out=0, freq=440, amp=0.1, gate=1, atk=1, rel=1, curve=0, mod=0, mute=0, pan=0| 4 | var sig; 5 | sig = SinOsc.ar(freq); 6 | sig = sig * (1 - SinOsc.ar(mod, mul: (mod > 0)).range(0.0,1.0)); 7 | sig = sig * EnvGen.ar(Env.asr(atk, 1.0, rel, curve), gate, doneAction: 2); 8 | sig = Pan2.ar(sig, pan, amp); 9 | Out.ar(out, sig * (1-mute)); 10 | }).add; 11 | 12 | 13 | SynthDef('rezpad', {arg out=0, amp=0.3, freq=440, dur=1, phase=2.5, modhz=0.1, saturation=10, atk=0.1, tremhz=4, tremmix=0.4; 14 | var sig, mod, ratios; 15 | ratios = [ 1.0665241742002, 1.0736323145277, 1.0792282365041, 1.0594630943591, 1.0293022366434 ]; 16 | sig = Saw.ar(freq * ratios).sum; 17 | mod = SinOsc.ar(modhz, phase * (pi/2)).range(0.2, 3); 18 | sig = Resonz.ar(sig, [400,1200,500,800,569] * mod, 0.1, mul: 1.0); 19 | sig = (sig*saturation).tanh * (saturation.log + 1).reciprocal; 20 | sig = Splay.ar(sig, Line.ar(0.1,1,dur/2)) * EnvGen.ar(Env.linen(atk,1-atk), doneAction: 2, timeScale: dur); 21 | sig = SinOsc.ar(tremhz).range(1-tremmix,1.0) * sig; 22 | Out.ar(out, sig * amp); 23 | }).add; 24 | 25 | SynthDef('play', {|amp=0.5, rate=1, freq=261.62556, rfreq=261.62556, buf, dur=1, out, pan=0, atk=0.01, rel=0.01, gate=1| 26 | var sig, playrate; 27 | playrate = rate * freq / rfreq; 28 | sig = PlayBuf.ar(1, buf, playrate, 1, 0, 1); 29 | sig = sig * EnvGen.ar(Env.asr(atk, 1.0, rel), gate: gate, doneAction: 2); 30 | Out.ar(out, Pan2.ar(sig, pan, amp)); 31 | }).add; 32 | ); 33 | 34 | 35 | ( 36 | // First few bars from 37 | // Wondrous Love in F minor (1811), The Sacred Harp 38 | ~degrees = [ 39 | [5, 5, 5, 5, 4, 5, 4, 4, 3, 1, 3, 2, 5, 5, 4, 5, 7, 8, 7, 7, 5], 40 | [5, 5, 5, 5, 7, 8, 7, 7, 8, 8, 7, 7, 8, 7, 8, 8, 9, 8, 9, 7, 5] - 7, 41 | [1, 1, 0, 2, 4, 5, 4, 2, 1, 1, 0, 2, 5, 7, 6, 5, 4, 5, 4, 2, 1], 42 | [8, 5, 5, 5, 7, 8, 7, 7, 8, 8, 7, 5, 8, 10, 9, 8, 7, 8, 7, 5, 8] - 14, 43 | ]; 44 | 45 | ~durations = [ 46 | [2, 4, 4, 4, 4, 2, 4, 4, 2, 4, 4, 2, 2, 4, 4, 4, 4, 2, 4, 4, 1], 47 | [2, 4, 4, 4, 4, 2, 4, 4, 2, 4, 4, 2, 2, 4, 4, 4, 4, 2, 4, 4, 1], 48 | [2, 4, 4, 4, 4, 2, 4, 4, 2, 4, 4, 2, 2, 4, 4, 4, 4, 2, 4, 4, 1], 49 | [2, 4, 4, 4, 4, 2, 4, 4, 2, 4, 4, 2, 2, 4, 4, 4, 4, 2, 4, 4, 1], 50 | ]; 51 | 52 | ~seq_1 = (~degrees[0]-1).pseq(inf); 53 | ~seq_2 = (~degrees[1]-1).pseq(inf); 54 | ~seq_3 = (~degrees[2]-1).pseq(inf); 55 | ~seq_4 = (~degrees[3]-1).pseq(inf); 56 | ~dur_1 = (1/~durations[0]).pseq(inf); 57 | 58 | // 1st order markov chains 59 | m = MarkovSet.fill(100, ~seq_1.asStream); m.makeSeeds; 60 | ~vsoprano = m.asStream; 61 | m = MarkovSet.fill(100, ~seq_2.asStream); m.makeSeeds; 62 | ~valto = m.asStream; 63 | m = MarkovSet.fill(100, ~seq_3.asStream); m.makeSeeds; 64 | ~vtenor = m.asStream; 65 | m = MarkovSet.fill(100, ~seq_4.asStream); m.makeSeeds; 66 | ~vbass = m.asStream; 67 | m = MarkovSet.fill(100, ~dur_1.asStream); m.makeSeeds; 68 | ~vdur = m.asStream; 69 | 70 | // 2nd order markov chains 71 | m = MarkovSetN.fill(100, ~seq_1.asStream, 2); m.makeSeeds; 72 | ~vsoprano2 = m.asStream; 73 | m = MarkovSetN.fill(100, ~seq_2.asStream, 2); m.makeSeeds; 74 | ~valto2 = m.asStream; 75 | m = MarkovSetN.fill(100, ~seq_3.asStream, 2); m.makeSeeds; 76 | ~vtenor2 = m.asStream; 77 | m = MarkovSetN.fill(100, ~seq_4.asStream, 2); m.makeSeeds; 78 | ~vbass2 = m.asStream; 79 | m = MarkovSetN.fill(100, ~dur_1.asStream, 2); m.makeSeeds; 80 | ~vdur2 = m.asStream; 81 | 82 | // 3nd order markov chains 83 | m = MarkovSetN.fill(100, ~seq_1.asStream, 3); m.makeSeeds; 84 | ~vsoprano3 = m.asStream; 85 | m = MarkovSetN.fill(100, ~seq_2.asStream, 3); m.makeSeeds; 86 | ~valto3 = m.asStream; 87 | m = MarkovSetN.fill(100, ~seq_3.asStream, 3); m.makeSeeds; 88 | ~vtenor3 = m.asStream; 89 | m = MarkovSetN.fill(100, ~seq_4.asStream, 3); m.makeSeeds; 90 | ~vbass3 = m.asStream; 91 | m = MarkovSetN.fill(100, ~dur_1.asStream); m.makeSeeds; 92 | ~vdur3 = m.asStream; 93 | 94 | a = (); 95 | a.sacred = (); 96 | a.countdown = {|e, val| 97 | m = Tdef(\countdown, { 98 | var seconds, cnt; 99 | seconds = val; 100 | seconds.do {|idx| 101 | cnt = seconds - idx; 102 | cnt.asString.postln; 103 | 1.wait; 104 | }; 105 | }).play(SystemClock); 106 | m; 107 | }; 108 | a.sacred.gen = {|e, order=1| 109 | var res; 110 | if(order == 1) { 111 | res = (dur: ~vdur2.next, voices: [~vsoprano.next, ~valto.next, ~vtenor.next, ~vbass.next]); 112 | }; 113 | if(order == 2) { 114 | res = (dur: ~vdur2.next, voices: [~vsoprano2.next, ~valto2.next, ~vtenor2.next, ~vbass2.next]); 115 | }; 116 | if(order == 3) { 117 | res = (dur: ~vdur3.next, voices: [~vsoprano3.next, ~valto3.next, ~vtenor3.next, ~vbass3.next]); 118 | }; 119 | res; 120 | }; 121 | 122 | ); 123 | -------------------------------------------------------------------------------- /jon/README.md: -------------------------------------------------------------------------------- 1 | # Instructions... 2 | 3 | To run this code you need a few extensions from the SC community. 4 | 5 | * MarkovSet and MarkovSetN found in the MathLib quark 6 | https://github.com/supercollider-quarks/MathLib 7 | 8 | * JPverb found in the SC3 Community Plugins 9 | https://supercollider.github.io/sc3-plugins/ 10 | 11 | Before starting I trained some Markov Chains on the first few bars of a 12 | hymn from [The Sacred Harp](http://originalsacredharp.com/). This code can 13 | be found in 10minute_plumbing.scd ~ along with some of the SynthDefs I use to 14 | do livecoding. 15 | -------------------------------------------------------------------------------- /jonreus/README.md: -------------------------------------------------------------------------------- 1 | # Requirements 2 | This code uses a couple extensions from the SC3plugins suite, which you can download at [https://supercollider.github.io/sc3-plugins/](https://supercollider.github.io/sc3-plugins/). 3 | 4 | -------------------------------------------------------------------------------- /kesson/README.md: -------------------------------------------------------------------------------- 1 | # 10-minutes Live Coding Challenge - [Kesson](https://kesson.io) 2 | 3 | ### Requirements 4 | 5 | The code is made in [Processing](https://processing.org/download/) 6 | 7 | For the REPL/Hot Swap mode (and so live code), you will need to download the REPL Mode. Sketch -> Import Library -> Add Library -> (under Modes) REPL Mode. -------------------------------------------------------------------------------- /kesson/s_200601_livecoding_3/s_200601_livecoding_3.pde: -------------------------------------------------------------------------------- 1 | import peasy.*; 2 | 3 | import ddf.minim.*; 4 | import ddf.minim.analysis.*; 5 | import ddf.minim.effects.*; 6 | import ddf.minim.signals.*; 7 | import ddf.minim.spi.*; 8 | import ddf.minim.ugens.*; 9 | 10 | Minim minim; 11 | AudioInput in; 12 | PeasyCam cam; 13 | 14 | int tot = 60; 15 | int totm = tot-1; 16 | PVector[][] points = new PVector[tot][tot]; 17 | 18 | void setup() { 19 | size(1080, 1080, P3D); 20 | surface.setLocation(0, 0); 21 | minim = new Minim(this); 22 | in = minim.getLineIn(Minim.STEREO, 1024); 23 | cam = new PeasyCam(this, 500); 24 | } 25 | 26 | void update() { 27 | float m1 = 8; 28 | float n11 = abs(cos(frameCount*0.0025)) + 0.1; 29 | float n12 = abs(sin(frameCount*0.00025)) + 0.1; 30 | float n13 = abs(cos(frameCount*0.0005)) + 0.1; 31 | 32 | float m2 = noise(frameCount*0.001) * 12; 33 | float n21 = (abs(sin(frameCount*0.0025)) + 0.1) * 100; 34 | float n22 = (abs(cos(frameCount*0.00025)) + 0.1) * 100; 35 | float n23 = (abs(cos(frameCount*0.00025)) + 0.1) * 100; 36 | 37 | for (int i = 0; i < tot; i++) { 38 | float theta = map(i, 0, totm, -PI, PI); 39 | 40 | float t11 = abs(cos(m1 * theta/4)); 41 | t11 = pow(t11, n12); 42 | 43 | float t12 = abs(sin(m1 * theta/4)); 44 | t12 = pow(t12, n13); 45 | 46 | float t13 = t11 + t12; 47 | float r1 = pow(t13, -1/n11); 48 | 49 | for (int j = 0; j < tot; j++) { 50 | float phi = map(j, 0, totm, -PI, PI); 51 | 52 | float t21 = abs(cos(m2 * phi/4)); 53 | t21 = pow(t21, n22); 54 | 55 | float t22 = abs(sin(m2 * phi/4)); 56 | t22 = pow(t22, n23); 57 | 58 | float t23 = t21 + t22; 59 | float r2 = pow(t23, -1/n21); 60 | 61 | 62 | float r = 400; 63 | float x = r * r1 * r2 * sin(theta) * cos(phi); 64 | float y = r * r1 * r2 * sin(theta) * sin(phi); 65 | float z = r * r2 * cos(theta); 66 | points[i][j] = new PVector(x, y, z); 67 | } 68 | } 69 | } 70 | 71 | void draw() { 72 | thread("update"); 73 | background(0); 74 | 75 | cam.setDistance(1000 + abs(sin(frameCount*0.001)) * 500); 76 | cam.rotateY(0.002); 77 | 78 | blendMode(ADD); 79 | 80 | stroke(222, 50, 50, in.mix.level() * 200); 81 | noFill(); 82 | beginShape(TRIANGLE_STRIP); 83 | for (int i = 0; i < totm; i++) { 84 | for (int j = 0; j < tot; j++) { 85 | PVector p = points[i+1][j]; 86 | PVector pp = points[i][j]; 87 | fill(in.mix.get(i%1024) * 200); 88 | vertex(p.x, p.y, p.z); 89 | vertex(pp.x, pp.y, pp.z); 90 | } 91 | } 92 | endShape(); 93 | } 94 | 95 | // Thanks for watching!! 96 | -------------------------------------------------------------------------------- /kesson/s_200601_livecoding_3/sketch.properties: -------------------------------------------------------------------------------- 1 | mode=REPL Mode 2 | mode.id=jm.mode.replmode.REPLMode 3 | -------------------------------------------------------------------------------- /luka-princic/behind_the_screens_performance_notes.scd: -------------------------------------------------------------------------------- 1 | 2 | // INIT first: 3 | ( 4 | fork { 5 | 6 | // synthdefs 7 | 8 | SynthDef(\ping,{ 9 | arg freq = 100, gate = 1, amp = 0.1, out=0, fxBus=nil, bufnum; 10 | var snd, env; 11 | freq = [freq, freq*1.01]; 12 | //snd = SinOsc.ar(freq) + Pulse.ar(freq*0.99) + LFTri.ar(freq*1.01); 13 | snd = Osc.ar(bufnum, freq); 14 | snd = snd * Linen.kr(gate, 0.001, 1, 0.01, doneAction:Done.freeSelf); 15 | snd = LeakDC.ar(snd); 16 | snd = Limiter.ar(snd, 0.95); 17 | snd = snd * amp * 0.5 * 10; 18 | //Out.ar() 19 | Out.ar(out,snd); 20 | } ).add; 21 | 22 | SynthDef(\wab,{ 23 | arg freq = 100, gate = 1, amp = 0.1, out=0, fxBus=nil, bufnum; 24 | var snd, env; 25 | snd = Osc.ar(bufnum, freq); 26 | snd = snd * Linen.kr(gate, 0.001, 1, 0.1, doneAction:Done.freeSelf); 27 | snd = LeakDC.ar(snd); 28 | snd = BRF.ar(snd, LFNoise1.kr(2).exprange(100,1000), 0.1); 29 | snd = RLPF.ar(snd, LFNoise1.kr(2).exprange(50,1000), 0.2); 30 | snd = snd * 20; 31 | snd = Limiter.ar(snd, 0.95); 32 | snd = Splay.ar(snd); 33 | snd = snd * amp * 0.7 * 10 ; 34 | Out.ar(out,snd); 35 | } ).add; 36 | 37 | 38 | SynthDef(\sab,{ 39 | arg freq = 100, gate = 1, amp = 0.1, out=0, fxBus=nil, bufnum, sustain; 40 | var snd, env; 41 | freq = XLine.ar(freq,freq * 0.1, sustain); 42 | snd = Osc.ar(bufnum, freq); 43 | snd = snd * Linen.kr(gate, 0.001, 1, 0.01, doneAction:Done.freeSelf); 44 | snd = LeakDC.ar(snd); 45 | snd = snd + PinkNoise.ar(0.5); 46 | snd = HPF.ar(snd, 500); 47 | snd = snd * 20; 48 | snd = snd.softclip; 49 | snd = Limiter.ar(snd, 0.95); 50 | snd = Splay.ar(snd); 51 | snd = snd * amp * 0.15 * 10; 52 | Out.ar(out,snd); 53 | } ).add; 54 | 55 | SynthDef(\dlywrangler, { 56 | arg out=0, in, wet=0.1, wet2=0.5; 57 | var snd, dly2; 58 | snd = In.ar(in,2); 59 | dly2 = CombN.ar(HPF.ar(snd,300), 1, [0.5,0.77], 5, mul: LFNoise1.kr(0.1).range(0.4,0.1) * 2 * wet2); 60 | snd = CombN.ar(snd, 1, Lag.ar(LFNoise0.ar(1).range(0.01,0.1),0.1), 3, mul:wet) + snd; 61 | snd = Limiter.ar(snd, 0.8); 62 | snd = snd + dly2; 63 | Out.ar(out, snd); 64 | }).add; 65 | 66 | // --------------------------- 67 | 68 | s.sync; 69 | 70 | ~dly.free; 71 | 0.1.wait; 72 | ~dly = Bus.audio(s, 2); 73 | 74 | s.sync; 75 | 76 | 0.1.wait; 77 | ~dw.free; 78 | // create delaymangler comb // on ctrl+. you need to reeval this 79 | ~dw = Synth(\dlywrangler, [\out, 0, \in, ~dly, \wet2, 0.1, \wet, 0.02]); 80 | 81 | } 82 | ) /////////////////////////////////////////////////////////////////// 83 | // end of init ///////////////////////////////////////////////////// 84 | 85 | 86 | // buffers init 87 | b.free; c.free; 88 | b = Buffer.alloc(s, 44100 * 10, 1); 89 | c = Buffer.alloc(s, 4096); 90 | 91 | // record something throught your mic 92 | {RecordBuf.ar(SoundIn.ar, b, loop:0, doneAction:2).dup}.play 93 | b.normalize 94 | b.plot 95 | 96 | ( 97 | Ndef(\g, { 98 | var snd = GrainBuf.ar(1, 99 | Impulse.ar(100), 100 | 0.2, b, [0.5,1,2,3,4,8], 101 | pos: LFNoise2.ar(1/50!6).range(0,1) * LFNoise0.ar(100).range(1,0.98) 102 | ); 103 | snd = Splay.ar(snd); 104 | snd = LPF.ar(snd, LFNoise1.kr(1/10).exprange(500,8000)); 105 | snd = Limiter.ar(snd, 0.6); 106 | snd = CombN.ar(snd, 1, [0.55,0.44], 5, mul:0.7) + snd; 107 | snd * 0.8; 108 | }).play 109 | ) 110 | 111 | Ndef(\g).fadeTime = 20; 112 | 113 | // copy a part from buffer b to buffer c 114 | b.copyData(c, 0, b.numFrames.rand) 115 | c.normalize 116 | c.plot 117 | 118 | ( 119 | Pbindef(\p1, *[instrument:\ping, bufnum:c, 120 | sustain: 0.1, 121 | octave: 3, 122 | out: ~dly, 123 | dur: Pseq([1,1.5] * 4,inf) 124 | ]).play 125 | ) 126 | 127 | ( 128 | Pbindef(\p2, *[instrument:\ping, bufnum:c, 129 | sustain: 0.01, 130 | octave: 8, 131 | out: ~dly, 132 | dur: Prand([1,1.5] * 1/4,inf) 133 | ]).play 134 | ) 135 | 136 | ( 137 | Pbindef(\p3, *[instrument:\wab, bufnum:c, 138 | sustain: 1, 139 | octave: [2,3], 140 | dur: 4, 141 | copydata: Pfunc({ 142 | b.copyData(c, 0, b.numFrames.rand); 143 | c.normalize; 144 | }) 145 | ]).play 146 | ) 147 | 148 | ( 149 | Pbindef(\p4, *[instrument:\sab, bufnum:c, 150 | sustain: Pwhite(0.1, 0.3), 151 | octave: 5, 152 | amp: 0.1, 153 | out: ~dly, 154 | dur: Prand([2,3,3.5],inf), 155 | ]).play 156 | ) 157 | 158 | ~dw.set(\wet2, 0.9) 159 | ~dw.set(\wet, 0.5) 160 | 161 | ////////////////////////// 162 | Pbindef(\p1).stop 163 | Pbindef(\p2).stop 164 | Pbindef(\p3).stop 165 | Pbindef(\p4).stop 166 | Ndef(\g).release 167 | ////////////////////////// 168 | 169 | -------------------------------------------------------------------------------- /narcode/10-min-narcodish.sc: -------------------------------------------------------------------------------- 1 | ~timestamp = "date '+%M'".unixCmdGetStdOut.asInteger 2 | 3 | ~funcs = (); 4 | a = PZ_machine(s) 5 | a.ignite 6 | 7 | ~funcs['bd'] = {PZ_layer(~bd).rhythm(1,0,[2],[0,1])} 8 | ~funcs['hh'] = {PZ_layer(~hh).rhythm([0,1],[0,2],[2],1)} 9 | ~funcs['sn'] = {PZ_layer(~sn).rhythm(0,1,0,[1])} 10 | 11 | "say -v whi 10 minutes went fast. bye bye".unixCmd 12 | 13 | Tdef(\t, { 14 | loop{ 15 | ~now = "date '+%M'".unixCmdGetStdOut.asInteger; 16 | if ((~timestamp+10) - ~now == 0) { 17 | ~funcs = (); 18 | "say -v wh the end".unixCmd; 19 | }; 20 | 2.wait; 21 | } 22 | }).play; 23 | 24 | x = {arg note=100; {Saw.ar(98)*0.1*EnvGen.kr(Env.perc,doneAction:2)}.play(s,11) } 25 | ~funcs['b'] = {PZ_layer(x).rhythm([2],[2],0,[2])} 26 | 27 | Tdef(\t).stop 28 | -------------------------------------------------------------------------------- /narcode/README.md: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | 3 | ### To run the code you will also need the Panda Zooicide beat classes. 4 | 5 | Just Place the `pz_beat_machine.sc` file in your Supercollider extensions folder 6 | before your boot supercollider. 7 | 8 | 9 | *I use 3 global variabales `~bd, ~hh, ~sn` for samples of bassdrum, hihat and snare. 10 | You can make your own variables like this:* 11 | 12 | `~bd = { Synth(\sampleNarcode, [\buf, Buffer.read(s, "PATH_TO_YOUR_SAMPLE")]) };` 13 | 14 | `~hh = { Synth(\sampleNarcode, [\buf, Buffer.read(s, "PATH_TO_YOUR_SAMPLE")]) };` 15 | 16 | `~sn = { Synth(\sampleNarcode, [\buf, Buffer.read(s, "PATH_TO_YOUR_SAMPLE")]) };` 17 | 18 | *And if you need a synth to play the samples, here:* 19 | 20 | `SynthDef(\sampleNarcode, {|out=0, at=0.01, rl=0.1, rate=1, pos=0, amp=1, buf| 21 | var env = EnvGen.kr(Env.perc(at, rl), doneAction:2); 22 | var snd; 23 | snd = PlayBuf.ar(1, buf, BufRateScale.kr(buf)*rate, 1, BufFrames.kr(buf)*pos)*env; 24 | Out.ar(out, snd*amp); 25 | }).add;` 26 | -------------------------------------------------------------------------------- /narcode/pz_beat_machine.sc: -------------------------------------------------------------------------------- 1 | //// PZ Beat machine 2020 v0.1 2 | 3 | /* 4 | Class for custom functional beat machine 5 | */ 6 | 7 | ////////////////////////////// 8 | 9 | PZ_machine { 10 | var <>beats=4, <>server=nil, <>routine; 11 | 12 | *new {arg server; 13 | ^super.new.init(server); 14 | } 15 | 16 | init {arg server; 17 | this.server = server; 18 | this.routine = TaskProxy.new; 19 | this.routine.play; 20 | } 21 | 22 | ignite {arg server=this.server, beats=this.beats; 23 | this.routine.source = { 24 | inf.do{ 25 | server.bind{ 26 | // audio 27 | ~funcs.do{|f| f.(); }; 28 | }; 29 | beats.wait; 30 | } 31 | } 32 | } 33 | 34 | } 35 | 36 | PZ_layer { 37 | classvar <>maxsubdiv=12, <>debug=false; 38 | var <>item=nil, <>itemarg=nil, <>debug=false; 39 | 40 | *new {arg item=this.item, itemarg=nil; 41 | 42 | ^super.new.init(item, itemarg); 43 | } 44 | 45 | init {|item, itemarg| 46 | this.item = item; 47 | this.itemarg = itemarg; 48 | } 49 | 50 | rhythm {arg ... args; 51 | var beats=args; 52 | // beats.postln; 53 | ^Routine{ 54 | if (debug) {item.postln; beats.asString.postln;}; 55 | 56 | beats.do{arg beat, index; 57 | if (beat.isArray.not) { // single: 58 | if (beat > 0) { 59 | if (debug) {(index.asString ++ " = " ++ beat.asString).postln;}; 60 | (beat.reciprocal.clip(1, maxsubdiv)).do{ 61 | item.(itemarg); 62 | (beat.clip(maxsubdiv.reciprocal, 1)).wait; 63 | }; 64 | } {1.wait}; 65 | } { // array: 66 | { 67 | beat.do{arg sub; 68 | if (sub > 0) { 69 | if (debug) {(beat.asString ++ " = " ++ beat.asString ++ sub.asString).postln;}; 70 | ((sub).clip(1, maxsubdiv)).do{ 71 | item.(itemarg); 72 | if (sub == 1) { 73 | (sub/beat.size).wait; 74 | } {(beat.size.reciprocal/sub).wait;} 75 | }} {(beat.size.reciprocal).wait;} 76 | }; 77 | 78 | (beat.size.reciprocal).wait; 79 | 80 | }.fork; 81 | 1.wait; 82 | }; 83 | }; 84 | }.play; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /nescivi/code-livecode-live-29-06-2020-performance-code-buffer.scd: -------------------------------------------------------------------------------- 1 | ~in = { SoundIn.ar( [0,1] ); }; 2 | ~in.play; 3 | 4 | ~ps = { PitchShift.ar( ~in.ar, 0.2, [4/5, 5/4], 0.2, 0.2 ) }; 5 | ~ps.play; 6 | 7 | b = Buffer.alloc( s, s.sampleRate * 5.rand + 2, 2 ); 8 | 9 | ~rec = { RecordBuf.ar( ~ps.ar, b, 0, 0, 0.6 ); }; 10 | 11 | ~play = { PlayBuf.ar( 2, b, 0.8, loop: 1 )*2 }; 12 | ~play.play 13 | 14 | ~filt = { Resonz.ar( ~play.ar, t.at( \keyVal ).kr.linexp( 0,1, 300, 4500 ), t.at( \headx ).kr.linexp( -1.0, 1.0, 0.02, 0.2 ), 16 ) }; 15 | ~filt.play; 16 | 17 | t = ThinkPad.new; 18 | 19 | 20 | c = Buffer.alloc( s, s.sampleRate, 2 ); 21 | 22 | ~recc = { RecordBuf.ar( ~filt.ar, c, 0, t.at( \t_x).kr, t.at(\t_y).kr, t.at( \t_touch ).kr ); }; 23 | 24 | ~plc = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*8 * \amp.kr(1) }; 25 | ~plc.play 26 | 27 | ~plc[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ), \delta, Pseq( [2,1,1,0.25], inf), \amp, Pseq( [2,1,2,3], inf ) ); 28 | 29 | ~plc = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*8 * \amp.kr(1) * EnvGen.kr( Env.perc, \trig.tr, timeScale: \dur.kr(1) ) }; 30 | ~plc.play 31 | 32 | ~plc[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ), \delta, Pseq( [2,1,1,0.25], inf) / 2, \amp, Pseq( [2,1,2,3], inf ) * 4, \trig, 1, \dur, 1 ); 33 | 34 | 35 | ~plc2 = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*8 * \amp.kr(1) * EnvGen.kr( Env.perc, \trig.tr, timeScale: \dur.kr(1) )}; 36 | ~plc2.play 37 | 38 | ~plc2[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 4, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 4, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 2, \trig, 1, \dur, 0.5 ); 39 | 40 | ~plc3 = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*8 * \amp.kr(1) * EnvGen.kr( Env.perc, \trig.tr, timeScale: \dur.kr(1) ) }; 41 | ~plc3.play 42 | 43 | ~plc3[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * Pstutter( 4, Pseq( [8,7,9,8], inf ) ), \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 8, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 2, \trig, 1, \dur, 0.5 ); 44 | 45 | ~plc4 = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*8 * \amp.kr(1) * EnvGen.kr( Env.perc, \trig.tr, timeScale: \dur.kr(1) ) }; 46 | ~plc4.play 47 | 48 | ~plc4[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 8 ), inf ) / 2, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) * 2, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 8, \trig, 1, \dur, 2 ); 49 | 50 | p.stop(15); -------------------------------------------------------------------------------- /nescivi/code-livecode-live-29-06-2020-performance-history-transcript.scd: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////// 2 | // History, as it was on Mon Jun 29 21:15:19 2020. 3 | /////////////////////////////////////////////////// 4 | 5 | // - 0:0:0 - 6 | ~in = { SoundIn.ar( [0,1] ); }; 7 | 8 | // - 0:0:2.22 - 9 | ~in.play; 10 | 11 | // - 0:0:18.7 - 12 | ~ps = { PitchShift.ar( ~in.ar, 0.2, [4/5, 5/4], 0.2, 0.2 ) }; 13 | 14 | // - 0:0:21.51 - 15 | ~ps.play; 16 | 17 | // - 0:0:37.64 - 18 | b = Buffer.alloc( s, s.sampleRate * 5.rand + 2, 2 ); 19 | 20 | // - 0:0:52.65 - 21 | ~rec = { RecordBuf.ar( ~ps.ar, b, 0, 1, 0.6 ); }; 22 | 23 | // - 0:1:9.8 - 24 | ~play = { PlayBuf.ar( 2, b, 0.8, loop: 1 ) }; 25 | 26 | // - 0:1:13.03 - 27 | ~play.play 28 | 29 | // - 0:1:16.9 - 30 | ~play = { PlayBuf.ar( 2, b, 0.8, loop: 1 )*2 }; 31 | 32 | // - 0:1:32 - 33 | ~filt = { Resonz.ar( ~play.ar, 700, 0.2, 4 ) }; 34 | 35 | // - 0:1:37.69 - 36 | ~filt.play; 37 | 38 | // - 0:1:41.71 - 39 | t = ThinkPad.new; 40 | 41 | // - 0:1:56.97 - 42 | ~filt = { Resonz.ar( ~play.ar, t.at( \keyVal ).kr.linexp( 0,1, 300, 4500 ), 0.2, 4 ) }; 43 | 44 | // - 0:2:17.56 - 45 | ~filt = { Resonz.ar( ~play.ar, t.at( \keyVal ).kr.linexp( 0,1, 300, 4500 ), t.at( \headx ).kr.linexp( -1.0, 1.0, 0.02, 0.2 ), 4 ) }; 46 | 47 | // - 0:2:21.44 - 48 | ~filt = { Resonz.ar( ~play.ar, t.at( \keyVal ).kr.linexp( 0,1, 300, 4500 ), t.at( \headx ).kr.linexp( -1.0, 1.0, 0.02, 0.2 ), 8 ) }; 49 | 50 | // - 0:2:24.85 - 51 | ~filt = { Resonz.ar( ~play.ar, t.at( \keyVal ).kr.linexp( 0,1, 300, 4500 ), t.at( \headx ).kr.linexp( -1.0, 1.0, 0.02, 0.2 ), 16 ) }; 52 | 53 | // - 0:2:35.53 - 54 | c = Buffer.alloc( s, s.sampleRate, 2 ); 55 | 56 | // - 0:3:5.44 - 57 | ~recc = { RecordBuf.ar( ~filt.ar, c, 0, t.at( \t_x).kr, t.at(\t_y).kr, t.at( \t_touch ).kr ); }; 58 | 59 | // - 0:3:15.7 - 60 | ~plc = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*2 }; 61 | 62 | // - 0:3:16.35 - 63 | ~plc.play 64 | 65 | // - 0:3:21.47 - 66 | ~plc = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*5 }; 67 | 68 | // - 0:3:24.87 - 69 | ~plc = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*5 }; 70 | 71 | // - 0:3:27.6 - 72 | ~plc = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*8 }; 73 | 74 | // - 0:3:48.62 - 75 | ~plc[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,1], inf ) ) 76 | 77 | // - 0:3:55.79 - 78 | ~plc[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,1], inf ), \delta, 2 ); 79 | 80 | // - 0:4:10.64 - 81 | ~plc[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ), \delta, Pseq( [2,1,1,0.25], inf) ); 82 | 83 | // - 0:4:20.09 - 84 | ~plc = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*8 * \amp.kr(1) }; 85 | 86 | // - 0:4:25.35 - 87 | ~plc[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ), \delta, Pseq( [2,1,1,0.25], inf), \amp, 2 ); 88 | 89 | // - 0:4:34.68 - 90 | ~plc[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ), \delta, Pseq( [2,1,1,0.25], inf), \amp, Pseq( [2,1,2,3], inf ) ); 91 | 92 | // - 0:4:46 - 93 | ~plc[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ), \delta, Pseq( [2,1,1,0.25], inf) / 2, \amp, Pseq( [2,1,2,3], inf ) ); 94 | 95 | // - 0:4:52.97 - 96 | ~plc2 = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*8 * \amp.kr(1) }; 97 | 98 | // - 0:4:54.09 - 99 | ~plc2.play 100 | 101 | // - 0:4:57.73 - 102 | ~plc2[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ) * 4, \delta, Pseq( [2,1,1,0.25], inf), \amp, Pseq( [2,1,2,3], inf ) ); 103 | 104 | // - 0:5:3.14 - 105 | ~plc2[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ) * 4, \delta, Pseq( [2,1,1,0.25], inf) / 2, \amp, Pseq( [2,1,2,3], inf ) ); 106 | 107 | // - 0:5:7.46 - 108 | ~plc2[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ) * 4, \delta, Pseq( [2,1,1,0.25], inf) / 4, \amp, Pseq( [2,1,2,3], inf ) ); 109 | 110 | // - 0:5:11.79 - 111 | ~plc2[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ) * 4, \delta, Pshuf( [2,1,1,0.25], inf) / 4, \amp, Pseq( [2,1,2,3], inf ) ); 112 | 113 | // - 0:5:20.52 - 114 | ~plc2[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ) * 4, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 4, \amp, Pseq( [2,1,2,3], inf ) ); 115 | 116 | // - 0:5:31.8 - 117 | ~plc2[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 4, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 4, \amp, Pseq( [2,1,2,3], inf ) ); 118 | 119 | // - 0:5:42.88 - 120 | ~plc2[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 4, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 4, \amp, Pn( Pshuf( [2,1,2,3], 4, ), inf ) ); 121 | 122 | // - 0:5:44.7 - 123 | ~plc2[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 4, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 4, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) ); 124 | 125 | // - 0:5:58.5 - 126 | ~plc3 = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*8 * \amp.kr(1) }; 127 | 128 | // - 0:5:59.25 - 129 | ~plc3.play 130 | 131 | // - 0:6:0.08 - 132 | ~plc3[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 4, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 4, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) ); 133 | 134 | // - 0:6:3.15 - 135 | ~plc3[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 8, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 4, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) ); 136 | 137 | // - 0:6:7.82 - 138 | ~plc3[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 8, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 8, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) ); 139 | 140 | // - 0:6:11.39 - 141 | ~plc3[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 8, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 8, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 2 ); 142 | 143 | // - 0:6:23.62 - 144 | ~plc4 = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*8 * \amp.kr(1) }; 145 | 146 | // - 0:6:24.37 - 147 | ~plc4.play 148 | 149 | // - 0:6:25.66 - 150 | ~plc4[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 8, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 8, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 2 ); 151 | 152 | // - 0:6:29.62 - 153 | ~plc4[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) / 2, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 8, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 2 ); 154 | 155 | // - 0:6:35.53 - 156 | ~plc4[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) / 2, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) * 2, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 2 ); 157 | 158 | // - 0:6:42.99 - 159 | ~plc4[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) / 2, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) * 2, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 3 ); 160 | 161 | // - 0:6:45 - 162 | ~plc4[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) / 2, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) * 2, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 4 ); 163 | 164 | // - 0:7:3.44 - 165 | ~plc4 = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*8 * \amp.kr(1) * EnvGen.kr( Env.perc, \trig.tr, timeScale: \dur.kr(1) ) }; 166 | 167 | // - 0:7:7.91 - 168 | ~plc4[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) / 2, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) * 2, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 4, \trig, 1 ); 169 | 170 | // - 0:7:15.08 - 171 | ~plc4[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) / 2, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) * 2, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 4, \trig, 1, \dur, 1 ); 172 | 173 | // - 0:7:21.11 - 174 | ~plc4[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) / 2, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) * 2, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 4, \trig, 1, \dur, 0.5 ); 175 | 176 | // - 0:7:25.8 - 177 | ~plc4[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) / 2, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) * 2, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 8, \trig, 1, \dur, 0.5 ); 178 | 179 | // - 0:7:33.65 - 180 | ~plc3 = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*8 * \amp.kr(1) * EnvGen.kr( Env.perc, \trig.tr, timeScale: \dur.kr(1) ) }; 181 | 182 | // - 0:7:37.08 - 183 | ~plc2 = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*8 * \amp.kr(1) * EnvGen.kr( Env.perc, \trig.tr, timeScale: \dur.kr(1) )}; 184 | 185 | // - 0:7:42.4 - 186 | ~plc = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*8 * \amp.kr(1) * EnvGen.kr( Env.perc, \trig.tr, timeScale: \dur.kr(1) ) }; 187 | 188 | // - 0:7:57.26 - 189 | ~plc3[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 8, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 8, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 2, \trig, 1, \dur, 0.5 ); 190 | 191 | // - 0:7:59.05 - 192 | ~plc3[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 8, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 8, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 2, \trig, 1, \dur, 0.25 ); 193 | 194 | // - 0:8:1.39 - 195 | ~plc3[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 8, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 8, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 2, \trig, 1, \dur, 0.125 ); 196 | 197 | // - 0:8:3.33 - 198 | ~plc3[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 8, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 8, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 2, \trig, 1, \dur, 0.25 ); 199 | 200 | // - 0:8:7.71 - 201 | ~plc2[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 4, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 4, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ), \trig, 1, \dur, 0.25 ); 202 | 203 | // - 0:8:15.91 - 204 | ~plc2[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 4, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 4, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 2, \trig, 1, \dur, 0.25 ); 205 | 206 | // - 0:8:17.6 - 207 | ~plc2 = { PlayBuf.ar( 2, c, \rate.kr(1), loop: 1 )*8 * \amp.kr(1) * EnvGen.kr( Env.perc, \trig.tr, timeScale: \dur.kr(1) )}; 208 | 209 | // - 0:8:23.15 - 210 | ~plc[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ), \delta, Pseq( [2,1,1,0.25], inf) / 2, \amp, Pseq( [2,1,2,3], inf ) , \trig, 1, \dur, 0.5 ); 211 | 212 | // - 0:8:28.69 - 213 | ~plc[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ), \delta, Pseq( [2,1,1,0.25], inf) / 2, \amp, Pseq( [2,1,2,3], inf ) * 2, \trig, 1, \dur, 0.5 ); 214 | 215 | // - 0:8:30.55 - 216 | ~plc[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ), \delta, Pseq( [2,1,1,0.25], inf) / 2, \amp, Pseq( [2,1,2,3], inf ) * 3, \trig, 1, \dur, 0.5 ); 217 | 218 | // - 0:8:34.07 - 219 | ~plc[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ), \delta, Pseq( [2,1,1,0.25], inf) / 2, \amp, Pseq( [2,1,2,3], inf ) * 4, \trig, 1, \dur, 0.5 ); 220 | 221 | // - 0:8:42.01 - 222 | ~plc[1] = \set -> Pbind( \rate, Pseq( [1,4/5,5/4,2], inf ), \delta, Pseq( [2,1,1,0.25], inf) / 2, \amp, Pseq( [2,1,2,3], inf ) * 4, \trig, 1, \dur, 1 ); 223 | 224 | // - 0:8:46.25 - 225 | ~plc2[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 4, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 4, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 2, \trig, 1, \dur, 0.5 ); 226 | 227 | // - 0:8:49.21 - 228 | ~plc3[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * 8, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 8, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 2, \trig, 1, \dur, 0.5 ); 229 | 230 | // - 0:8:52.71 - 231 | ~plc4[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) / 2, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) * 2, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 8, \trig, 1, \dur, 2 ); 232 | 233 | // - 0:9:4.44 - 234 | ~plc4[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 8 ), inf ) / 2, \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) * 2, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 8, \trig, 1, \dur, 2 ); 235 | 236 | // - 0:9:37.15 - 237 | ~plc3[1] = \set -> Pbind( \rate, Pn( Pshuf( [1,4/5,5/4,2], 4 ), inf ) * Pstutter( 4, Pseq( [8,7,9,8], inf ) ), \delta, Pn( Pshuf( [2,1,1,0.25], 4 ), inf) / 8, \amp, Pn( Pshuf( [2,1,2,3], 4 ), inf ) * 2, \trig, 1, \dur, 0.5 ); 238 | 239 | // - 0:9:47.99 - 240 | p.stop(15); 241 | 242 | // - 0:9:51.83 - 243 | ~rec = { RecordBuf.ar( ~ps.ar, b, 0, 0, 0.6 ); }; 244 | 245 | // - 0:9:52.82 - 246 | ~rec = { RecordBuf.ar( ~ps.ar, b, 0, 0, 0.6 ); }; 247 | 248 | -------------------------------------------------------------------------------- /raphael-bastide/README.md: -------------------------------------------------------------------------------- 1 | # Cascade Patch for Behind The Screens 2 | 3 | .-.~-— - . -- —-. ——— 4 | |°|'| | ' ° 5 | '|| | 6 | . | || | 7 | . .-.~ ~° 8 | || '|' 9 | '|| '| 10 | | °| ' 11 | || | | 12 | . | | || , 13 | .\°| ° '/: 14 | —— ——— ——— —' ———— — —— 15 | 16 | Open bts.html in your web browser (best performances with chromium). You will see an prepared Cascade set with animations. You can try functions such as `add()` or with custom style: `add('background:green; top:3vh; width:80vw; height:20vh;')`. 17 | 18 | Cascade documentation : https://raphaelbastide.com/cascade/ 19 | 20 | Enjoy! 21 | 22 | raphaël -------------------------------------------------------------------------------- /raphael-bastide/bts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | cascade BTS 6 | 7 | 8 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 172 | 173 | -------------------------------------------------------------------------------- /raphael-bastide/css/cascade.css: -------------------------------------------------------------------------------- 1 | /* Reset */ 2 | html {box-sizing: border-box;}*,*::before,*::after {box-sizing: inherit;}body,h1,h2,h3,h4,h5,h6,ul,ol,li,p,pre,blockquote,figure,hr {margin: 0;padding: 0; font-size:100%; font-weight: normal;}ul {list-style: none;}input,textarea,select,button {color: inherit;font: inherit;letter-spacing: inherit;}input,textarea,button {border: 1px solid gray;}button {border-radius: 0;padding: 0.75em 1em;background-color: transparent;}button * {pointer-events: none;}embed,iframe,img,object,video {display: block;max-width: 100%;}table {table-layout: fixed;width: 100%;}[hidden] {display: none !important;}noscript {display: block;margin-bottom: 1em;margin-top: 1em;} 3 | /* Buttons and input buttons */ 4 | [role="button"],input[type="submit"],input[type="reset"],input[type="button"],button { -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box;} 5 | input[type="submit"], input[type="reset"], input[type="button"], button { background: none; border: 0; color: inherit; font: inherit; line-height: normal; overflow: visible; padding: 0; } 6 | input::-moz-focus-inner, button::-moz-focus-inner { border: 0; padding: 0;} 7 | #c{font: clamp(12px, .8vw, 20px)/1.5em monospace; letter-spacing: 1px;} 8 | a{color:black;} 9 | #c.mute:after{content:""; position:absolute; width:100%; height:100vh; background:black; z-index: 200; opacity:.8;border:20vw solid black;} 10 | /* Cascade */ 11 | :root{ 12 | --c0:white; 13 | --c1:black; 14 | --c2:tan; 15 | --c3:blue; 16 | --c4:cyan; 17 | --c5:gold; 18 | --c6:gray; 19 | --c7:lime; 20 | --c8:magenta; 21 | --c9:peru; 22 | --c10:pink; 23 | --c11:red; 24 | --c12:teal; 25 | --c13:khaki; 26 | --c14:olive; 27 | --c15:purple; 28 | --c16:silver; 29 | } 30 | .show-grid .c-grid{background-image: linear-gradient(white 1px, transparent 1px), linear-gradient(90deg, white 1px, transparent 1px); z-index: 200; pointer-events: none; opacity: .5; 31 | background-size: 101px 101px; width:100vw; height:100vw; text-transform: uppercase;} 32 | .start{position: absolute; top:0; left: 0; bottom:0; right:0; background: lightgray; width:100%; opacity: .8; z-index: 900; display: flex; justify-content: center; align-items: center; cursor: pointer;} 33 | [data-instrument]{position: relative;} 34 | [data-instrument]:hover{z-index:200;} 35 | [data-instrument]:before{ 36 | content: attr(id); 37 | /* background: white; */ 38 | position: absolute; 39 | top:-1.2em; right:0; 40 | opacity: 0; 41 | height: 0; 42 | } 43 | .active{ 44 | /* opacity:.5; */ 45 | margin-top:2px; 46 | /* outline:3px solid; */ 47 | } 48 | .scan [data-instrument]:before{opacity:1; width:auto; height:auto;} 49 | .color-scale{display: none; position: absolute; bottom: 0; left:0;} 50 | .c-timer{display: none; position: absolute; top: 0; right:0;} 51 | .color-box, .c-timer{height:20px; padding:0 2px; text-shadow: 1px 1px 1px white} 52 | .color-box:before{content: attr(data-name); text-shadow: 1px 1px 1px white} 53 | .scan .color-scale, .scan .c-timer{display: flex;} 54 | .cas{position: relative} 55 | -------------------------------------------------------------------------------- /raphael-bastide/js/cascade.js: -------------------------------------------------------------------------------- 1 | // Cascade v.0.6 2 | // https://raphaelbastide.com/cascade 3 | 4 | let d = document; 5 | let allowedCssProperties = ['opacity', 'display', 'visibility', 'background', 'background-color', 'border-top-left-radius', 'border-top-right-radius', 'border-bottom-right-radius', 'border-bottom-left-radius', 'width', 'height', 'border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width', ]; 6 | let defaultCascadeClass = ".cas"; 7 | let defaultRoot = "body"; 8 | let defaultIntervalBpmbasis = intervalBpmBasis = 60000; 9 | 10 | 11 | class Cascade { 12 | constructor(rootNode = defaultRoot, options = {}) { 13 | if (typeof rootNode === 'string' || rootNode instanceof String) { // checking if rootnode is a selector (string) or object 14 | this.rootNode = d.querySelector(rootNode); 15 | if (d.body.contains(this.rootNode)) { 16 | // always returns false when checking Shadowdom. Use non-string selector (element objects) in case of a shadowDom Cascade root 17 | this.rootNode.style.position = "relative"; 18 | } else { 19 | console.info('Invalid root element'); 20 | return; 21 | } 22 | }else{ 23 | this.rootNode = rootNode; 24 | } 25 | 26 | this.state = { 27 | isMute: false, 28 | playing: false, 29 | tick: 0, 30 | timerInterval:0, 31 | userHasBeenWarned: false 32 | } 33 | 34 | this.documentCssRules = this.getDocumentCssRules(); 35 | this.bpm = this.getbpm(); 36 | this.els = []; 37 | this.insList = []; 38 | this.colors = []; 39 | this.intervalBpmBasis = defaultIntervalBpmbasis; 40 | this.interval = Math.round(intervalBpmBasis / (this.bpm)); 41 | this.cascadeClass = options.cascadeClass ? options.cascadeClass : defaultCascadeClass; 42 | this.instruments = options.instruments ? options.instruments : instruments; 43 | this.startButton = options.startButton == undefined ? true : options.startButton; 44 | this.defaultStyle = options.defaultStyle ? options.defaultStyle : "width:100px; height:200px; background-color:var(--c0); position:absolute; bottom:40vh; left:40vw;" 45 | this.debugTime = options.debugTime == undefined ? false : options.debugTime; 46 | this.init(); 47 | let event = new CustomEvent('newCascade', { 48 | detail: { 49 | cascade: this 50 | } 51 | }); 52 | if (options.newCascadeEvent != false) { 53 | // this is used for cascade pool. It must be explicitly set as false for multi performers 54 | d.dispatchEvent(event); 55 | } 56 | } 57 | 58 | getDocumentCssRules() { 59 | let proto = Element.prototype; 60 | let slice = Function.call.bind(Array.prototype.slice); 61 | let matches = Function.call.bind(proto.matchesSelector || 62 | proto.mozMatchesSelector || proto.webkitMatchesSelector || 63 | proto.msMatchesSelector || proto.oMatchesSelector); 64 | return slice(document.styleSheets).reduce(function(rules, styleSheet) { 65 | return rules.concat(slice(styleSheet.cssRules)); 66 | }, []); 67 | } 68 | 69 | init() { 70 | if (!this.rootNode) { 71 | return; 72 | } else { 73 | console.info('Welcome to Cascade') 74 | } 75 | this.rootNode.id = 'c'; 76 | this.createInstruments() 77 | makeColorList() 78 | 79 | let elNodes = this.rootNode.querySelectorAll(':scope > ' + this.cascadeClass); 80 | elNodes.forEach((elNode, i) => { 81 | this.initEl(this.rootNode, elNode); 82 | }); 83 | this.addMutationObserverChildren(this.rootNode, this.rootNode); 84 | if (this.startButton) { 85 | this.createStartBtn(); 86 | } 87 | } 88 | 89 | nextTick() { 90 | if (!this.state.playing) { 91 | this.state.tick = -1 92 | return 93 | } 94 | // BPM 95 | if (this.bpm != this.getbpm()) { 96 | this.bpm = this.getbpm() 97 | console.info('BPM = ' + this.bpm); 98 | let event = new CustomEvent('update', { 99 | detail: { 100 | element: this.rootNode, 101 | } 102 | }) 103 | // dispatch the event 104 | this.rootNode.dispatchEvent(event); 105 | 106 | } 107 | // Interpret all elements 108 | if (this.els.length == 0 && !this.state.userHasBeenWarned) { 109 | console.info("No HTML element found, try adding one with add()"); 110 | this.state.userHasBeenWarned = true; 111 | } else if (this.els.length != 0) { 112 | this.els.forEach((el, i) => { 113 | this.interpret(el) 114 | }); 115 | } 116 | this.state.tick++ 117 | this.interval = Math.round(this.intervalBpmBasis / this.bpm); 118 | return setTimeout(function() { 119 | return this.nextTick(); 120 | }.bind(this), this.interval); 121 | } 122 | 123 | initEl(parent, elNode, elsArray) { 124 | let el = new cElement(elNode, window.getComputedStyle(elNode), this); 125 | this.addMutationObserverChildren(el, elNode) 126 | if (parent == this.rootNode) { 127 | let newIdNumber; 128 | if (this.els[this.els.length-1]) { 129 | newIdNumber = Number(this.els[this.els.length-1].htmlNode.id.split('-').pop()); 130 | newIdNumber++; 131 | } else { 132 | newIdNumber = 0 133 | } 134 | this.els.push(el); 135 | elNode.id = parent.id + "-" + newIdNumber; 136 | } else { 137 | let newIdNumber; 138 | if (parent.children[parent.children.length-1]) { 139 | newIdNumber = Number(parent.children[parent.children.length-1].htmlNode.id.split('-').pop()); 140 | newIdNumber++; 141 | } else { 142 | newIdNumber = 0 143 | } 144 | parent.children.push(el); 145 | elNode.id = parent.htmlNode.id + "-" + newIdNumber; 146 | } 147 | let children = elNode.querySelectorAll(this.cascadeClass); 148 | children.forEach((childNode, i) => { 149 | this.initEl(el, childNode); 150 | }); 151 | } 152 | 153 | addMutationObserverChildren(parent, parentNode) { 154 | // watches for new nodes added to the page and adds them to the cascade 155 | let config = { 156 | childList: true, 157 | }; 158 | let self = this; 159 | let mutationCallbackChildren = function(mutationsList) { 160 | mutationsList.forEach((mutation, i) => { 161 | if (mutation.type == 'childList') { 162 | mutation.addedNodes.forEach((newNode, i) => { 163 | if (newNode.classList && newNode.classList.contains(self.cascadeClass.slice(1))) { 164 | 165 | self.initEl(parent, newNode); 166 | if (parent.htmlNode) { 167 | console.info('Added new element ' + newNode.id + ' to ' + parent.htmlNode.id); 168 | } else { 169 | console.info('Added new element ' + newNode.id + ' to ' + parent.id); 170 | } 171 | 172 | let event = new CustomEvent('add', { 173 | detail: { 174 | parent: parent, 175 | newNode: newNode, 176 | } 177 | }) 178 | // dispatch the event 179 | self.rootNode.dispatchEvent(event); 180 | 181 | if (parent != self.rootNode) { 182 | parent.htmlNode.setAttribute('data-childs', parent.children.length); 183 | } 184 | 185 | } else { 186 | // Leaving this for now because there is unnecessaty divs being created 187 | // and it needs investigation 188 | // console.log(newNode); 189 | } 190 | }); 191 | 192 | mutation.removedNodes.forEach((deletedNode, i) => { 193 | if (deletedNode.classList.contains(self.cascadeClass.slice(1))) { 194 | let event = new CustomEvent('rm', { 195 | detail: { 196 | params: { 197 | id: deletedNode.id 198 | } 199 | } 200 | }) 201 | // dispatch the event 202 | self.rootNode.dispatchEvent(event); 203 | 204 | let filterRule = itemFilter => itemFilter.htmlNode == deletedNode; 205 | let elToDelete = filterRecursive(self.els, filterRule)[0]; 206 | let pathElToDelete = findInRecursiveArray(self.els, elToDelete)[0].path.reverse(); 207 | if (pathElToDelete) { 208 | if (pathElToDelete.length == 1) { 209 | self.els[pathElToDelete[0]].computedProperties.currentInstrument.numberOfElsPlaying--; 210 | self.els.splice(pathElToDelete[0], 1) 211 | } else { 212 | let parentOfElToDelete = self.els[pathElToDelete[i]] 213 | for (var i = 1; i < pathElToDelete.length-1; i++) { 214 | parentOfElToDelete = parentOfElToDelete.children[pathElToDelete[i]] 215 | } 216 | parentOfElToDelete.children[pathElToDelete[pathElToDelete.length-1]].computedProperties.currentInstrument.numberOfElsPlaying--; 217 | parentOfElToDelete.children.splice(pathElToDelete[pathElToDelete.length-1], 1) 218 | } 219 | } 220 | } 221 | }); 222 | } 223 | }); 224 | }; 225 | let childrenObserver = new MutationObserver(mutationCallbackChildren); 226 | childrenObserver.observe(parentNode, config); 227 | } 228 | 229 | interpret(element) { 230 | // check if something changed in the style of the element 231 | if (!element.compare(window.getComputedStyle(element.htmlNode))) { 232 | this.documentCssRules = this.getDocumentCssRules(); 233 | // update the element 234 | element.update() 235 | } 236 | 237 | let elProp = element.computedProperties 238 | let cycle = Number(element.htmlNode.getAttribute('data-cycle')) 239 | if (element.htmlNode.getAttribute('data-cycle') == undefined) { 240 | element.htmlNode.setAttribute('data-cycle', 0) 241 | } 242 | let probRan = Math.floor(Math.random() * 10) 243 | if ( 244 | element.cssProperties['display'] !== "none" && 245 | element.cssProperties['visibility'] !== "hidden" && 246 | (elProp.euclPat[cycle - 1]) == 1 247 | ) { 248 | setTimeout(function() { 249 | if (this.debugTime) { 250 | if (typeof timeTracking === "function") { 251 | timeTracking(element, arguments[0], elProp.delay); 252 | } else { 253 | console.info('Cannot debug: deubugTime is `true`, but debug.js is not linked to this page.'); 254 | } 255 | } 256 | 257 | if (elProp.probability > probRan) { 258 | if (!this.state.isMute && element.children.length == 0) { // not muted & has no child 259 | // console.log(elProp.panVal); 260 | // if(elProp.panVal < -10){elProp.panVal = -10}else if(elProp.panVal > 10){elProp.panVal = 10} 261 | if (elProp.insSynthType !== "none") { 262 | // console.log(elProp.panVal / 20 + .5); 263 | // console.log(panner.pan); 264 | // panner.connect() 265 | // Change volume depending on element surface and volume correction 266 | elProp.currentInstrument.volume.value = Math.round(elProp.surface / 20000) + elProp.volumeCorrection 267 | // Caps volume value to 10db 268 | if (elProp.currentInstrument.volume.value >= 10) { 269 | elProp.currentInstrument.volume.value = 10 270 | } 271 | } 272 | 273 | if (elProp.insSynthType === "NoiseSynth") { 274 | try { 275 | elProp.currentInstrument.triggerAttackRelease(elProp.duration); 276 | // elProp.currentInstrument.envelope.sustain = elProp.duration; 277 | // elProp.currentInstrument.start() 278 | // setTimeout(() => { 279 | // elProp.currentInstrument.stop() 280 | // }, elProp.duration); 281 | } catch (e) { 282 | console.info("Multiple overlapping synths. Higher instrumentDuplicate advised."); 283 | } 284 | } else if (elProp.insSynthType === "PluckSynth") { 285 | try { 286 | elProp.currentInstrument.triggerAttack(elProp.note, elProp.duration); 287 | } catch (e) { 288 | console.info("Multiple overlapping synths. Higher instrumentDuplicate advised."); 289 | } 290 | } else if (elProp.insSynthType === "none") { 291 | // do nothing :3 292 | } else { 293 | try { 294 | elProp.currentInstrument.triggerAttackRelease(elProp.note, elProp.duration); 295 | } catch (e) { 296 | console.info("Multiple overlapping synths. Higher instrumentDuplicate advised."); 297 | } 298 | } 299 | } 300 | activatecElement(element.htmlNode); 301 | // interpret children 302 | element.children.forEach((child, i) => { 303 | this.interpret(child); 304 | }); 305 | } 306 | }.bind(this), elProp.delay, Date.now() /* only used if debugTime */ ); 307 | } 308 | if (cycle >= elProp.euclPat.length) { 309 | cycle = 0 310 | } 311 | cycle++ 312 | element.htmlNode.setAttribute('data-cycle', cycle) 313 | } 314 | 315 | createInstruments() { 316 | if (typeof this.instruments !== 'undefined' ) { 317 | this.instruments.forEach((instrument, index) => { 318 | let synthType = instrument.synth 319 | let insOptions = instrument.options; 320 | this.insList[instrument.name] = []; 321 | let newSynth = {} 322 | 323 | if (synthType == "none") { 324 | // newSynth = new Tone.Synth().toDestination() 325 | } else { 326 | newSynth = new Tone[synthType](insOptions).toDestination() 327 | } 328 | newSynth.numberOfElsPlaying = 0; 329 | this.insList[instrument.name].push(newSynth); 330 | }); 331 | }else{ 332 | console.info('Instruments missing'); 333 | } 334 | } 335 | 336 | getbpm() { 337 | let color = window.getComputedStyle(this.rootNode).getPropertyValue('background-color'); 338 | let lum = RGBtoHSL(color)['lum'] 339 | let bpm = Math.round(lum * 3) + 20; // *2 makes enlarge the bpm range, currently in test 340 | bpm = bpm >= 0 ? bpm : 1; 341 | // sets interval as CSS variable for animation syncing 342 | this.rootNode.style.setProperty('--interval', this.interval / 1000); 343 | return bpm 344 | } 345 | } 346 | 347 | class cElement { 348 | constructor(htmlNode, computedStyle, cascade) { 349 | this.cascadeParent = cascade; 350 | this.htmlNode = htmlNode; 351 | this.previousCssPropertiesObj = this.cssStyleDeclarationToJsObj(computedStyle); 352 | this.cssProperties = this.setCssProperties(computedStyle); 353 | this.children = []; 354 | this.computedProperties = this.setComputedProperties(); 355 | this.htmlNode.setAttribute('data-ratio', this.computedProperties["ratio"][0] + ":" + this.computedProperties["ratio"][1]) 356 | this.htmlNode.setAttribute('data-instrument', this.computedProperties["insID"]) 357 | } 358 | 359 | update() { 360 | this.previousCssPropertiesObj = this.cssStyleDeclarationToJsObj(window.getComputedStyle(this.htmlNode)); 361 | this.cssProperties = this.setCssProperties(window.getComputedStyle(this.htmlNode)); 362 | this.computedProperties = this.setComputedProperties(); 363 | this.htmlNode.setAttribute('data-ratio', this.computedProperties["ratio"][0] + ":" + this.computedProperties["ratio"][1]) 364 | this.htmlNode.setAttribute('data-instrument', this.computedProperties["insID"]); 365 | let event = new CustomEvent('update', { 366 | detail: { 367 | element: this, 368 | } 369 | }) 370 | // dispatch the event 371 | this.cascadeParent.rootNode.dispatchEvent(event); 372 | } 373 | 374 | compare(currentComputedStyle) { 375 | let currentComputedStyleObj = this.cssStyleDeclarationToJsObj(currentComputedStyle) 376 | return JSON.stringify(this.previousCssPropertiesObj) === JSON.stringify(currentComputedStyleObj) 377 | } 378 | setCssProperties(computedStyle) { 379 | // combine computed style with nonComputedStyle in order to also 380 | // gather non explicitly defined css properties. 381 | let computedStyleObj = this.cssStyleDeclarationToJsObj(computedStyle); 382 | let nonComputedStyleObj = this.getNonComputedStyle(); 383 | let arrayTemp = [computedStyleObj, nonComputedStyleObj]; 384 | arrayTemp = arrayTemp.reduce(function(result, current) { 385 | return Object.assign(result, current); 386 | }, {}); 387 | 388 | return this.filterCssProperties(arrayTemp, allowedCssProperties) 389 | } 390 | cssStyleDeclarationToJsObj(styleDeclaration) { 391 | // CSSStyleDeclaration https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration 392 | let obj = {}; 393 | for (var i = 0; i < styleDeclaration.length; i++) { 394 | obj[styleDeclaration[i]] = styleDeclaration.getPropertyValue(styleDeclaration[i]); 395 | } 396 | return obj; 397 | } 398 | filterCssProperties(cssProperties, allowedCssProperties) { 399 | // Modified version of https://stackoverflow.com/questions/38750705/filter-object-properties-by-key-in-es6 400 | // Filters the array so that only the relevant p 401 | let filteredArray = Object.keys(cssProperties).filter(key => allowedCssProperties.includes(key)) 402 | return filteredArray.reduce((obj, key) => { 403 | obj[key] = cssProperties[key]; 404 | return obj; 405 | }, {}); 406 | } 407 | 408 | getNonComputedStyle() { 409 | var elementMatchCSSRule = function(element, cssRule) { 410 | let proto = Element.prototype; 411 | let slice = Function.call.bind(Array.prototype.slice); 412 | let matches = Function.call.bind(proto.matchesSelector || 413 | proto.mozMatchesSelector || proto.webkitMatchesSelector || 414 | proto.msMatchesSelector || proto.oMatchesSelector); 415 | return matches(element, cssRule.selectorText); 416 | }; 417 | // based on this wonderfull piece of code https://gist.github.com/ZER0/5267608 418 | // Only gather explicitly defined css properties 419 | // For example, if there is no border on an element, 420 | // the property "border" won't be part of the array returned 421 | let cssRules = this.cascadeParent.documentCssRules.filter(elementMatchCSSRule.bind(null, this.htmlNode)); 422 | cssRules = cssRules.map(function(item) { 423 | return item["style"]; 424 | }); 425 | cssRules.push(this.htmlNode.style) 426 | let arrayTemp = []; 427 | cssRules.forEach((item, i) => { 428 | arrayTemp.push(this.cssStyleDeclarationToJsObj(item)); 429 | }); 430 | 431 | return arrayTemp.reduce(function(result, current) { 432 | return Object.assign(result, current); 433 | }, {}); 434 | } 435 | 436 | setComputedProperties() { 437 | let obj = {} 438 | let instruments = this.cascadeParent.instruments; 439 | if ((!this.computedProperties) || (this.computedProperties && this.computedProperties.insID != getVarNbr(this.cssProperties['background-color']))) { 440 | // if the instrument isn't setuped yet or 441 | // if the element is updated and the instrument has changed 442 | if (this.computedProperties) { 443 | this.computedProperties.currentInstrument.numberOfElsPlaying > 0 ? this.computedProperties.currentInstrument.numberOfElsPlaying-- : this.computedProperties.currentInstrument.numberOfElsPlaying = 0; 444 | } 445 | obj.insID = getVarNbr(this.cssProperties['background-color']); 446 | obj.instrumentDuplicate = instruments[obj.insID].instrumentDuplicate ? instruments[obj.insID].instrumentDuplicate : 0; 447 | obj.currentInstrument = this.getInstrument(obj.insID, obj.instrumentDuplicate) 448 | } else if (this.computedProperties) { 449 | obj.insID = this.computedProperties.insID; 450 | obj.instrumentDuplicate = instruments[obj.insID].instrumentDuplicate ? instruments[obj.insID].instrumentDuplicate : 0; 451 | obj.currentInstrument = this.computedProperties.currentInstrument; 452 | } 453 | obj.insName = Object.keys(this.cascadeParent.insList)[obj.insID]; 454 | obj.insSynthType = instruments[obj.insID].synth; 455 | obj.volumeCorrection = instruments[obj.insID].volumeCorrection 456 | obj.relativePos = this.getRelativePos(this.htmlNode); 457 | obj.delay = Math.round(obj.relativePos.x * this.cascadeParent.interval / 100) < 0 ? 0 : Math.round(obj.relativePos.x * this.cascadeParent.interval / 100); 458 | obj.ratio = getRatio(parseInt(this.cssProperties.width), parseInt(this.cssProperties.height)) 459 | // Surface has to be pixel based otherwise vol will change with ≠ units 460 | obj.surface = this.getSurfaceInPixels(this.htmlNode) 461 | obj.note = Math.min(300, Math.round(obj.relativePos.y) + 30) 462 | obj.borderTW = parseInt(this.cssProperties['border-top-width']); 463 | obj.borderRW = parseInt(this.cssProperties['border-right-width']) 464 | obj.borderBW = parseInt(this.cssProperties['border-bottom-width']) 465 | obj.borderLW = parseInt(this.cssProperties['border-left-width']) 466 | obj.radTL = parseInt(this.cssProperties['border-top-left-radius']) 467 | obj.radTR = parseInt(this.cssProperties['border-top-right-radius']) 468 | obj.radBR = parseInt(this.cssProperties['border-bottom-right-radius']) 469 | obj.radBL = parseInt(this.cssProperties['border-bottom-left-radius']) 470 | obj.totalBorderRadius = (obj.radTL + obj.radTR + obj.radBR + obj.radBL) / 4; 471 | obj.probability = this.cssProperties['opacity'] * 10 472 | obj.duration = obj.totalBorderRadius == 0 ? .01 : obj.totalBorderRadius / 20 473 | obj.euclSteps = Math.max(obj.ratio[0], obj.ratio[1]) 474 | obj.euclBeats = Math.min(obj.ratio[0], obj.ratio[1]) 475 | obj.panVal = (obj.borderRW - obj.borderLW) 476 | obj.euclPat = generatePattern(obj.euclBeats, obj.euclSteps); 477 | shiftPat(obj.euclPat, obj.borderTW); 478 | 479 | // problem with negative duration; 480 | 481 | return obj; 482 | } 483 | 484 | getRelativePos(element) { 485 | let pos = element.getBoundingClientRect() 486 | let parentPos = element.parentNode.getBoundingClientRect() 487 | let relativePos = [] 488 | relativePos.top = pos.top - parentPos.top, 489 | relativePos.right = pos.right - parentPos.right, 490 | relativePos.bottom = pos.bottom - parentPos.bottom, 491 | relativePos.left = pos.left - parentPos.left; 492 | let propPosX = (pos.left - parentPos.left) * 100 / this.cascadeParent.rootNode.getBoundingClientRect().width; 493 | let propPosY = pos.top * 100 / this.cascadeParent.rootNode.getBoundingClientRect().height; 494 | return { 495 | x: propPosX, 496 | y: propPosY 497 | } 498 | } 499 | 500 | getSurfaceInPixels(element){ 501 | return Math.floor(element.offsetWidth * element.offsetHeight) 502 | } 503 | getInstrument(index, instrumentDuplicate) { 504 | let currentInstrument = {}; 505 | if (index) { 506 | let insList = this.cascadeParent.insList; 507 | let instruments = this.cascadeParent.instruments; 508 | 509 | let currentInstrumentArray = insList[Object.keys(insList)[index]]; 510 | let filterRule = itemFilter => itemFilter.computedProperties.insID == index; 511 | let numberOfElsPlayingSameInstrument = filterRecursive(this.cascadeParent.els, filterRule); 512 | if (Math.round(instrumentDuplicate * numberOfElsPlayingSameInstrument.length + 1) > currentInstrumentArray.length) { 513 | console.info("Adding a new tonejs synth"); 514 | let synthType = instruments[index].synth; 515 | let insName = instruments[index].name; 516 | let insOptions = instruments[index].options; 517 | if (synthType == "none") { 518 | currentInstrument = new Tone.Synth(insOptions).toDestination() 519 | } else { 520 | currentInstrument = new Tone[synthType](insOptions).toDestination(); 521 | } 522 | currentInstrument.numberOfElsPlaying = 1; 523 | insList[insName].push(currentInstrument); 524 | } else { 525 | // assign to the element the synth with the least amount of element plaing it 526 | let minNumberOfElsPlaying = Math.min(...insList[instruments[index].name].map(item => item.numberOfElsPlaying)); 527 | currentInstrument = insList[instruments[index].name].filter(item => item.numberOfElsPlaying === minNumberOfElsPlaying)[0] 528 | currentInstrument.numberOfElsPlaying++; 529 | } 530 | } else { 531 | // if the element has no defined synth, fallback on the first one of the list 532 | currentInstrument = this.insList[Object.keys(this.insList)[0][0]]; 533 | } 534 | return currentInstrument; 535 | } 536 | } 537 | 538 | 539 | const findInRecursiveArray = (items, itemToFind) => { 540 | // https://stackoverflow.com/questions/57717986/track-path-of-recursive-function 541 | // the path is backward and needs to be reversed before use 542 | let path = [] 543 | // console.log(items); 544 | items.forEach((item,i) => { 545 | 546 | if('children' in item){ 547 | let item_path = findInRecursiveArray(item.children, itemToFind) 548 | 549 | if(item_path.length > 0){ 550 | item_path[0].path.push(i) 551 | path.push(item_path[0]) 552 | } 553 | } 554 | if(items.indexOf(itemToFind) != -1){ 555 | path.push({path:[items.indexOf(itemToFind)]}) 556 | } 557 | }) 558 | return path 559 | } 560 | 561 | // 562 | // function findInRecursiveArray(array, itemToFind, path) { 563 | // // console.log(array, itemToFind, path); 564 | // // console.log(array, itemToFind); 565 | // let result; 566 | // if (array.indexOf(itemToFind) != -1) { 567 | // // console.log("here"); 568 | // result = path.concat(array.indexOf(itemToFind)); 569 | // // console.log(); 570 | // } else { 571 | // for (var i = 0; i < array.length; i++) { 572 | // if (array[i].children) { 573 | // return findInRecursiveArray(array[i].children, itemToFind, path.concat(i)) 574 | // } else { 575 | // return; 576 | // } 577 | // } 578 | // } 579 | // return result; 580 | // } 581 | 582 | function filterRecursive(arrayTofilter, filterRule) { 583 | let destinationArray = []; 584 | arrayTofilter.forEach((item, i) => { 585 | // console.log(item); 586 | if (item.children) { 587 | destinationArray = destinationArray.concat(filterRecursive(item.children, filterRule)); 588 | } 589 | if (filterRule(item)) { 590 | destinationArray.push(item) 591 | } 592 | }); 593 | return destinationArray 594 | } 595 | 596 | // System functions 597 | // Cascade API 598 | 599 | Cascade.prototype.start = function(delay, sendEvent) { 600 | setTimeout(function() { 601 | if (!this.state.playing) { 602 | this.state.playing = true 603 | this.nextTick() 604 | console.info('Cascade started'); 605 | this.initTimer(); 606 | if (sendEvent != false) { 607 | let event = new CustomEvent('start') 608 | this.rootNode.dispatchEvent(event); 609 | } 610 | } else { 611 | console.info('Already started'); 612 | } 613 | if (this.rootNode.querySelector('.start')) { 614 | this.rootNode.querySelector('.start').remove() 615 | } 616 | }.bind(this), delay * 1000); 617 | } 618 | 619 | Cascade.prototype.stop = function(sendEvent) { 620 | if (this.state.playing) { 621 | this.state.playing = false 622 | console.info('Cascade stopped'); 623 | clearInterval(this.state.timerInterval) 624 | if (sendEvent != false) { 625 | let event = new CustomEvent('stop') 626 | this.rootNode.dispatchEvent(event); 627 | } 628 | } 629 | } 630 | 631 | Cascade.prototype.mute = function() { 632 | this.state.isMute = !this.state.isMute 633 | if (this.state.isMute) { 634 | this.rootNode.classList.add('mute') 635 | }else{ 636 | this.rootNode.classList.remove('mute') 637 | } 638 | } 639 | 640 | Cascade.prototype.add = function(style = this.defaultStyle, parentId = "c", copies = 1) { 641 | style = style == null || style == false || style == "" ? this.defaultStyle : style; 642 | let elementsList = [] 643 | if (parentId == "c") { 644 | parent = this.rootNode 645 | } else { 646 | parent = this.rootNode.querySelector("#" + parentId) 647 | } 648 | if (parent == undefined) { 649 | console.info('Chosen parent element is undefined'); 650 | return 651 | } else { 652 | for (var i = 0; i < copies; i++) { 653 | let el = d.createElement("div") 654 | el.classList.add(this.cascadeClass.slice(1)); 655 | if (style) 656 | el.style = style 657 | parent.appendChild(el) 658 | elementsList.push(el) 659 | } 660 | } 661 | } 662 | 663 | Cascade.prototype.rawStyle = function(css) { 664 | let style = d.querySelector('style').innerHTML; 665 | d.querySelector('style').innerHTML = style + "\n" + css 666 | } 667 | 668 | Cascade.prototype.mod = function(style, id) { 669 | if (Array.isArray(id)) { 670 | for (var i = 0; i < id.length; i++) { 671 | let el = this.rootNode.querySelector("#c-" + id[i]) 672 | if (!checkSelector(el)){return false} 673 | el.style.cssText += style 674 | } 675 | }else { 676 | let el = this.rootNode.querySelector("#c-" + id); 677 | if (!checkSelector(el)){return false} 678 | el.style.cssText += style 679 | } 680 | } 681 | 682 | Cascade.prototype.addCl = function(cl, id) { 683 | let el = this.rootNode.querySelector("#c-" + id); 684 | if (!checkSelector(el)){return false} 685 | el.classList.add(cl) 686 | } 687 | 688 | Cascade.prototype.rmCl = function(cl, id) { 689 | let el = this.rootNode.querySelector("#c-" + id) 690 | if (!checkSelector(el)){return false} 691 | el.classList.remove(cl) 692 | } 693 | 694 | Cascade.prototype.clone = function(style, id) { 695 | let elToClone = this.rootNode.querySelector("#c-" + id) 696 | if (!checkSelector(elToClone)){return false} 697 | let el = elToClone.cloneNode(true); 698 | if (style) { 699 | el.style.cssText += style 700 | } 701 | parent = elToClone.parentNode; 702 | parent.appendChild(el); 703 | console.info('Cloned new element ' + id); 704 | let event = new CustomEvent('clone', { 705 | detail: { 706 | element: el 707 | } 708 | }) 709 | this.rootNode.dispatchEvent(event); 710 | } 711 | 712 | Cascade.prototype.on = function(eventTolistenTo, callback) { 713 | return this.rootNode.addEventListener(eventTolistenTo, callback) 714 | } 715 | 716 | Cascade.prototype.rm = function(id, sendEvent) { 717 | if (Array.isArray(id)) { 718 | id.forEach((idItem, i) => { 719 | if (this.rootNode.querySelector("#c-" + idItem)) { 720 | this.rootNode.querySelector("#c-" + idItem).remove(); 721 | console.info('cElement ' + idItem + ' removed'); 722 | } else { 723 | console.info('cElement doesn’t exist'); 724 | } 725 | }); 726 | } else { 727 | if (this.rootNode.querySelector("#c-" + id)) { 728 | this.rootNode.querySelector("#c-" + id).remove(); 729 | console.info('cElement ' + id + ' removed'); 730 | } else { 731 | console.info('cElement doesn’t exist'); 732 | } 733 | } 734 | } 735 | 736 | Cascade.prototype.clear = function() { 737 | this.els.forEach((element, i) => { 738 | element.htmlNode.remove() 739 | }); 740 | console.info('Cleared all elements') 741 | } 742 | 743 | Cascade.prototype.ls = function() { 744 | this.els.forEach((element, i) => { 745 | console.info(element.htmlNode, element.htmlNode.id) 746 | }); 747 | } 748 | 749 | Cascade.prototype.dl = function(fileName) { 750 | let date = new Date().getTime(); 751 | let html = document.querySelector('html').innerHTML 752 | if (!fileName) { 753 | fileName = "cascade-" + date + ".html" 754 | } 755 | download(html, fileName, "text/html"); 756 | } 757 | 758 | Cascade.prototype.scan = function(time = 4) { 759 | this.createColorTable() 760 | this.rootNode.classList.add('scan') 761 | setTimeout(function() { 762 | this.rootNode.classList.remove('scan') 763 | }.bind(this), time * 1000); 764 | return 765 | } 766 | 767 | Cascade.prototype.grid = function(time = 10) { 768 | if (typeof(this.rootNode.querySelector('.c-grid')) != 'undefined' && 769 | this.rootNode.querySelector('.c-grid') != null) { 770 | let gridEl = this.rootNode.querySelector('.c-grid') 771 | } else { 772 | let gridEl = d.createElement('div') 773 | gridEl.classList.add('c-grid') 774 | this.rootNode.appendChild(gridEl) 775 | } 776 | this.rootNode.classList.add('show-grid') 777 | setTimeout(function() { 778 | this.rootNode.classList.remove('show-grid') 779 | }.bind(this), time * 1000); 780 | return 781 | } 782 | 783 | Cascade.prototype.copyNodeStyle = function(sourceNode, targetNode) { 784 | const computedStyle = window.getComputedStyle(sourceNode); 785 | Array.from(computedStyle).forEach(key => targetNode.style.setProperty(key, computedStyle.getPropertyValue(key), computedStyle.getPropertyPriority(key))) 786 | } 787 | 788 | // function 789 | 790 | function activatecElement(element) { 791 | element.classList.add('active') 792 | setTimeout(function() { 793 | element.classList.remove('active') 794 | }, 50); 795 | } 796 | 797 | 798 | Cascade.prototype.createStartBtn = function() { 799 | let startBtn = d.createElement('button') 800 | startBtn.classList.add('start') 801 | startBtn.innerHTML = "" 802 | startBtn.addEventListener('click', () => this.activateToneJs()) 803 | this.rootNode.appendChild(startBtn) 804 | } 805 | 806 | Cascade.prototype.activateToneJs = function() { 807 | Tone.Transport.start() 808 | this.start() 809 | this.rootNode.querySelector('.start').remove() 810 | } 811 | 812 | Cascade.prototype.createColorTable = function() { 813 | if (this.rootNode.querySelector('.color-scale')) { 814 | this.rootNode.querySelector('.color-scale').remove() 815 | } 816 | let scale = d.createElement('div') 817 | scale.classList.add('color-scale') 818 | this.rootNode.appendChild(scale) 819 | for (var i = 0; i < colors.length; i++) { 820 | let colorBox = d.createElement('div') 821 | colorBox.classList.add('color-box') 822 | colorBox.style.backgroundColor = colors[i].hex 823 | colorBox.setAttribute('data-var', colors[i].var) 824 | if (!instruments[i] || instruments[i] == 'undefined') { 825 | colorBox.setAttribute('data-name', "undef") 826 | } else { 827 | colorBox.setAttribute('data-name', instruments[i].name) 828 | } 829 | scale.appendChild(colorBox) 830 | } 831 | } 832 | 833 | Cascade.prototype.initTimer = function() { 834 | timerMin = 0 835 | let timer = d.createElement('div') 836 | timer.classList.add('c-timer') 837 | timer.innerHTML = timerMin 838 | this.rootNode.appendChild(timer) 839 | this.state.timerInterval = setInterval(() => { 840 | timerMin++ 841 | timer.innerHTML = timerMin 842 | console.info('⧗ ' + timerMin) 843 | }, 60000); 844 | } 845 | 846 | function getVarNbr(rgbColor) { 847 | makeColorList(); 848 | let needleHex = allToHex(rgbColor) 849 | for (var i = 0; i < colors.length; i++) { 850 | closerColor = getClosestColor(needleHex) 851 | if (closerColor == colors[i].hex) { // if element’s color matches a line 852 | let cssVar = colors[i].var.replace("--c", "") // get number only 853 | return cssVar 854 | } 855 | } 856 | } 857 | 858 | function makeColorList() { 859 | colors = [] // empty the color array 860 | let vars = getColorCSSVars() // get colorvar and colorname 861 | for (var i = 0; i < vars.length; i++) { 862 | let colorVar = vars[i][0] // retrive var from getColorCSSVars 863 | let colorName = vars[i][1] // retrive name from getColorCSSVars 864 | let hex = allToHex(colorName) 865 | let color = {} // create color object 866 | color.name = colorName 867 | color.var = colorVar 868 | color.hex = hex 869 | colors.push(color) // add the color to colors array 870 | } 871 | } 872 | 873 | // Get applied CSS variables 874 | const isSameDomain = (styleSheet) => { 875 | if (!styleSheet.href) { 876 | return true; 877 | } 878 | return styleSheet.href.indexOf(window.location.origin) === 0; 879 | }; 880 | const isStyleRule = (rule) => rule.type === 1; 881 | const getColorCSSVars = () => [...document.styleSheets].filter(isSameDomain).reduce( 882 | (finalArr, sheet) => 883 | finalArr.concat( 884 | [...sheet.cssRules].filter(isStyleRule).reduce((propValArr, rule) => { 885 | const props = [...rule.style] 886 | .map((propName) => [ 887 | propName.trim(), 888 | rule.style.getPropertyValue(propName).trim() 889 | ]) 890 | .filter(([propName]) => propName.indexOf("--c") === 0); 891 | 892 | return [...propValArr, ...props]; 893 | }, []) 894 | ), 895 | [] 896 | ); 897 | 898 | // Utils 899 | function generatePattern(beats, steps) { 900 | // Bjorklund algorithm from https://gist.github.com/withakay/1286731 901 | steps = Math.round(steps) 902 | beats = Math.round(beats) 903 | if (beats > steps || beats == 0 || isNaN(beats) || steps == 0 || isNaN(steps)) { 904 | console.info('Element needs width / height'); 905 | return [] 906 | } 907 | let pattern = [] 908 | let counts = [] 909 | let remainders = [] 910 | let divisor = steps - beats 911 | remainders.push(beats) 912 | let level = 0 913 | while (true) { 914 | counts.push(Math.floor(divisor / remainders[level])) 915 | remainders.push(divisor % remainders[level]) 916 | divisor = remainders[level] 917 | level += 1 918 | if (remainders[level] <= 1) { 919 | break 920 | } 921 | } 922 | counts.push(divisor) 923 | let r = 0 924 | const build = function(level) { 925 | r += 1 926 | if (level > -1) { 927 | for (var i = 0; i < counts[level]; i++) { 928 | build(level - 1) 929 | } 930 | if (remainders[level] !== 0) { 931 | build(level - 2) 932 | } 933 | } else if (level === -1) { 934 | pattern.push(0) 935 | } else if (level === -2) { 936 | pattern.push(1) 937 | } 938 | } 939 | build(level) 940 | return pattern.reverse() 941 | } 942 | 943 | function checkSelector(el){ 944 | if (el == undefined) { 945 | console.info('Wrong selector'); 946 | return false 947 | }else{ 948 | return true 949 | } 950 | } 951 | function RGBtoHSL(rgb) { 952 | // https://css-tricks.com/converting-color-spaces-in-javascript/ 953 | // If rgba, the color is still considered valid but the a isn't taken into consideration 954 | let ex = /^rgb\((((((((1?[1-9]?\d)|10\d|(2[0-4]\d)|25[0-5]),\s?)){2}|((((1?[1-9]?\d)|10\d|(2[0-4]\d)|25[0-5])\s)){2})((1?[1-9]?\d)|10\d|(2[0-4]\d)|25[0-5]))|((((([1-9]?\d(\.\d+)?)|100|(\.\d+))%,\s?){2}|((([1-9]?\d(\.\d+)?)|100|(\.\d+))%\s){2})(([1-9]?\d(\.\d+)?)|100|(\.\d+))%))\)$/i; 955 | let ex_rgba = /^rgba\((((((((1?[1-9]?\d)|10\d|(2[0-4]\d)|25[0-5]),\s?)){3})|(((([1-9]?\d(\.\d+)?)|100|(\.\d+))%,\s?){3}))|(((((1?[1-9]?\d)|10\d|(2[0-4]\d)|25[0-5])\s){3})|(((([1-9]?\d(\.\d+)?)|100|(\.\d+))%\s){3}))\/\s)((0?\.\d+)|[01]|(([1-9]?\d(\.\d+)?)|100|(\.\d+))%)\)$/i; 956 | if (ex.test(rgb) || ex_rgba.test(rgb)) { 957 | let sep = rgb.indexOf(",") > -1 ? "," : " "; 958 | if (ex.test(rgb)) { 959 | rgb = rgb.substr(4).split(")")[0].split(sep); 960 | } else { 961 | rgb = rgb.substr(5).split(")")[0].split(sep); 962 | 963 | } 964 | for (let R in rgb) { 965 | let r = rgb[R]; 966 | if (r.indexOf("%") > -1) 967 | rgb[R] = Math.round(r.substr(0, r.length - 1) / 100 * 255); 968 | } 969 | 970 | let r = rgb[0] / 255, 971 | g = rgb[1] / 255, 972 | b = rgb[2] / 255, 973 | cmin = Math.min(r, g, b), 974 | cmax = Math.max(r, g, b), 975 | delta = cmax - cmin, 976 | h = 0, 977 | s = 0, 978 | l = 0; 979 | if (delta == 0) 980 | h = 0; 981 | else if (cmax == r) 982 | h = ((g - b) / delta) % 6; 983 | else if (cmax == g) 984 | h = (b - r) / delta + 2; 985 | else 986 | h = (r - g) / delta + 4; 987 | h = Math.round(h * 60); 988 | if (h < 0) 989 | h += 360; 990 | l = (cmax + cmin) / 2; 991 | s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1)); 992 | s = +(s * 100).toFixed(1); 993 | l = +(l * 100).toFixed(1); 994 | return { 995 | 'hue': h, 996 | 'sat': s, 997 | 'lum': l 998 | } 999 | } else { 1000 | console.info('Invalid color'); 1001 | return { 1002 | 'hue': 100, 1003 | 'sat': 100, 1004 | 'lum': 100 1005 | }; 1006 | } 1007 | } 1008 | 1009 | function allToHex(colorStr) { 1010 | var a = document.createElement('div'); 1011 | a.style.color = colorStr; 1012 | var colors = window.getComputedStyle(document.body.appendChild(a)).color.match(/\d+/g).map(function(a) { 1013 | return parseInt(a, 10); 1014 | }); 1015 | document.body.removeChild(a); 1016 | return (colors.length >= 3) ? '#' + (((1 << 24) + (colors[0] << 16) + (colors[1] << 8) + colors[2]).toString(16).substr(1)) : false; 1017 | } 1018 | 1019 | function getRatio(a, b) { 1020 | if (isNaN(a) || isNaN(b)) { 1021 | return [0, 0] 1022 | } else { 1023 | return [a / gcd(a, b), b / gcd(a, b)] 1024 | } 1025 | } 1026 | 1027 | function gcd(a, b) { // greatest common divisor 1028 | return (b == 0) ? a : gcd(b, a % b); 1029 | } 1030 | 1031 | function shiftPat(pattern, shiftVal) { 1032 | while (shiftVal > 0) { 1033 | let last = pattern.pop() 1034 | pattern.unshift(last) 1035 | shiftVal-- 1036 | } 1037 | } 1038 | 1039 | function getClosestColor(hex) { 1040 | let stats = [] 1041 | for (var i = 0; i < colors.length; i++) { 1042 | let color = {} 1043 | color.hex = colors[i].hex 1044 | color.score = hexColorDelta(colors[i].hex, hex) 1045 | stats.push(color) 1046 | } 1047 | stats = stats.sort((a, b) => b.score - a.score) 1048 | let bestScore = stats[0].hex 1049 | return bestScore 1050 | } 1051 | 1052 | function hexColorDelta(hex1, hex2) { 1053 | hex1 = hex1.replace("#", "") 1054 | hex2 = hex2.replace("#", "") 1055 | var r1 = parseInt(hex1.substring(0, 2), 16); 1056 | var g1 = parseInt(hex1.substring(2, 4), 16); 1057 | var b1 = parseInt(hex1.substring(4, 6), 16); 1058 | // get red/green/blue int values of hex2 1059 | var r2 = parseInt(hex2.substring(0, 2), 16); 1060 | var g2 = parseInt(hex2.substring(2, 4), 16); 1061 | var b2 = parseInt(hex2.substring(4, 6), 16); 1062 | // calculate differences between reds, greens and blues 1063 | var r = 255 - Math.abs(r1 - r2); 1064 | var g = 255 - Math.abs(g1 - g2); 1065 | var b = 255 - Math.abs(b1 - b2); 1066 | // limit differences between 0 and 1 1067 | r /= 255; 1068 | g /= 255; 1069 | b /= 255; 1070 | // 0 means opposit colors, 1 means same colors 1071 | return (r + g + b) / 3; 1072 | } 1073 | const getRealCssVal = (el, property) => { 1074 | // Chrome only 1075 | // let styleMap = el.computedStyleMap(); 1076 | // const unitvalue = styleMap.get(property); 1077 | 1078 | // Firefox compatible 1079 | const unitvalue = getComputedStyle(el).getPropertyValue(property) 1080 | if (unitvalue.unit == undefined) { // avoid fatal js error 1081 | return "0px" 1082 | } 1083 | return unitvalue.value 1084 | } 1085 | -------------------------------------------------------------------------------- /raphael-bastide/js/debug.js: -------------------------------------------------------------------------------- 1 | 2 | function average(element, array) { 3 | element.timeTracking["averageDifference"] = array.reduce((a, b) => a + b) / array.length; 4 | // console.log("Average difference: " + element.timeTracking["average"]) + "ms"; 5 | } 6 | 7 | function timeTracking(element, timeFunctionSet, delay) { 8 | if(!element.timeTracking){ 9 | element.timeTracking = [[]]; 10 | } 11 | let timeFunctionExecuted = Date.now(); 12 | let difference = timeFunctionExecuted - (timeFunctionSet + delay); 13 | // As long as the difference is under 10-25ms it should be imperceptible 14 | element.timeTracking[element.timeTracking.length - 1].push(difference); 15 | average(element, element.timeTracking[0]); 16 | } 17 | 18 | // Used convienience during dev to see if 19 | // there is any errors or to check on some values 20 | function startAndStop(delay){ 21 | setTimeout(function() { 22 | start(); 23 | setTimeout(function() { 24 | stop() 25 | }, delay); 26 | }, 10); 27 | } 28 | 29 | 30 | Cascade.prototype.initAndStop = function(delay){ 31 | setTimeout(function() { 32 | this.init(); 33 | setTimeout(function() { 34 | this.stop() 35 | }.bind(this), delay); 36 | }.bind(this), 10); 37 | } 38 | -------------------------------------------------------------------------------- /raphael-bastide/js/download.js: -------------------------------------------------------------------------------- 1 | //download.js v4.2, by dandavis; 2008-2016. [CCBY2] see http://danml.com/download.html for tests/usage 2 | // v1 landed a FF+Chrome compat way of downloading strings to local un-named files, upgraded to use a hidden frame and optional mime 3 | // v2 added named files via a[download], msSaveBlob, IE (10+) support, and window.URL support for larger+faster saves than dataURLs 4 | // v3 added dataURL and Blob Input, bind-toggle arity, and legacy dataURL fallback was improved with force-download mime and base64 support. 3.1 improved safari handling. 5 | // v4 adds AMD/UMD, commonJS, and plain browser support 6 | // v4.1 adds url download capability via solo URL argument (same domain/CORS only) 7 | // v4.2 adds semantic variable names, long (over 2MB) dataURL support, and hidden by default temp anchors 8 | // https://github.com/rndme/download 9 | 10 | (function (root, factory) { 11 | if (typeof define === 'function' && define.amd) { 12 | // AMD. Register as an anonymous module. 13 | define([], factory); 14 | } else if (typeof exports === 'object') { 15 | // Node. Does not work with strict CommonJS, but 16 | // only CommonJS-like environments that support module.exports, 17 | // like Node. 18 | module.exports = factory(); 19 | } else { 20 | // Browser globals (root is window) 21 | root.download = factory(); 22 | } 23 | }(this, function () { 24 | 25 | return function download(data, strFileName, strMimeType) { 26 | 27 | var self = window, // this script is only for browsers anyway... 28 | defaultMime = "application/octet-stream", // this default mime also triggers iframe downloads 29 | mimeType = strMimeType || defaultMime, 30 | payload = data, 31 | url = !strFileName && !strMimeType && payload, 32 | anchor = document.createElement("a"), 33 | toString = function(a){return String(a);}, 34 | myBlob = (self.Blob || self.MozBlob || self.WebKitBlob || toString), 35 | fileName = strFileName || "download", 36 | blob, 37 | reader; 38 | myBlob= myBlob.call ? myBlob.bind(self) : Blob ; 39 | 40 | if(String(this)==="true"){ //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback 41 | payload=[payload, mimeType]; 42 | mimeType=payload[0]; 43 | payload=payload[1]; 44 | } 45 | 46 | 47 | if(url && url.length< 2048){ // if no filename and no mime, assume a url was passed as the only argument 48 | fileName = url.split("/").pop().split("?")[0]; 49 | anchor.href = url; // assign href prop to temp anchor 50 | if(anchor.href.indexOf(url) !== -1){ // if the browser determines that it's a potentially valid url path: 51 | var ajax=new XMLHttpRequest(); 52 | ajax.open( "GET", url, true); 53 | ajax.responseType = 'blob'; 54 | ajax.onload= function(e){ 55 | download(e.target.response, fileName, defaultMime); 56 | }; 57 | setTimeout(function(){ ajax.send();}, 0); // allows setting custom ajax headers using the return: 58 | return ajax; 59 | } // end if valid url? 60 | } // end if url? 61 | 62 | 63 | //go ahead and download dataURLs right away 64 | if(/^data\:[\w+\-]+\/[\w+\-]+[,;]/.test(payload)){ 65 | 66 | if(payload.length > (1024*1024*1.999) && myBlob !== toString ){ 67 | payload=dataUrlToBlob(payload); 68 | mimeType=payload.type || defaultMime; 69 | }else{ 70 | return navigator.msSaveBlob ? // IE10 can't do a[download], only Blobs: 71 | navigator.msSaveBlob(dataUrlToBlob(payload), fileName) : 72 | saver(payload) ; // everyone else can save dataURLs un-processed 73 | } 74 | 75 | }//end if dataURL passed? 76 | 77 | blob = payload instanceof myBlob ? 78 | payload : 79 | new myBlob([payload], {type: mimeType}) ; 80 | 81 | 82 | function dataUrlToBlob(strUrl) { 83 | var parts= strUrl.split(/[:;,]/), 84 | type= parts[1], 85 | decoder= parts[2] == "base64" ? atob : decodeURIComponent, 86 | binData= decoder( parts.pop() ), 87 | mx= binData.length, 88 | i= 0, 89 | uiArr= new Uint8Array(mx); 90 | 91 | for(i;i { 16 | makeInterractive(existingEl) 17 | }); 18 | // Make elements created live, interactive 19 | cascadeObj.on('add', function(e) { 20 | let el = e.detail.newNode; 21 | makeInterractive(el) 22 | }) 23 | cascadeObj.on('clone', function(e) { 24 | let el = e.detail.element; 25 | makeInterractive(el) 26 | }) 27 | }) 28 | 29 | function makeInterractive(el){ 30 | bindClick(el) 31 | dragElement(el) 32 | el.style.resize = 'both' 33 | el.style.overflow = 'hidden' 34 | } 35 | 36 | // Click 37 | function bindClick(el){ 38 | el.onclick = function(e){ 39 | if (e.shiftKey) { 40 | browseColors(el) 41 | } 42 | } 43 | el.addEventListener('dblclick', function (e) { 44 | if (!e.shiftKey) { 45 | el.remove() 46 | } 47 | }); 48 | } 49 | 50 | // Silver random 51 | let silverRandom = function(element){ 52 | randomPickedColor = cssColors[Math.floor(Math.random() * cssColors.length)].hex 53 | if (randomPickedColor != "#c0c0c0") { // avoid picking silver again 54 | element.style.backgroundColor = randomPickedColor 55 | } 56 | } 57 | 58 | // Drag 59 | function dragElement(elmnt) { 60 | let pos1 = 0, 61 | pos2 = 0, 62 | pos3 = 0, 63 | pos4 = 0; 64 | elmnt.onmousedown = dragMouseDown; 65 | function dragMouseDown(e) { 66 | if (!e.ctrlKey) { // ctrl is used for resize 67 | e = e || window.event; 68 | e.preventDefault(); 69 | pos3 = e.clientX; 70 | pos4 = e.clientY; 71 | document.onmouseup = closeDragElement; 72 | // call a function whenever the cursor moves: 73 | document.onmousemove = elementDrag; 74 | } 75 | } 76 | function elementDrag(e) { 77 | dragActive = true; 78 | e = e || window.event; 79 | e.preventDefault(); 80 | // calculate the new cursor position: 81 | pos1 = pos3 - e.clientX; 82 | pos2 = pos4 - e.clientY; 83 | pos3 = e.clientX; 84 | pos4 = e.clientY; 85 | // set the element's new position: 86 | elmnt.style.top = (elmnt.offsetTop - pos2) + "px"; 87 | elmnt.style.left = (elmnt.offsetLeft - pos1) + "px"; 88 | } 89 | function closeDragElement() { 90 | dragActive = false; 91 | document.onmouseup = null; 92 | document.onmousemove = null; 93 | } 94 | } 95 | 96 | // Browse colors 97 | const browseColors = (el) => { 98 | let cs = window.getComputedStyle(el) 99 | let currentColor 100 | let picked 101 | if (el.silverRandomMode) { 102 | // Check is a silver random anim is currently in use 103 | clearInterval(el.silverInterval) 104 | el.silverRandomMode = false 105 | currentColor = '#c0c0c0' 106 | }else{ 107 | currentColor = cs.getPropertyValue("background-color") 108 | } 109 | for (var i = 0; i < colors.length; i++) { 110 | // If current color is in color array, loop 111 | if (allToHex(currentColor) == colors[i].hex && i+1 < colors.length){ 112 | picked = colors[i+1].hex 113 | } 114 | } 115 | if (!picked){ 116 | // Nothing found? End of the list? -> go back color 1 117 | el.style.backgroundColor = colors[0].hex 118 | }else { 119 | if (picked == "#c0c0c0") { 120 | // Silver color? -> random color animation 121 | el.silverRandomMode = true 122 | el.silverInterval = setInterval(() => { 123 | silverRandom(el) 124 | }, 200); 125 | }else{ 126 | el.style.backgroundColor = picked 127 | } 128 | } 129 | } 130 | 131 | // Message 132 | function message(content, time=5){ 133 | let messageBox 134 | if (d.querySelector('.message-box') == undefined) { 135 | messageBox = d.createElement('div') 136 | messageBox.classList.add('message-box') 137 | d.body.appendChild(messageBox) 138 | }else { 139 | messageBox = d.querySelector('.message-box') 140 | } 141 | messageBox.innerHTML = content 142 | setTimeout(function () { 143 | messageBox.remove() 144 | }, time * 1000); 145 | } 146 | -------------------------------------------------------------------------------- /raphael-bastide/js/live-shortcut.js: -------------------------------------------------------------------------------- 1 | let cascadeArrayShortcut = []; 2 | 3 | d.addEventListener("newCascade", function(e) { 4 | let newCascadeObj = e.detail.cascade; 5 | cascadeArrayShortcut.push(newCascadeObj); 6 | }) 7 | 8 | 9 | function add(style = this.defaultStyle, parentId = "c", copies = 1) { 10 | if (cascadeArrayShortcut.length == 1) { 11 | cascadeArrayShortcut[0].add(style, parentId, copies) 12 | } else { 13 | errorShortcut(); 14 | } 15 | } 16 | 17 | function start(delay, sendEvent) { 18 | if (cascadeArrayShortcut.length == 1) { 19 | cascadeArrayShortcut[0].start(delay, sendEvent) 20 | } else { 21 | errorShortcut(); 22 | } 23 | } 24 | 25 | function stop(sendEvent) { 26 | if (cascadeArrayShortcut.length == 1) { 27 | cascadeArrayShortcut[0].stop(sendEvent) 28 | } else { 29 | errorShortcut(); 30 | } 31 | } 32 | 33 | function mute() { 34 | if (cascadeArrayShortcut.length == 1) { 35 | cascadeArrayShortcut[0].mute() 36 | } else { 37 | errorShortcut(); 38 | } 39 | } 40 | 41 | function rawStyle(style) { 42 | if (cascadeArrayShortcut.length == 1) { 43 | cascadeArrayShortcut[0].rawStyle(style) 44 | } else { 45 | errorShortcut(); 46 | } 47 | } 48 | 49 | function mod(style, id) { 50 | if (cascadeArrayShortcut.length == 1) { 51 | cascadeArrayShortcut[0].mod(style, id) 52 | } else { 53 | errorShortcut(); 54 | } 55 | } 56 | 57 | function addCl(cl, id) { 58 | if (cascadeArrayShortcut.length == 1) { 59 | cascadeArrayShortcut[0].addCl(cl, id) 60 | } else { 61 | errorShortcut(); 62 | } 63 | } 64 | 65 | function rmCl(cl, id) { 66 | if (cascadeArrayShortcut.length == 1) { 67 | cascadeArrayShortcut[0].rmCl(cl, id) 68 | } else { 69 | errorShortcut(); 70 | } 71 | } 72 | 73 | function clone(style, elToCloneID) { 74 | if (cascadeArrayShortcut.length == 1) { 75 | cascadeArrayShortcut[0].clone(style, elToCloneID) 76 | } else { 77 | errorShortcut(); 78 | } 79 | } 80 | 81 | function on(eventTolistenTo, callback) { 82 | if (cascadeArrayShortcut.length == 1) { 83 | cascadeArrayShortcut[0].on(eventTolistenTo, callback) 84 | } else { 85 | errorShortcut(); 86 | } 87 | } 88 | 89 | function rm(id, sendEvent) { 90 | if (cascadeArrayShortcut.length == 1) { 91 | cascadeArrayShortcut[0].rm(id, sendEvent) 92 | } else { 93 | errorShortcut(); 94 | } 95 | } 96 | 97 | function clear() { 98 | if (cascadeArrayShortcut.length == 1) { 99 | cascadeArrayShortcut[0].clear(); 100 | } else { 101 | errorShortcut(); 102 | } 103 | } 104 | 105 | function ls() { 106 | if (cascadeArrayShortcut.length == 1) { 107 | cascadeArrayShortcut[0].ls() 108 | } else { 109 | errorShortcut(); 110 | } 111 | } 112 | 113 | function dl(fileName) { 114 | if (cascadeArrayShortcut.length == 1) { 115 | cascadeArrayShortcut[0].dl() 116 | } else { 117 | errorShortcut(); 118 | } 119 | } 120 | 121 | function scan(time = 4) { 122 | if (cascadeArrayShortcut.length == 1) { 123 | cascadeArrayShortcut[0].scan(time) 124 | } else { 125 | errorShortcut(); 126 | } 127 | } 128 | 129 | function grid(time = 10) { 130 | if (cascadeArrayShortcut.length == 1) { 131 | cascadeArrayShortcut[0].grid(time) 132 | } else { 133 | errorShortcut(); 134 | } 135 | } 136 | 137 | function copyNodeStyle(sourceNode, targetNode) { 138 | if (cascadeArrayShortcut.length == 1) { 139 | cascadeArrayShortcut[0].copyNodeStyle(sourceNode, targetNode) 140 | } else { 141 | errorShortcut(); 142 | } 143 | } 144 | 145 | function message(content) { 146 | if (cascadeArrayShortcut.length == 1) { 147 | cascadeArrayShortcut[0].message(content) 148 | } else { 149 | errorShortcut(); 150 | } 151 | } 152 | 153 | function errorShortcut() { 154 | if (cascadeArrayShortcut == 0) { 155 | console.log('No Cascade instance yet'); 156 | } else { 157 | console.log('Several Cascade instances are running. Please use refToCascadeInstance.function()'); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /roald-vandillewijn/Mercury.txt: -------------------------------------------------------------------------------- 1 | set tempo 100 2 | set scale lydian E 3 | 4 | ring notesOne sine(12) 5 | ring notesTwo clone(notesOne -3 -5 7 12) 6 | ring notesThree clone(notesOne -5 -7 5 9) 7 | 8 | ring beatOne hexBeat(fade) 9 | ring beatTwo hexBeat(cafe) 10 | ring beatThree hexBeat(dead) 11 | 12 | new synth saw note(notesOne) wave2(sine 0.5) env(5000 5000) time(4) 13 | new synth saw note(notesTwo 2) wave2(saw 0.9976) env(5000 5000) time(5 1/4) 14 | new synth saw note(notesThree 2.5) wave2(saw 0.995) env(5000 5000) time(3 1/2) 15 | 16 | new sample kick_909 beat(beatOne) time(1/4) name(f) 17 | new sample snare_909 beat(beatTwo) time(1/8) name(f) 18 | new sample hat_909 beat(beatOne) time(1/16) gain(0.8) 19 | 20 | set f fx(filter low 1500) gain(0.5) 21 | 22 | new emitter osc name(volante) 23 | new emitter osc name(particle) 24 | new emitter osc name(cathedral) 25 | new emitter osc name(tensor) 26 | new emitter osc name(mixer) 27 | new emitter osc name(ottobit) 28 | 29 | ring rndfreeze random(25 0 127) 30 | ring rndpart random(100 0 127) 31 | ring rndlfo random(50 0 127) 32 | set volante _bypass(127 change) time(4) 33 | // set cathedral _bypass(1 change) time(4) 34 | set particle _bypass(127 change) time(4) 35 | set particle dens(rndpart) time(1) 36 | set particle lforate(rndlfo) time(1) 37 | set particle freeze(rndfreeze) time(1/2) 38 | set mixer channel1(1 change) time(4) 39 | set tensor _bypass(127 change) time(4) 40 | 41 | set ottobit _bypass(127 change) time(4) 42 | set ottobit stutter(rndpart) time(1) 43 | set cathedral _bypass(0 change) 44 | set ottobit fade(filter 0 127 120000 once) -------------------------------------------------------------------------------- /roald-vandillewijn/README.md: -------------------------------------------------------------------------------- 1 | ## CCU 10 minute live coding ## 2 | 3 | 10 minute live code performance by [Roald van Dillewijn](https://www.roaldvandillewijn.nl) 4 | 5 | To run exactly this code you'll need: 6 | 7 | - [Mercury](https://github.com/tmhglnd/mercury) 8 | - [DigilogOSC](https://github.com/roaldvdillewijn/digilogOSC) 9 | - All the pedals I used, including the hacked ones.. 10 | 11 | To use MIDI-enabled pedals or other gear combined with Mercury you check out the README from DigilogOSC. 12 | 13 | Thanks to [Creative Coding Utrecht](http://creativecodingutrecht.nl)! 14 | 15 | -------------------------------------------------------------------------------- /sasj/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netherlands-coding-live/community-code/9c717ea94e27e2891de1afee6643b8e6ec89daaa/sasj/.DS_Store -------------------------------------------------------------------------------- /sasj/CCU_10minlivecoding.js: -------------------------------------------------------------------------------- 1 | //hydra 2 | 3 | osc([30,40,100],0.05,[0.001,0.2,0.7]) 4 | .posterize(4,10) 5 | .scrollX( ()=> a.fft[2]*0.01) 6 | .rotate(0.6,0.1) 7 | .scale(0.2) 8 | .out(o1) 9 | 10 | 11 | solid(0,0,0) 12 | .add(o1,1) 13 | .mult(shape(4).rotate(0.8,0.2).repeat([4],1,0.4,0.5).modulateScale(osc(0.2,0.0005).scale(0.01))) 14 | .scrollX( () => a.fft[0]*0.01,0.01) 15 | .scrollY(0.01,0.1) 16 | .scale(0.1) 17 | .out(o3) 18 | 19 | render(o3) 20 | -------------------------------------------------------------------------------- /sasj/README.md: -------------------------------------------------------------------------------- 1 | # CCU_10minlivecoding 2 | 10 minute livecoding challenge CCU - June 16 2020 3 | 4 | 5 | [CCU / Creative Coding Utrecht](http://creativecodingutrecht.nl) 6 | 7 | 8 | Created with [Hydra](https://github.com/ojack/hydra) 9 | 10 | Music by: [eerieear](https://github.com/eerieear/e_e-ccu) 11 | 12 | -------------------------------------------------------------------------------- /sonologico/README.md: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | 3 | In order to run this, you're going to need: 4 | 5 | * https://gitlab.com/gamag/ocaml-synth 6 | * https://csound.com/ 7 | 8 | Feel free to message me (@sonologico) if you need help. 9 | 10 | -------------------------------------------------------------------------------- /sonologico/gen.ml: -------------------------------------------------------------------------------- 1 | open Containers 2 | 3 | module Gen (M : Mllvin_intf.S) = struct 4 | open M 5 | 6 | let now () = Unix.gettimeofday () 7 | 8 | let seconds () = 9 | let zero = now () in 10 | fun () -> now () -. zero 11 | 12 | 13 | let singleton x = 14 | let finished = ref false in 15 | fun () -> 16 | if !finished 17 | then raise Done 18 | else ( 19 | finished := true ; 20 | x ) 21 | 22 | 23 | let of_array xs = 24 | let i = ref 0 in 25 | fun () -> 26 | if !i >= Array.length xs 27 | then raise Done 28 | else ( 29 | incr i ; 30 | xs.(!i) ) 31 | 32 | 33 | let of_list xs = of_array (Array.of_list xs) 34 | 35 | let take n g = 36 | let k = ref n in 37 | fun () -> 38 | if !k = 0 39 | then raise Done 40 | else ( 41 | decr k ; 42 | g () ) 43 | 44 | 45 | let discard g = 46 | ignore (g ()) ; 47 | g 48 | 49 | 50 | let drop n g = 51 | let rec loop g = function 0 -> () | k -> loop (discard g) (k - 1) in 52 | loop g n ; 53 | g 54 | 55 | 56 | let interleave xs = 57 | let arr = Array.of_list xs in 58 | let index = ref 0 in 59 | fun () -> 60 | let i = !index in 61 | index := (i + 1) mod Array.length arr ; 62 | arr.(i) () 63 | 64 | 65 | let repeat x () = x 66 | 67 | let ( ~> ) = repeat 68 | 69 | let cycle xs = 70 | let arr = Array.of_list xs in 71 | let index = ref 0 in 72 | fun () -> 73 | let i = !index in 74 | index := (i + 1) mod Array.length arr ; 75 | arr.(i) 76 | 77 | 78 | let stutter count gen = 79 | let curr = ref None in 80 | let curr_count = ref 0 in 81 | fun () -> 82 | while !curr_count = 0 do 83 | curr := Some (gen ()) ; 84 | curr_count := count () 85 | done ; 86 | decr curr_count ; 87 | Option.get_exn !curr 88 | 89 | 90 | let seq ?(single = false) lst = 91 | let arr = Array.of_seq (Seq.map (fun f -> f ()) (List.to_std_seq lst)) in 92 | let index = ref 0 in 93 | let rec loop () = 94 | let i = !index in 95 | if i < Array.length arr 96 | then ( 97 | try arr.(i) () with 98 | | Done -> 99 | incr index ; 100 | loop () ) 101 | else if single 102 | then raise Done 103 | else ( 104 | List.iteri (fun i f -> arr.(i) <- f ()) lst ; 105 | index := 0 ; 106 | loop () ) 107 | in 108 | loop 109 | 110 | 111 | let time_bound dur f = 112 | let limit = now () +. dur in 113 | fun () -> Float.(if now () >= limit then raise Done else f ()) 114 | 115 | 116 | let tbseq ?(single = false) lst = 117 | seq ~single (List.map (fun (f, d) () -> time_bound d (f ())) lst) 118 | 119 | 120 | let zip_with f a b () = f (a ()) (b ()) 121 | 122 | module Rnd = struct 123 | let int low high () = Random.run (Random.int_range low (high - 1)) 124 | 125 | let float low high () = Random.run (Random.float_range low high) 126 | 127 | let bool = Random.bool 128 | 129 | let beta ~alpha ~beta = 130 | let distr = Pareto.Distributions.Beta.create ~alpha ~beta in 131 | fun () -> Pareto.Distributions.Beta.random distr 132 | 133 | 134 | let bernoulli p = 135 | let distr = Pareto.Distributions.Bernoulli.create ~p in 136 | fun () -> Pareto.Distributions.Bernoulli.random distr 137 | 138 | 139 | let binomial ~trials ~p = 140 | let distr = Pareto.Distributions.Binomial.create ~trials ~p in 141 | fun () -> Pareto.Distributions.Binomial.random distr 142 | 143 | 144 | let cauchy ~location ~scale = 145 | let distr = Pareto.Distributions.Cauchy.create ~location ~scale in 146 | fun () -> Pareto.Distributions.Cauchy.random distr 147 | 148 | 149 | let chi_squared df = 150 | let distr = Pareto.Distributions.ChiSquared.create ~df in 151 | fun () -> Pareto.Distributions.ChiSquared.random distr 152 | 153 | 154 | let exponential scale = 155 | let distr = Pareto.Distributions.Exponential.create ~scale in 156 | fun () -> Pareto.Distributions.Exponential.random distr 157 | 158 | 159 | let gamma ~shape ~scale = 160 | let distr = Pareto.Distributions.Gamma.create ~shape ~scale in 161 | fun () -> Pareto.Distributions.Gamma.random distr 162 | 163 | 164 | let gaussian mean stdev = 165 | let distr = Pareto.Distributions.Normal.create ~mean ~sd:stdev in 166 | fun () -> Pareto.Distributions.Normal.random distr 167 | 168 | 169 | let geometric p = 170 | let distr = Pareto.Distributions.Geometric.create ~p in 171 | fun () -> Pareto.Distributions.Geometric.random distr 172 | 173 | 174 | let hypergeometric ~m ~t ~k = 175 | let distr = Pareto.Distributions.Hypergeometric.create ~m ~t ~k in 176 | fun () -> Pareto.Distributions.Hypergeometric.random distr 177 | 178 | 179 | let logistic ~location ~scale = 180 | let distr = Pareto.Distributions.Logistic.create ~location ~scale in 181 | fun () -> Pareto.Distributions.Logistic.random distr 182 | 183 | 184 | let log_normal ~mean ~stdev = 185 | let distr = Pareto.Distributions.LogNormal.create ~mean ~sd:stdev in 186 | fun () -> Pareto.Distributions.LogNormal.random distr 187 | 188 | 189 | let negative_binomial ~failures ~p = 190 | let distr = Pareto.Distributions.NegativeBinomial.create ~failures ~p in 191 | fun () -> Pareto.Distributions.NegativeBinomial.random distr 192 | 193 | 194 | let poisson rate = 195 | let distr = Pareto.Distributions.Poisson.create ~rate in 196 | fun () -> Pareto.Distributions.Poisson.random distr 197 | 198 | 199 | let t df = 200 | let distr = Pareto.Distributions.T.create ~df in 201 | fun () -> Pareto.Distributions.T.random distr 202 | 203 | 204 | let one_of xs = 205 | let arr = Array.of_list xs in 206 | fun () -> arr.(Random.run (Random.int (Array.length arr))) 207 | 208 | 209 | module Weighted_int = Pareto.Distributions.Categorical.Make (Int) 210 | 211 | let wone_of xs = 212 | let arr = Array.of_list xs in 213 | let arr_fst = Array.map fst arr in 214 | let distr = 215 | Weighted_int.create (Array.mapi (fun i (_, prob) -> (i, prob)) arr) 216 | in 217 | fun () -> 218 | let i = Weighted_int.random distr in 219 | arr_fst.(i) 220 | end 221 | 222 | let rec filter f xs () = 223 | let x = xs () in 224 | if f xs then x else filter f xs () 225 | 226 | 227 | let map f g () = f (g ()) 228 | 229 | let bind f g () = f (g ()) () 230 | 231 | let labelled_pair label dur = 232 | let ref = dref label Dyn.Conv.(tup2 float float) in 233 | match !?ref with 234 | | None -> 235 | let zero_t = now () in 236 | let pair = (zero_t, zero_t +. dur) in 237 | ref <-- pair ; 238 | pair 239 | | Some pair -> 240 | pair 241 | 242 | 243 | let line ?(continue = false) label ((a, b) as dst) dur = 244 | let open Float in 245 | let cmp_f = if b > a then Float.min else Float.max in 246 | let src = labelled_pair label dur in 247 | fun () -> 248 | let x = Gamag.Range_map.lin_exp ~src ~dst (now ()) in 249 | if continue then x else cmp_f b x 250 | 251 | 252 | let linex ?(continue = false) label ((a, b) as dst) dur = 253 | let open Float in 254 | let cmp_f = if b > a then Float.min else Float.max in 255 | let src = labelled_pair label dur in 256 | fun () -> 257 | let x = Gamag.Range_map.lin_exp ~src ~dst (now ()) in 258 | if continue then x else cmp_f b x 259 | 260 | 261 | let sine label range period = 262 | let src = labelled_pair label period in 263 | fun () -> 264 | Gamag.Range_map.lin ~src:(-1.0, 1.0) ~dst:range 265 | @@ sin 266 | @@ Gamag.Range_map.lin 267 | ~src 268 | ~dst: 269 | ( 0.0 270 | , 2.0 271 | *. 3.141592653589793238462643 272 | ) 273 | (now ()) 274 | 275 | 276 | let cosine ?(range = (0.0, 1.0)) period = 277 | let zero_t = now () in 278 | fun () -> 279 | Gamag.Range_map.lin ~src:(-1.0, 1.0) ~dst:range 280 | @@ cos 281 | @@ Gamag.Range_map.lin 282 | ~src:(zero_t, zero_t +. period) 283 | ~dst: 284 | ( 0.0 285 | , 2.0 286 | *. 3.141592653589793238462643 287 | ) 288 | (now ()) 289 | 290 | 291 | let hann label range dur = time_bound dur (sine label range (dur *. 2.)) 292 | 293 | let iterate init f = 294 | let s = ref init in 295 | fun () -> 296 | let x = !s in 297 | s := f x ; 298 | x 299 | 300 | 301 | let some_or_none x = Rnd.one_of [ Some x; None ] 302 | 303 | let rec rem' x n = if x < 0 then rem' (x + n) n else x mod n 304 | 305 | let mod_walk ~modulo init step = 306 | iterate init (fun x -> rem' (x + step ()) (modulo ())) 307 | 308 | 309 | let walk init step = iterate init (fun x -> x + step ()) 310 | 311 | let walk_float init step = iterate init (fun x -> x +. step ()) 312 | 313 | let zip a b () = (a (), b ()) 314 | 315 | let zip3 a b c () = (a (), b (), c ()) 316 | 317 | let zip4 a b c d () = (a (), b (), c (), d ()) 318 | 319 | let zip5 a b c d e () = (a (), b (), c (), d (), e ()) 320 | 321 | let zip6 a b c d e f () = (a (), b (), c (), d (), e (), f ()) 322 | 323 | let zip7 a b c d e f g () = (a (), b (), c (), d (), e (), f (), g ()) 324 | 325 | let zip8 a b c d e f g h () = (a (), b (), c (), d (), e (), f (), g (), h ()) 326 | 327 | let zip9 a b c d e f g h i () = 328 | (a (), b (), c (), d (), e (), f (), g (), h (), i ()) 329 | 330 | 331 | let zip10 a b c d e f g h i j () = 332 | (a (), b (), c (), d (), e (), f (), g (), h (), i (), j ()) 333 | 334 | 335 | let ( +~ ) = zip_with ( + ) 336 | 337 | let ( *~ ) = zip_with ( * ) 338 | 339 | let ( /~ ) = zip_with ( / ) 340 | 341 | let ( -~ ) = zip_with ( - ) 342 | 343 | let ( +.~ ) = zip_with ( +. ) 344 | 345 | let ( *.~ ) = zip_with ( *. ) 346 | 347 | let ( -.~ ) = zip_with ( -. ) 348 | 349 | let ( /.~ ) = zip_with ( /. ) 350 | 351 | let ( ||~ ) (a : unit -> 'a) (b : unit -> 'a) : unit -> 'a = 352 | let x = Rnd.one_of [ a; b ] in 353 | fun () -> x () () 354 | 355 | 356 | module Infix = struct 357 | let ( >|= ) x f = map f x 358 | 359 | let ( >>= ) x f = bind f x 360 | end 361 | 362 | let ( ! ) = repeat 363 | end 364 | -------------------------------------------------------------------------------- /sonologico/helper.ml: -------------------------------------------------------------------------------- 1 | open! Containers 2 | 3 | let addr = Unix.ADDR_INET (Unix.inet_addr_of_string "127.0.0.1", 4997) 4 | 5 | module Lib (M : Mllvin_intf.S) = struct 6 | open M 7 | include Gen.Gen (M) 8 | include Rnd 9 | 10 | let fd = Unix.socket Unix.PF_INET Unix.SOCK_DGRAM 0 11 | 12 | let scatterp period ~dens ~pos f = 13 | let nr_grains = Float.(round (dens * period)) in 14 | let avg_sep = period /. nr_grains in 15 | let events = 16 | Array.init (Float.to_int nr_grains) (fun i -> 17 | let sync_pos = Float.of_int i *. avg_sep in 18 | let pos_factor = 19 | Gamag.Range_map.lin ~src:(0., 1.) ~dst:(0., avg_sep) (pos ()) 20 | in 21 | let pos_t = Float.max 0. (sync_pos +. pos_factor) in 22 | f pos_t) 23 | in 24 | let str = 25 | "$" 26 | ^ Array.to_string 27 | ~sep:"\n" 28 | (fun x -> "i" ^ Array.to_string ~sep:" " string_of_float x) 29 | events 30 | ^ "\n" 31 | in 32 | Unix.sendto_substring fd str 0 (String.length str) [] addr |> ignore 33 | 34 | 35 | let now = now 36 | 37 | let wait x = Unix.sleepf x 38 | 39 | let wait_until x = wait (x -. now ()) 40 | 41 | let disable = true 42 | 43 | let l1 = "_:l1" %: Dyn.Conv.proc 44 | 45 | let l2 = "_:l2" %: Dyn.Conv.proc 46 | 47 | let l3 = "_:l3" %: Dyn.Conv.proc 48 | 49 | let l4 = "_:l4" %: Dyn.Conv.proc 50 | 51 | let l5 = "_:l5" %: Dyn.Conv.proc 52 | 53 | let l6 = "_:l6" %: Dyn.Conv.proc 54 | 55 | let l7 = "_:l7" %: Dyn.Conv.proc 56 | 57 | let l8 = "_:l8" %: Dyn.Conv.proc 58 | 59 | let root = "root" %: Dyn.Conv.float 60 | 61 | let scatterg 62 | ?env 63 | ?distort 64 | ?filter 65 | ?modfreq 66 | ?(dens = 1.0) 67 | ?(pos = ~>0.0) 68 | ?(dur = ~>0.5) 69 | ?(rate = ~>1.0) 70 | ?(phase = float 0.0 1.0) 71 | ?(amp = ~>0.1) 72 | ?(pan = float 0.0 1.0) 73 | period 74 | () = 75 | scatterp period ~dens ~pos (fun pos -> 76 | let distort, pre, post, negative, positive, d2factor = 77 | match distort with 78 | | None -> 79 | (0.0, 0.0, 0.0, 0.0, 0.0, 0.0) 80 | | Some f -> 81 | let d2factor = f () in 82 | (1.0, 4., 0.9, 1.0, 1.8, d2factor) 83 | in 84 | let filter, freq, bwr = 85 | match filter with 86 | | None -> 87 | (0.0, 0.0, 0.0) 88 | | Some f -> 89 | let freq, bwr = f () in 90 | (1.0, freq, bwr) 91 | in 92 | let env, att = 93 | match env with None -> (0.0, 0.0) | Some f -> (1.0, f ()) 94 | in 95 | let imod, modfreq = 96 | match modfreq with None -> (0.0, 0.0) | Some f -> (1.0, f ()) 97 | in 98 | [| 1.0 99 | ; pos 100 | ; Float.max 0.0 (dur ()) 101 | ; 10. 102 | ; rate () (* rate *) 103 | ; phase () (* phase *) 104 | ; amp () (* amp *) 105 | ; env (* env *) 106 | ; att (* env.perc.att *) 107 | ; distort (* distort *) 108 | ; pre (* pregain *) 109 | ; post (* postgain *) 110 | ; negative (* negative *) 111 | ; positive (* positive *) 112 | ; filter (* filter *) 113 | ; freq (* freq *) 114 | ; bwr (* bwr *) 115 | ; pan () (* pan *) 116 | ; imod 117 | ; modfreq 118 | ; d2factor 119 | |]) 120 | 121 | 122 | let of_scale oct scale () = (Rnd.one_of scale (), oct ()) 123 | 124 | let harmonics ?(detune = fun () -> 1.0) root p () = 125 | float_of_int (Rnd.geometric p ()) *. root () *. detune () 126 | 127 | 128 | let n1 = "n1" 129 | 130 | let n2 = "n2" 131 | 132 | let n3 = "n3" 133 | 134 | let n4 = "n4" 135 | 136 | let n5 = "n5" 137 | 138 | let n6 = "n6" 139 | 140 | let n7 = "n7" 141 | 142 | let n8 = "n8" 143 | 144 | let repeat_in period ?(init = "") ?(disable = false) ref f = 145 | if disable 146 | then ref <-- fun () -> () 147 | else ( 148 | ( ref 149 | <-- fun () -> 150 | let next = now () +. period in 151 | f () ; 152 | wait_until next ; 153 | !!ref () ) ; 154 | if not (String.equal init "") then unique init !!ref () ) 155 | end 156 | -------------------------------------------------------------------------------- /sonologico/m10.ml: -------------------------------------------------------------------------------- 1 | (* sonologico - 2020-05 *) 2 | open Mllvin_intf 3 | open! Containers 4 | 5 | ;; 6 | run 7 | @@ fun (module M : S) -> 8 | let open! M in 9 | let open! Helper.Lib (M) in 10 | 11 | let _ = 12 | node n1 @@ fun () -> 13 | let period = 1. in 14 | scatterg period 15 | ~dens:8. 16 | ~pos:(gaussian 0.6 0.4) 17 | ~dur:(gaussian 1.1 0.2) 18 | ~rate:(sine "r" (0.01, 4.0) 40. *.~ one_of [0.9; 1.2; 2.; 3.; 4.]) 19 | ~amp:(sine "a" (0.1, 0.6) 57.) 20 | ~modfreq:(float 20. 778. *.~ one_of [1.;2.; 4.1; 0.7; 0.5; 0.3; 0.28; 1.3]) 21 | ~distort:(float 2.0 3.0) 22 | |> repeat_in period l1 ~disable ~init:"l1" 23 | in 24 | 25 | let _ = 26 | node n2 @@ fun () -> 27 | let period = 1. in 28 | scatterg period 29 | ~dens:16. 30 | ~dur:(gaussian 3. 0.1) 31 | ~pos:(float 0. 1.) 32 | ~rate:(sine "q" (0.01, 0.3) 47.) 33 | ~amp:(sine "p" (0.1, 0.03) 43.) 34 | ~filter:(map (fun x -> x , 0.7) (harmonics ~detune:(float 0.7 1.2) !90. 0.7)) 35 | ~modfreq:(float 21. 121.) 36 | ~distort:(gaussian 1.7 0.2) 37 | |> repeat_in period l1 ~init:"l1" ~disable 38 | in 39 | let _ = 40 | node n3 @@ fun () -> 41 | let period = 1. in 42 | scatterg period 43 | ~dens:8. 44 | ~pos:(gaussian 0.6 0.3) 45 | ~dur:(gaussian 1.2 0.2) 46 | ~rate:(sine "r" (0.01, 5.7) 17. *.~ one_of [1.; 1.; 2.; 3.; 4.]) 47 | ~amp:(sine "a" (0.1, 0.4) 57.) 48 | ~modfreq:(float 7770. 10000.) 49 | ~filter:(map (fun x -> x , 0.7) (harmonics ~detune:(float 0.9 1.4) !120. 0.7)) 50 | ~distort:(linex "l" (0.01, 2.5) 150.) 51 | |> repeat_in period l1 ~disable ~init:"l1" 52 | in 53 | 54 | 55 | () 56 | -------------------------------------------------------------------------------- /t.mo/10-min-session-in-mercury.txt: -------------------------------------------------------------------------------- 1 | 2 | set tempo 118 3 | set scale minor_harmonic c 4 | 5 | ring pos sineFloat(200 1 0 0.5) 6 | 7 | new sample bowl_hi time(1/24) speed(0.5) gain(0) name(bwl) 8 | set bwl fx(double) fx(reverb 0.9 16) shape(1 80) 9 | set bwl offset(pos) pan(random) 10 | 11 | ring bssLine fill(0 20 3 20) 12 | 13 | new synth saw note(bssLine 0) shape() name(scp_lo) 14 | set scp_lo fx(filter low 1/2 1900 100 0.4 0.5 0.1) wave2(saw 0.99832) 15 | set scp_lo fx(double) fx(reverb 2 17) gain(0) 16 | 17 | set notes sine(50 11.2 0 24) 18 | set len sine(90 1 20 80) 19 | set notes clone(notes 0 0 3 5) 20 | 21 | new synth saw note(notes 2) shape(1 len) name(arp) 22 | set arp time(1/24) gain(0.8) pan(random) fx(filter low 3 200 900 0.3) 23 | set arp fx9delay 1/16 3/12 0.7) 24 | --------------------------------------------------------------------------------