8 | ## 'The CodeKlavier: Appropriating the piano as a live coding instrument'
9 | **Authors:** Felipe Ignacio Noriega, Anne Veinberg
10 | **Publication:** Chapter 17 in book 'Re-thinking The Musical Instrument'edited by Mine Doganton-Dack
11 | [link](https://www.cambridgescholars.com/product/978-1-5275-7789-3)
12 |
13 |
14 | ## The sound of lambda
15 | **Authors:** Felipe Ignacio Noriega, Anne Veinberg
16 | **Publication:** FARM 2019: Proceedings of the 7th ACM SIGPLAN International Workshop on Functional Art, Music, Modeling, and DesignAugust 2019 Pages 56–60
17 | [link](https://dl.acm.org/doi/abs/10.1145/3331543.3342583) \
18 | [Paper download](https://drive.google.com/file/d/1lEfXXN59y1iKI3wrd--RE0UZrG3-yzk4/view?usp=sharing)
19 |
20 |
21 | ## Coding with the piano: The first phase of the CodeKlavier's development
22 | **Authors:** Anne Veinberg, Felipe Ignacio Noriega
23 | **Publication:** International Computer Music Conference 2018
24 | [link](https://drive.google.com/file/d/1UIr2JyPqRw833OIkBgDrx2P6VjZcEKf1/view)
25 |
26 |
27 | ## Scheduled visual contact as a strategy for improved communication in a live coder and piano ensemble
28 | **Authors:** Anne Veinberg, Felipe Ignacio Noriega
29 | **Publication:** International Conference on Live Coding 2016
30 | [link](https://www.keyboardsunite.com/offzz/ICLC-paperrevised.pdf)
31 |
--------------------------------------------------------------------------------
/CodeKlavier/CK_display.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | class CK_display(object):
4 | """
5 | Class to handle display functionality
6 | """
7 |
8 | def __init__(self, num_displays):
9 | """
10 | initialize the number of display's and the corresponding UDP ports
11 | """
12 | self._display1 = 1111
13 | self._display2 = 2222
14 | self._display3 = 3333
15 | self._display4 = 4444
16 | self._display5 = 5555
17 |
18 | def formatAndSend(self, msg='', encoding='utf-8', host='localhost', display=1, syntax_color='', spacing=True):
19 | """format and prepare a string for sending it over UDP socket
20 |
21 | :param str msg: the string to be sent
22 | :param str encoding: the character encoding
23 | :param str host: the UDP server hostname
24 | :param int display: the UDP destination port
25 | :param str syntax_color: the tag to use for syntax coloring (loop, primitive, mid, low, hi, snippet)
26 | :param boolean spacing: wheather to put a \n (new line) before the msg
27 | """
28 |
29 | if display == 1:
30 | port = 1111
31 | elif display == 2:
32 | port = 2222
33 | elif display == 3:
34 | port = 3333
35 | elif display == 4:
36 | port = 4444
37 | elif display == 5:
38 | port = 5555
39 |
40 | if spacing:
41 | newline = '\n'
42 | else:
43 | newline = ''
44 |
45 | return self.__socket.sendto(bytes(syntax_color+newline+msg, encoding), (host, port))
--------------------------------------------------------------------------------
/hybrid/README.md:
--------------------------------------------------------------------------------
1 | # Hybrid Prototype
2 | The hybrid prototype allows for easy transition from the "hello world" prototype to the Motippets prototype without stopping any of the running code. Check the README.md in the HelloWorld and Motippets directory for more information about what these prototypes can do.
3 |
4 | The hybrid prototype comes with a 5 column display for the printed text, the first of which is for "hello world" and 2-5 are for Motippets.
5 |
6 | Column 1 - "hello world"
7 | Column 2 - Mot. Snippet 1
8 | Column 3 - Mot. Snippet 2
9 | Column 4 - Mot. Conditionals text
10 | Column 5 - Mot. Conditionals running loops
11 |
12 |
13 | ## Run
14 | Make sure you in the right directory and have installed SuperCollider and the required libraries as mentioned in the general [Read Me document](https://github.com/narcode/codeklavier-python/blob/master/README.md)
15 |
16 | To run hybrid codeklavier: ``python3 codeklavier.py -p hybrid``
17 | To run display: Make sure you are in the Codeklavier folder of the codeklavier directory and then use ``python3 CK_socket.py -d5``
18 |
19 | ## Using the hybrid
20 | Switching between the two prototypes is done by pressing the top Bb on the piano. All sound processes and the ongoing conditionals will continue running so the change will only impact the input mode for the piano.
21 |
22 | Be sure to evaluate the SuperCollider files that correspond with your desired code output extension
23 |
24 | ## Videos
25 |
26 | The hybrid is artisticly currently still under development but to get a taste of the visual display, you can watch a video from our concert at [In-Sonora Festival in Madrid in March 2018.] (https://youtu.be/F5O_WUdtOqY?t=1h31m1s)
27 |
--------------------------------------------------------------------------------
/instructions.md:
--------------------------------------------------------------------------------
1 | ## Instructions to boot
2 |
3 | 1. In folder codeklavier-extras/websocket-server
4 | python3 server.py --local —-reset (only use local if running both CKAR app AND CK from the same laptop)
5 | 2. In codeklavier folder: python3 codeklavier -p ckalculator
6 | 3. Open app CodeklaviAR (if using two laptops, make sure the app is configured to send to the local ip of SC computer. You can find this via the system pref or by under the inet under en0
7 | 4. In folder codeklavier-supercollider/ck_ar: osc_defs.sc (evaluate everything)
8 |
9 |
10 | ## How to use:
11 | To make an axiom, the values must be within brackets and without a rule)
12 | For example:
13 | (2 1 2)
14 |
15 | To make a rule put the values of what you want changed, followed by the '.' and what it should become.
16 | For example:
17 | (2.1 0 1)
18 |
19 | You can also make 'no numbers' by in brackets making a comparison and adding a value to the True/False value.
20 | For example:
21 | (5 > 4 [eval] + 3) essentialy this becomes (True + 3)
22 | This translates to the 'N' token which removes the symbol
23 |
24 | For tree operatons, the commands are as follows. Besides the dot, the other dunctions are only accesible in the context of a function (ostinato) figure. Please note the ostinato should have a change of 2 semitones.
25 | dot: lowest A
26 | create tree: C
27 | drop tree: D, but short (make number first include evaluate!)
28 | collect tree: D but long (make number first include evaluate!)
29 | next: F, but short
30 | previous: F, but now tenuto
31 | Eventually these operations will only exist in the context of defining a new function (with ostinato and a note change of 2 semitones). More to follow
32 | transform: G
33 | Change shape: A
34 |
--------------------------------------------------------------------------------
/ml_data/deprecated tests/deltatime_dif_test_18-11-14.csv:
--------------------------------------------------------------------------------
1 | source_id,midi_note,velocity,deltatime,ck_deltatime,dif_deltatime
2 | 144, 60, 67,0.040772787000000005,12.639370326,0
3 | 128, 60, 127,0.04003023,12.679400556,0.04003022999999928
4 | 144, 62, 71,0.007736420000000001,13.606021880999998,0.9266213249999993
5 | 128, 62, 127,0.041713816,13.647735696999998,0.04171381599999968
6 | 144, 60, 75,0.00246109,14.600684185999999,0.9529484890000006
7 | 128, 60, 71,0.09435752800000001,14.695041713999998,0.09435752799999975
8 | 144, 62, 80,0.032358513000000005,15.630542794,0.9355010800000017
9 | 128, 62, 127,0.039575821000000004,15.670118615,0.03957582099999968
10 | 144, 60, 71,0.01897799,16.616933151999998,0.9468145369999981
11 | 128, 60, 97,0.047251323000000005,16.664184475,0.04725132300000112
12 | 144, 62, 80,0.033338385000000005,17.631192066000004,0.9670075910000051
13 | 128, 62, 65,0.07463865900000001,17.705830725000006,0.07463865900000144
14 | 144, 60, 75,0.027929962000000003,18.625795789000005,0.9199650639999994
15 | 128, 60, 96,0.048192048,18.673987837000006,0.048192048000000653
16 | 144, 62, 81,0.030882379,19.628544770000005,0.9545569329999992
17 | 128, 62, 60,0.08248707000000001,19.711031840000004,0.08248706999999911
18 | 144, 60, 68,0.011184694,20.608667216,0.8976353759999967
19 | 128, 60, 68,0.07459940100000001,20.683266617,0.0745994010000004
20 | 144, 62, 77,0.19082806700000002,21.588194037,0.9049274199999999
21 | 128, 62, 96,0.039538949000000004,21.637016906000003,0.0488228690000021
22 | 144, 60, 63,0.16493887000000002,22.562226730000003,0.9252098239999995
23 | 128, 60, 89,0.015405930000000002,22.612719642000002,0.05049291199999928
24 | 144, 62, 70,0.06501968000000001,23.662150549,1.0494309069999979
25 | 128, 62, 103,0.045155985,23.707306534,0.04515598500000095
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 |
27 | # PyInstaller
28 | # Usually these files are written by a python script from a template
29 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
30 | *.manifest
31 | *.spec
32 |
33 | # Installer logs
34 | pip-log.txt
35 | pip-delete-this-directory.txt
36 |
37 | # Unit test / coverage reports
38 | htmlcov/
39 | .tox/
40 | .coverage
41 | .coverage.*
42 | .cache
43 | nosetests.xml
44 | coverage.xml
45 | *.cover
46 | .hypothesis/
47 |
48 | # Translations
49 | *.mo
50 | *.pot
51 |
52 | # Django stuff:
53 | *.log
54 | local_settings.py
55 |
56 | # Flask stuff:
57 | instance/
58 | .webassets-cache
59 |
60 | # Scrapy stuff:
61 | .scrapy
62 |
63 | # Sphinx documentation
64 | docs/_build/
65 |
66 | # PyBuilder
67 | target/
68 |
69 | # Jupyter Notebook
70 | .ipynb_checkpoints
71 |
72 | # pyenv
73 | .python-version
74 |
75 | error sending
76 | # celery beat schedule file
77 | celerybeat-schedule
78 |
79 | # SageMath parsed files
80 | *.sage.py
81 |
82 | # Environments
83 | .env
84 | .venv
85 | env/
86 | venv/
87 | ENV/
88 | bin/
89 |
90 | # Spyder project settings
91 | .spyderproject
92 | .spyproject
93 |
94 | # Rope project settings
95 | .ropeproject
96 |
97 | # mkdocs documentation
98 | /site
99 |
100 | # mypy
101 | .mypy_cache/
102 |
103 | # EXTRA
104 | .DS_Store
105 |
106 | #Allow html buld
107 | !doc/build
108 |
109 | # CK user files
110 | ck_functions.ini
111 |
--------------------------------------------------------------------------------
/CodeKlavier/midi_delegate.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | """midi_delegate.py
3 |
4 | This file opens a delegate between nodejs and python's CodeKlavier.
5 | Used for the installation at NKK 2017
6 | """
7 |
8 | #TODO: use CodeKlavier module
9 |
10 | import time
11 | from pynput.keyboard import Key, Controller
12 | from CK_Setup import Setup
13 |
14 | def run(codeK):
15 | """Run the CodeKlavier
16 |
17 | :param CodeKlavier.Setup.setup codeK: the setup file
18 | """
19 | print("CodeKlavier is ON. Press Control-C to exit.")
20 | try:
21 | timer = time.time()
22 | keyboard = Controller()
23 | while True:
24 | msg = codeK.get_message()
25 |
26 | if msg:
27 | message, deltatime = msg
28 | # this filters the 'enter' delegate:
29 | if message[1] == 64 and message[2] == 1:
30 | print('deltatime: ', deltatime, 'msg: ', message)
31 | print('enter sent!')
32 | keyboard.press(Key.enter)
33 | keyboard.release(Key.enter)
34 | time.sleep(2)
35 |
36 | #this sends the break delegate
37 | if message[1] == 64 and message[2] == 2:
38 | break
39 |
40 | time.sleep(0.01)
41 |
42 | except KeyboardInterrupt:
43 | print('')
44 | finally:
45 | print("MIDI delegate auto-destruct")
46 | codeK.end()
47 |
48 | def main():
49 | """Main function as example.
50 | """
51 |
52 | codeK = Setup()
53 |
54 | # Start the CodeKlavier
55 | codeK = Setup()
56 | myPort = codeK.perform_setup()
57 | codeK.open_port(myPort)
58 | device_id = codeK.get_device_id()
59 | print('your device id is: ', device_id, '\n')
60 | run(codeK)
61 |
62 | if __name__ == "__main__":
63 | main()
64 |
--------------------------------------------------------------------------------
/motippets/default_setup.ini:
--------------------------------------------------------------------------------
1 | [midi]
2 | port: 2
3 | device_id: 144
4 | noteoff_id: 0
5 |
6 | [snippets]
7 | snippet1 : ~snippet1 = Tdef(\1, {|ev| loop{ Ndef(~name.next,{|pitch=420,fx=88| SinOsc.ar(456*LFTri.kr(fx).range(100, pitch)) * EnvGen.kr(Env.perc) * ev.amp}).play(0,2);(1/ev.rit).wait;}}).play(~ts, quant:0).envir = (rit: ~tremoloL, amp: 0.036);
8 |
9 | mini_snippet_hi_1: [\pulse, \pulse2, \pulse3, \pulse4, \pulse5, \pulse6].do{|i| Ndef(i).map(\fx, Ndef(\krm3));}; ~tremoloH1;
10 | mini_unmap_hi_2: Ndef(\acc).set(\fx, ~tremoloH2.linlin(1, 16, 0, 15));
11 |
12 | mini_snippet_mid_1: [\pulse, \pulse2, \pulse3, \pulse4, \pulse5, \pulse6].do{|i| Ndef(i).map(\pitch, Ndef(\krm1));}; ~tremoloM1;
13 | mini_unmap_mid_2: Ndef(\acc).set(\note, ~tremoloM2.linlin(1, 16, 180, 800));
14 |
15 | mini_snippet_low_1: ~map_rhythm = true; ~tremoloL1;
16 | mini_unmap_low_1: ~map_rhythm = false;
17 | mini_unmap_low_2: Ndef(\acc).set(\amp, ~tremoloL2.linlin(1, 16, 0, 1.5))
18 | mini_unmap_low_3: ~map_amplitude = false;
19 | mini_snippet_low_1_amp: ~map_amplitude = true; ~tremoloL1amp;
20 |
21 | snippet2 : ~snippet2 = Ndef(\acc, {|note=500, amp=0.036, cut=200, bw=0.5, fx=0.1| BPF.ar(Resonz.ar(SinOsc.ar([note.lag(1), note.lag(2)*3/2, note*2, note.lag(1.5)*4/3]), (note*LFTri.kr(fx).range(1/2, 8))+80, bw), 600, 0.8) * amp.lag(0.5)}).play(0,2);
22 |
23 | mini_snippet_hi_2: Ndef(\acc).map(\fx, Ndef(\krm2_3)); ~tremoloH2;
24 | mini_unmap_hi_1: [\pulse, \pulse2, \pulse3, \pulse4, \pulse5, \pulse6].do{|i| Ndef(i).set(\fx, ~tremoloH1.linlin(1, 16, 1, 88));}
25 |
26 | mini_snippet_mid_2: Ndef(\acc).map(\note, Ndef(\krm2_1)); ~tremoloM2;
27 | mini_snippet_mid_2b: Ndef(\acc).map(\note, Ndef(\krm2_1)); ~tremoloH2;
28 | mini_unmap_mid_1: [\pulse, \pulse2, \pulse3, \pulse4, \pulse5, \pulse6].do{|i| Ndef(i).set(\pitch, ~tremoloM1.linlin(1, 16, 200, 3000));};
29 |
30 | mini_snippet_low_2: Ndef(\acc).map(\amp, Ndef(\krm2_2)); ~tremoloL2
31 |
--------------------------------------------------------------------------------
/motippets/README.md:
--------------------------------------------------------------------------------
1 | # Motippets
2 |
3 | The Motippets prototype is able to parse selected melodic/harmonic motifs and map these to music making code snippets. Once a snippet is present, up to three of its variables can be manipulated through a tremolo recognition function. This function calculates the interval of the tremolo in real-time and sets this value to the associated variable. The keyboard is divided into three distinct ranges and we use mini-motifs to direct the system as to which variable is being manipulated at any given moment.This setup enables the pianist to code and manipulate snippets in parallel- a feature made possible by the use of the piano keyboard as a coding interface.
4 |
5 | Furthermore, in Motippets the performer is able to set up both ongoing and momentary conditionals. These conditionals test aspects of the pianist’s playing such as the number of notes played over a particular time period or the range within which the pianist IS or IS NOT playing. If a test is passed, an event occurs. All of the values and outcomes of these conditionals are set up by the pianist during the performance.
6 |
7 | The performer is relatively free to play anything on the piano but must ensure that the coding motifs are integrated into the performance. The structure is not set and should be reactionary to the interaction of the coded algorithms.You can watch a video of one version of Motippets [here](https://youtu.be/nzsW1w38JEc)
8 |
9 |
10 | ## Run
11 | Make sure you have installed supercollider and the required libraries before you
12 | start motippets. Then run: ``python3 codeklavier.py -p hybrid`` <--- be sure to avoid the top Bb! You can also run ``python3 codeklavier.py -p motippets`` but this version may not stay as upto date as the hybrid.
13 |
14 |
15 | ## Customise
16 | This prototype is musically customisable by adjusting the motifs used to trigger the snippets in the motifs class and/or adjusting the printed snippets in the default.ini
17 |
--------------------------------------------------------------------------------
/doc/source/CodeKlavier.rst:
--------------------------------------------------------------------------------
1 | CodeKlavier package
2 | ===================
3 |
4 | CodeKlavier\.CK_Setup module
5 | ----------------------------
6 |
7 | .. automodule:: CodeKlavier.CK_Setup
8 | :members:
9 | :undoc-members:
10 | :show-inheritance:
11 |
12 | CodeKlavier\.CK_configWriter module
13 | -----------------------------------
14 |
15 | .. automodule:: CodeKlavier.CK_configWriter
16 | :members:
17 | :undoc-members:
18 | :show-inheritance:
19 |
20 | CodeKlavier\.Instructions module
21 | --------------------------------
22 |
23 | .. automodule:: CodeKlavier.Instructions
24 | :members:
25 | :undoc-members:
26 | :show-inheritance:
27 |
28 | CodeKlavier\.Mapping module
29 | ---------------------------
30 | .. We specifify the separate classes and not use automodule to include the __init__ method
31 |
32 | .. autoclass:: CodeKlavier.Mapping.Mapping_HelloWorld
33 | :members:
34 | :undoc-members:
35 |
36 | .. automethod:: __init__
37 |
38 | .. autoclass:: CodeKlavier.Mapping.Mapping_HelloWorld_NKK
39 | :members:
40 | :undoc-members:
41 |
42 | .. automethod:: __init__
43 |
44 | .. autoclass:: CodeKlavier.Mapping.Mapping_Motippets
45 | :members:
46 | :undoc-members:
47 |
48 | .. automethod:: __init__
49 |
50 | CodeKlavier\.Motifs module
51 | --------------------------
52 |
53 | .. automodule:: CodeKlavier.Motifs
54 | :members:
55 | :undoc-members:
56 | :show-inheritance:
57 |
58 | CodeKlavier\.hello\_classes module
59 | ----------------------------------
60 |
61 | .. automodule:: CodeKlavier.hello_classes
62 | :members:
63 | :undoc-members:
64 | :show-inheritance:
65 |
66 | CodeKlavier\.midi\_delegate module
67 | ----------------------------------
68 |
69 | .. automodule:: CodeKlavier.midi_delegate
70 | :members:
71 | :undoc-members:
72 | :show-inheritance:
73 |
74 | CodeKlavier\.motippets\_classes module
75 | --------------------------------------
76 |
77 | .. automodule:: CodeKlavier.motippets_classes
78 | :members:
79 | :undoc-members:
80 | :show-inheritance:
81 |
82 |
--------------------------------------------------------------------------------
/assets/papers.md.orig:
--------------------------------------------------------------------------------
1 | ---
2 | permalink: /publications
3 | ---
4 |
5 | # CodeKlavier Publications 📝
6 |
7 | <<<<<<< HEAD
8 |
9 | ### The sound of lambda
10 | Authors: Felipe Ignacio Noriega, Anne Veinberg
11 | Publication: FARM 2019: Proceedings of the 7th ACM SIGPLAN International Workshop on Functional Art, Music, Modeling, and DesignAugust 2019 Pages 56–60https://doi.org/10.1145/3331543.3342583
12 |
13 | ## Scheduled visual contact as a strategy for improved communication in a live coder and piano ensemble
14 | Authors: Anne Veinberg, Felipe Ignacio Noriega
15 | Publication: https://www.keyboardsunite.com/offzz/ICLC-paperrevised.pdf
16 |
17 | ## Coding with the piano: The first phase of the CodeKlavier's development
18 | Authors: Anne Veinberg, Felipe Ignacio Noriega
19 | Publication: https://drive.google.com/file/d/1UIr2JyPqRw833OIkBgDrx2P6VjZcEKf1/view
20 |
21 |
22 | ## In process: Writing Chapter 17 of the book ....
23 | =======
24 |
25 | ## 'The CodeKlavier: Appropriating the piano as a live coding instrument'
26 | **Authors:** Felipe Ignacio Noriega, Anne Veinberg
27 | **Publication:** In process: Chapter 17 in book 'Re-thinking The Musical Instrument'edited by Mine Doganton-Dack
28 |
29 |
30 | ## The sound of lambda
31 | **Authors:** Felipe Ignacio Noriega, Anne Veinberg
32 | **Publication:** FARM 2019: Proceedings of the 7th ACM SIGPLAN International Workshop on Functional Art, Music, Modeling, and DesignAugust 2019 Pages 56–60
33 | [link](https://doi.org/10.1145/3331543.3342583D)
34 |
35 |
36 | ## Coding with the piano: The first phase of the CodeKlavier's development
37 | **Authors:** Anne Veinberg, Felipe Ignacio Noriega
38 | **Publication:** International Computer Music Conference 2018
39 | [link](https://drive.google.com/file/d/1UIr2JyPqRw833OIkBgDrx2P6VjZcEKf1/view)
40 |
41 |
42 | ## Scheduled visual contact as a strategy for improved communication in a live coder and piano ensemble
43 | **Authors:** Anne Veinberg, Felipe Ignacio Noriega
44 | **Publication:** International Conference on Live Coding 2016
45 | [link](https://www.keyboardsunite.com/offzz/ICLC-paperrevised.pdf)
46 | >>>>>>> master
47 |
--------------------------------------------------------------------------------
/assets/videos.md:
--------------------------------------------------------------------------------
1 | ---
2 | permalink: /videos
3 | ---
4 |
5 | # CodeKlavier VIDEOS 🎥 🎹
6 |
7 |
8 | ### Introductory video by Creative Industries Fund NL:
9 |
40 |
--------------------------------------------------------------------------------
/doc/source/Documentation.rst:
--------------------------------------------------------------------------------
1 | Documentation
2 | =============
3 | Every developer likes to have documentation, but no one really likes to write it.
4 |
5 | Sphinx and rst
6 | --------------
7 | To help us with the documentation proces, CodeKlavier uses the Sphinx package that converts rst-files (that are easy to write) to html-files that are beautiful and easy to browse. On top of that: Sphinx can 'walk' over the python source code and generate the documentation out of the docstrings in the python code.
8 |
9 | Rst-files are plain text files with some basic formatting. You can underline words with === to indicate a header and you use '*' to use **boldface** and so on. There is enough material on the internet to help you with the basics.
10 |
11 | Installation
12 | ............
13 | You can use ``pip3`` to install the Sphinx-package by running::
14 |
15 | pip3 install sphinx
16 |
17 | Use pip3 because CodeKlavier uses python **3** and not python 2.
18 |
19 | .. NOTE::
20 | If you used the ``requirements.txt`` file to install CodeKlavier, you have already installed Sphinx.
21 |
22 | Setup
23 | .....
24 | The ``doc`` folder was created to put everything that deals with documentation. From that directory we made the setup by running ``sphynx-quickstart`` and answering the questions that pop up. This creates the ``source`` and ``build`` directories and provides you with a ``Makefile`` file. Some small tweaks to the ``source/conf.py`` were made to finalise the installation.
25 |
26 | Sphinx can autogenerate some documentation based on the docstrings from the python code. Make sure you enable the "autodoc" module in the ``conf.py`` file and the you insert the correct "path". With the command: ``sphinx-apidoc -o module-path`` you can include an entire package/module in one go and it generates and ``.rst`` file that you can include in the ``modules.rst`` file.
27 |
28 | How to write documentation
29 | --------------------------
30 | Change existing rst-files, or create additional files in case you want to create a new page.
31 |
32 | For documeting the python code: please add appropiate docstring in the code itself.
33 |
34 | How to build the documentation
35 | ------------------------------
36 | Most likely, you'll want to build towards html-code. You can make a build by running ``make html`` from the ``doc`` folder. This will run sphinx in html-mode and save an updated version of the html in the ``doc/build`` directory.
37 |
--------------------------------------------------------------------------------
/ml_data/deprecated tests/test 4 (12 notes)_18-11-16.csv:
--------------------------------------------------------------------------------
1 | source_id0,midi_note0,velocity0,ck_deltatime0,dif_deltatime0,source_id1,midi_note1,velocity1,ck_deltatime1,dif_deltatime1,source_id2,midi_note2,velocity2,ck_deltatime2,dif_deltatime2,source_id3,midi_note3,velocity3,ck_deltatime3,dif_deltatime3,source_id4,midi_note4,velocity4,ck_deltatime4,dif_deltatime4,source_id5,midi_note5,velocity5,ck_deltatime5,dif_deltatime5,source_id6,midi_note6,velocity6,ck_deltatime6,dif_deltatime6,source_id7,midi_note7,velocity7,ck_deltatime7,dif_deltatime7,source_id8,midi_note8,velocity8,ck_deltatime8,dif_deltatime8,source_id9,midi_note9,velocity9,ck_deltatime9,dif_deltatime9,
2 | 144,60,68,2.310651642,0,144,68,78,2.492941015,0,128,60,62,2.499559765,0.0066187500000000005,144,61,69,2.678454489,0,128,68,65,2.683004715,0.004550226,128,61,73,2.8377936989999997,0.15478898400000002,144,60,63,2.8664984049999997,0,128,60,72,3.0225254059999997,0.156027001,144,68,78,3.0248349209999996,0,144,61,70,3.1958517509999997,0,
3 | 144,60,68,3.389230235,0,144,68,75,3.554421435,0,128,60,67,3.571806377,0.017384942,144,61,74,3.743210335,0,128,68,65,3.751710081,0.008499746,128,61,51,3.84548417,0.093774089,144,62,66,5.106427435,0,128,62,69,5.2680769949999995,0.16164956000000003,144,67,68,5.2894221109999995,0,144,66,79,5.460875688999999,0,
4 | 144,62,71,5.655568775999999,0,144,67,69,5.825010483999999,0,128,62,56,5.827182749999999,0.002172266,128,67,74,5.997253971999998,0.17007122200000002,144,66,74,6.001874876999998,0,128,66,65,6.187242124999998,0.185367248,144,62,66,6.194106615999998,0,144,67,69,6.371450649999998,0,128,62,65,6.393477649999998,0.022027,128,67,74,6.550653240999997,0.15717559100000003,
5 | 144,63,70,8.710378294999998,0,128,63,66,8.889673208999998,0.17929491400000003,144,69,54,8.915857811999999,0,128,69,84,8.980395043999998,0.064537232,144,74,59,9.083166786,0,144,63,70,9.250528574999999,0,128,74,69,9.269224763999999,0.018696189000000002,128,63,67,9.422506529,0.153281765,144,69,69,9.424731897,0,128,69,63,9.584736874999999,0.16000497800000002,
6 | 144,63,74,9.776700831,0,128,74,68,9.78777567,0.011074839000000001,128,63,68,9.955731231,0.167955561,144,69,67,9.959158887,0,128,69,52,10.139554123999998,0.180395237,144,74,76,10.141733740999998,0,128,74,73,10.252454339999998,0.110720599,144,66,71,13.205205894999999,0,128,66,61,13.383430280999999,0.178224386,144,63,70,13.385958936,0,
7 | 144,62,63,13.564004107,0,144,66,69,13.73227881,0,128,62,59,13.75268991,0.0204111,144,63,67,13.907499231000001,0,128,66,63,13.916913267000002,0.009414036,128,63,70,14.045880596000002,0.12896732900000002,144,62,58,14.081266696000002,0,144,66,65,14.250301735,0,128,62,67,14.258261521000001,0.007959786,128,66,66,14.419704117000002,0.16144259600000002,
8 |
--------------------------------------------------------------------------------
/hello_world/README.md:
--------------------------------------------------------------------------------
1 | # "hello world"
2 | A work for Robot Toy Piano and acoustic midi piano performed by a (coder) pianist.
3 |
4 | “hello world” is the first prototype of the CodeKlavier created especially to live code the actions of a Robot Toy Piano through playing an acoustic midi piano as interface. The keys are individually mapped to alphanumeric characters and strings to allow the (coder) pianist to execute various code
5 | commands through corresponding motivic material. The system is built on top of Python 3.0 and SuperCollider.
6 |
7 | In true live coding spirit, a performance of "hello world" is not subject to a concrete structure and should unfold in its own way with every performance. Feel free to watch Anne Veinberg's [performance](https://youtu.be/ytpB8FB6VTU) of "hello world" and view a [score](https://drive.google.com/file/d/0B6qSeqXuDEKQSWNnSDVOdkJyaGNIVnVhNVlhbDZZLThWSzFz/view?usp=sharing) of the piece.
8 |
9 |
10 | ## To Run
11 | Make sure you in the right directory and have installed SuperCollider and the required libraries as mentioned in the general [Read Me document](https://github.com/narcode/codeklavier-python/blob/master/README.md).
12 |
13 | For the Robot Toy Piano version, run ``python3 codeklavier.py -p hello_world_rtp``
14 |
15 | ## Versions and Extensions
16 | As an extension to the original "hello world", for [SHA2017](https://sha2017.org) a version that also incorporates sound processing was created. You can watch the presentation on [youtube](https://youtu.be/efU7trVAPvA).
17 |
18 | To run this version use ``python3 codeklavier.py -phello_world_v4.py``
19 |
20 | To make your own custom mappings, use the Mapping.py file
21 |
22 | In September 2017, a special version of "hello world" was created for the Leiden Night of Art and Science (Leiden Nacht van Kunst en Kennis (NKK)). For this version, audience members were encouraged to try-out the CodeKlavier system and see what they could live code through piano playing. The key mapping was simplified so that non-pianists were also able to have a go and a Python tutorial was created to assist the participant. With the help of the tutorial, this version can theoretically run as an installation without further assistance, although some participants may find this too challenging or require more time to navigate through the system.
23 |
24 | A unique feature of the NKK version is that it utilized the tremolo as value function of the [Motippets](https://github.com/narcode/codeklavier/tree/master/mottipets) prototype. In the future, the concept behind this version will form the basis of the CodeKlavierEDU model - an educational CodeKlavier system. If you would like to know more about this version or the future CodeKlavierEDU model, please get in touch.
25 |
26 |
--------------------------------------------------------------------------------
/ml_data/deprecated tests/test 5 (12 notes, last 6 were staccato)_18-11-16.csv:
--------------------------------------------------------------------------------
1 | source_id0,midi_note0,velocity0,ck_deltatime0,dif_deltatime0,source_id1,midi_note1,velocity1,ck_deltatime1,dif_deltatime1,source_id2,midi_note2,velocity2,ck_deltatime2,dif_deltatime2,source_id3,midi_note3,velocity3,ck_deltatime3,dif_deltatime3,source_id4,midi_note4,velocity4,ck_deltatime4,dif_deltatime4,source_id5,midi_note5,velocity5,ck_deltatime5,dif_deltatime5,source_id6,midi_note6,velocity6,ck_deltatime6,dif_deltatime6,source_id7,midi_note7,velocity7,ck_deltatime7,dif_deltatime7,source_id8,midi_note8,velocity8,ck_deltatime8,dif_deltatime8,source_id9,midi_note9,velocity9,ck_deltatime9,dif_deltatime9,
2 | 144,62,71,0.830888285,0,128,62,73,0.983216749,0.152328464,144,60,63,1.0058213980000001,0,144,70,75,1.1698147710000002,0,128,60,68,1.177410215,0.007595444000000001,128,70,64,1.339540038,0.162129823,144,62,70,1.344424176,0,128,62,75,1.5115492640000001,0.167125088,144,60,66,1.5257801780000002,0,144,70,76,1.699228745,0,
3 | 144,62,71,1.871829101,0,128,70,64,1.8754906450000002,0.003661544,128,62,76,2.0355713750000004,0.16008073,144,60,65,2.0520157750000005,0,144,70,73,2.2403966450000006,0,128,60,69,2.2576207690000007,0.017224124,128,70,62,2.3581619330000008,0.10054116399999999,144,56,70,3.2986535250000006,0,128,56,64,3.4882387610000007,0.18958523600000002,144,57,65,3.493995564000001,0,
4 | 144,58,62,3.687497435000001,0,128,58,65,3.8212941660000013,0.133796731,144,56,61,3.865815953000001,0,128,56,70,4.024997991000001,0.15918203800000003,144,57,65,4.0524285240000015,0,128,57,67,4.200644215000001,0.148215691,144,58,59,4.240979338000002,0,128,58,65,4.392191161000001,0.15121182300000002,144,56,57,4.414070681000001,0,128,56,61,4.556639979000001,0.142569298,
5 | 144,58,68,4.780600106000001,0,128,58,71,4.897160546000001,0.11656044000000002,144,60,75,5.671073000000001,0,128,60,127,5.713344865000001,0.042271865000000006,144,61,56,5.909563706000001,0,128,61,127,5.948074565000001,0.038510859,144,62,73,6.104691344000001,0,128,62,127,6.142374535000001,0.037683191000000005,144,60,75,6.316782683000001,0,128,60,127,6.351314814000001,0.034532131,
6 | 144,62,78,6.774957920000001,0,128,62,127,6.810667781000001,0.035709861,144,60,72,7.001269865000001,0,128,60,127,7.036570158000001,0.035300293,144,61,81,7.227967968000001,0,128,61,127,7.265221831000001,0.037253863000000005,144,62,81,7.442621153000001,0,128,62,127,7.482467635000001,0.039846482,144,54,63,8.474565365,0,128,54,127,8.50929929,0.034733925,
7 | 144,55,56,8.946663401,0,128,55,98,8.989913893,0.043250492,144,54,63,9.179040291,0,128,54,89,9.237031403,0.057991112000000004,144,56,63,9.403749722999999,0,128,56,121,9.446871938,0.043122215000000005,144,55,56,9.646068968,0,128,55,90,9.691646713999999,0.045577746,144,54,68,9.866748691,0,128,54,64,9.941029588,0.074280897,
8 |
--------------------------------------------------------------------------------
/doc/source/HelloWorld.rst:
--------------------------------------------------------------------------------
1 | hello world
2 | ===========
3 |
4 | Hello World is the first prototype of the CodeKlavier and it demonstrates the core principes of CodeKlavier. It uses a basic mapping from the piano (midi)keys to characters or predefined strings. These character/string translation is send to SuperCollider to generate sounds. In the original version of Hello World, it instructed a robot toy piano to play notes and motifes. When the piece is performed without the robot toy piano, the piece can also work with recorded samples.
5 |
6 | hello_world
7 | -----------
8 | Run an infinite loop (or at least until keyboard intterupt) and run CodeKlavier. This programm set the callback and pass the key presses on towards SuperCollider.
9 |
10 | .. NOTE::
11 | Make sure you have SuperCollider up and running before running the ``hello world`` application. Please reboot SuperCollider Server berfore you astart a live performance.
12 |
13 | Video tutorials
14 | ...............
15 |
16 | A video of the Hello World performance can be found `here `_. This is an early version; the piece evolved over time. A short video tutorial on the ``~ost`` function can be found `here `_ and the ``delay to pitch`` example can be found `here `_.
17 |
18 | instructions_nkk
19 | ----------------
20 | For the *Leiden Nacht van Kunst en Cultuur* a special version is made, so the visitors can also try out the CodeKlavier. To teach them how to get used to the system and how to perform, they can first run through the ``instruction`` for the CodeKlavier.
21 |
22 | hello_world_nkk
23 | ---------------
24 | This is a special version of the CodeKlaver, made specifically for the *Leiden Nacht van Kunst en Cultuur*. It uses a seperate key-mapping that can be found in ``CodeKlavier.Mapping.Mapping_HelloWorld_NKK``.
25 |
26 | Hello World python documentation
27 | --------------------------------
28 |
29 | The python scripts in the hello world folder contain documentation.
30 |
31 | Hello World
32 | ...........
33 |
34 | .. automodule:: hello_world.hello_world
35 | :members:
36 | :undoc-members:
37 | :show-inheritance:
38 |
39 | Hello World NKK
40 | ...............
41 | .. automodule:: hello_world.hello_world_nkk
42 | :members:
43 | :undoc-members:
44 | :show-inheritance:
45 |
46 | Instructions
47 | ............
48 | .. automodule:: hello_world.instructions_nkk
49 | :members:
50 | :undoc-members:
51 | :show-inheritance:
52 |
--------------------------------------------------------------------------------
/hello_world/SC/toypiano_sampler.scd:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | -> toy piano sampler by narcode. April 2017 <-
4 |
5 | Thanks to Anne Veinberg for Recording this
6 |
7 | */
8 |
9 | {
10 | // load the custom toy piano samples
11 | b = ();
12 | g = Group.new(s, \addToHead);
13 | ~pathsamples = thisProcess.nowExecutingPath.dirname;
14 | s.sync;
15 | 29.do{|i|
16 | ~num = 36 + i;
17 | b[i] = Buffer.read(s, ~pathsamples++"/TPSamples/"++~num++".wav");
18 | };
19 | s.sync;
20 |
21 | ~srcid = nil; // annerob: 1151127154 felipe 1429867122 anne -1869464304
22 |
23 | // sampler node:
24 | MIDIdef.noteOn(\toypiano, {arg ...args;
25 | var midinote = args[1]-56;
26 | // args.postln;
27 | midinote.postln;
28 | if (midinote < 64 && midinote >= 0) {
29 | Ndef(midinote.asSymbol, {PlayBuf.ar(2, b[midinote], loop:0) * EnvGen.kr(Env.perc(0.01, 1.5))}).play(6, group: g);
30 | Ndef((midinote.asString++"d0").asSymbol, {PlayBuf.ar(2, b[midinote], loop:0) * EnvGen.kr(Env.perc(0.01, 1.5))}).play(0);
31 | }
32 | }, chan: 0, srcID: ~srcid); // 1151127154
33 |
34 |
35 | // channel 1:
36 | MIDIdef.noteOn(\toypiano1, {arg ...args;
37 | var midinote = args[1]-56;
38 | /*args.postln;*/
39 | midinote.postln;
40 | if (midinote < 64 && midinote >= 0) {
41 | Ndef(midinote.asSymbol, {PlayBuf.ar(2, b[midinote], loop:0) * EnvGen.kr(Env.perc(0.01, 1.5))}).play(20, group: g);
42 | Ndef((midinote.asString++"d1").asSymbol, {PlayBuf.ar(2, b[midinote], loop:0) * EnvGen.kr(Env.perc(0.01, 1.5))}).play(0);
43 | }
44 | }, chan: 1, srcID: ~srcid); // 1151127154
45 |
46 |
47 | // channel 2:
48 | MIDIdef.noteOn(\toypiano2, {arg ...args;
49 | var midinote = args[1]-56;
50 | var duplicate = midinote.asString++"d";
51 | /*args.postln;*/
52 | midinote.postln;
53 |
54 | if (midinote < 64 && midinote >= 0) {
55 | Ndef(midinote.asSymbol, {PlayBuf.ar(2, b[midinote], loop:0) * EnvGen.kr(Env.perc(0.01, 1.5))}).play(4, group: g);
56 | Ndef(duplicate.asSymbol, {PlayBuf.ar(2, b[midinote], loop:0) * EnvGen.kr(Env.perc(0.01, 1.5))}).play(0);
57 | }
58 | }, chan: 2, srcID: ~srcid); // 1151127154
59 |
60 | // channel 3:
61 | MIDIdef.noteOn(\toypiano3, {arg ...args;
62 | var midinote = args[1]-56;
63 | /*args.postln;*/
64 | midinote.postln;
65 |
66 | if (midinote < 64 && midinote >= 0) {
67 | Ndef(midinote.asSymbol, {PlayBuf.ar(2, b[midinote], loop:0) * EnvGen.kr(Env.perc(0.01, 1.5))}).play(0);
68 | }
69 | }, chan: 3, srcID: ~srcid); // 1151127154
70 |
71 |
72 | s.sync;
73 | "Toy piano sampler ready!".postln;
74 | s.sync;
75 | // fx:
76 | ~gtail = Group.new(s, \addToTail);
77 | Ndef(\fx, {|del=1, amp=0.001| CombN.ar(SoundIn.ar(0), 0.2, del.reciprocal, 4)*amp}).play(0, group: ~gtail);
78 | s.sync;
79 | Ndef(\fx1, {|del=1, amp=0.001| CombN.ar(SoundIn.ar(0), 0.2, del.reciprocal, 1)*amp}).play(1, group: ~gtail);
80 | s.sync;
81 | Ndef(\fx2, {|del=2, amp=0.001, rate=1| GVerb.ar(FreqShift.ar(SoundIn.ar(0), LFTri.kr(rate.reciprocal).range(8000, 100)), 62, del)*amp}).play(0,2, group: ~gtail);
82 | s.sync;
83 | "fx ready!".postln;
84 | }.fork;
85 |
--------------------------------------------------------------------------------
/hello_world/hello_world.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import configparser
4 | import getopt
5 | import rtmidi
6 | import sys
7 | import time
8 |
9 | # CodeKlavier Modules
10 | import CK_configWriter
11 | from CK_Setup import Setup
12 | from hello_classes import HelloWorld
13 | from Mapping import Mapping_HelloWorld
14 |
15 | def main(configfile='default_setup.ini'):
16 | """
17 | Start hello world!
18 |
19 | :param int configfile: use this configuration file. Defaults to 'default_setup.ini'.
20 | """
21 |
22 | #Read config and settings
23 | config = configparser.ConfigParser()
24 | config.read(configfile, encoding='utf8')
25 |
26 | try:
27 | myPort = config['midi'].getint('port')
28 | device_id = config['midi'].getint('noteon_id')
29 | except KeyError:
30 | raise LookupError('Missing key information in the config file.')
31 |
32 | if (myPort == None or device_id == None):
33 | raise LookupError('Missing key information in the config file.')
34 |
35 | codeK = Setup()
36 | codeK.print_welcome(27)
37 | codeK.open_port(myPort)
38 |
39 | # Use your favourite mapping of the keys
40 | mapping = Mapping_HelloWorld()
41 |
42 | print("\nCodeKlavier is ready and ON.")
43 | print("You are performing: HELLO WORLD")
44 | print("\nPress Control-C to exit.")
45 |
46 | codeK.set_callback(HelloWorld(myPort, mapping, device_id))
47 |
48 | # Loop to program to keep listening for midi input
49 | try:
50 | while True:
51 | time.sleep(0.01)
52 | except KeyboardInterrupt:
53 | print('')
54 | finally:
55 | print("Bye-Bye :(")
56 | codeK.end()
57 |
58 | if (__name__ == '__main__'):
59 | try:
60 | options, args = getopt.getopt(sys.argv[1:],'hc:m:',['help', 'configfile=', 'makeconfig='])
61 | selected_options = [x[0] for x in options]
62 | except getopt.GetoptError:
63 | print('Something went wrong with parsing the options')
64 | if ('-c' in selected_options or '--configfile' in selected_options) \
65 | and ('-m' in selected_options or '--makeconfig' in selected_options):
66 | #cannot deal with creating a new one and using a specified config
67 | raise ValueError('Chooce either the "configfile-option" or the option to create a configfile. Not both.')
68 | for o, a in options:
69 | if o in ('-h', '--help'):
70 | print('Usage: python3 hello_world.py [OPTION]')
71 | print('')
72 | print('Where [OPTION] is:')
73 | print(' -h | --help')
74 | print(' Print this help text.')
75 | print('')
76 | print(' -c <> | --configgile <>')
77 | print(' Use configuration file <>. You can write this configuration file with the -m option')
78 | print('')
79 | print(' -m <> | --makeconfig <>')
80 | print(' Create a configfile and use it. If <> already exits, it will be over written.')
81 | sys.exit(0)
82 | if o in ('-c', '--configfile'):
83 | #use existing configfile
84 | main(configfile=a)
85 | if o in ('-m', '--makeconfig'):
86 | #create new configfile and use it
87 | CK_configWriter.createConfig(configfile=a)
88 | main(configfile=a)
89 |
90 | #no options were supplied: run hello_world with default settings
91 | main()
92 |
--------------------------------------------------------------------------------
/text/text.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import configparser
4 | import getopt
5 | import sys
6 | import time
7 |
8 | # CodeKlavier Modules
9 | import CK_configWriter
10 | from CK_Setup import Setup
11 | from text_classes import TextPrint
12 |
13 | def main(text_id=1, configfile='default_setup.ini'):
14 | """
15 | Start the Text Printer/ Typer
16 |
17 | :param string text_id: the text to load.
18 | :param string configfile: use this configuration file. Defaults to 'default_setup.ini'.
19 | """
20 |
21 | #Read config and settings
22 | config = configparser.ConfigParser()
23 | config.read(configfile, encoding='utf8')
24 |
25 | try:
26 | myPort = config['midi'].getint('port')
27 | device_id = config['midi'].getint('noteon_id')
28 | pedal_id = config['midi'].getint('pedal_id')
29 | except KeyError:
30 | raise LookupError('Missing key information in the config file.')
31 |
32 | if (myPort == None or device_id == None):
33 | raise LookupError('Missing key information in the config file.')
34 |
35 | codeK = Setup()
36 | codeK.print_welcome(27)
37 | codeK.open_port(myPort)
38 |
39 |
40 | print("\nCodeKlavier is ready and ON.")
41 | print("You are performing: Fixed Text Typer")
42 | print("\nPress Control-C to exit.")
43 |
44 | #codeK.set_callback(TextPrint(myPort, device_id, pedal_id))
45 | text = TextPrint(myPort, device_id, pedal_id, text_id)
46 |
47 | # Loop to program to keep listening for midi input
48 | try:
49 | while True:
50 | msg = codeK.get_message()
51 |
52 | if msg:
53 | text.printText(msg)
54 | time.sleep(0.01)
55 |
56 | except KeyboardInterrupt:
57 | print('')
58 | finally:
59 | print("Bye-Bye :(")
60 | codeK.end()
61 |
62 | if (__name__ == '__main__'):
63 | try:
64 | options, args = getopt.getopt(sys.argv[1:],'hc:m:',['help', 'configfile=', 'makeconfig='])
65 | selected_options = [x[0] for x in options]
66 | except getopt.GetoptError:
67 | print('Something went wrong with parsing the options')
68 | if ('-c' in selected_options or '--configfile' in selected_options) \
69 | and ('-m' in selected_options or '--makeconfig' in selected_options):
70 | #cannot deal with creating a new one and using a specified config
71 | raise ValueError('Chooce either the "configfile-option" or the option to create a configfile. Not both.')
72 | for o, a in options:
73 | if o in ('-h', '--help'):
74 | print('Usage: python3 hello_world.py [OPTION]')
75 | print('')
76 | print('Where [OPTION] is:')
77 | print(' -h | --help')
78 | print(' Print this help text.')
79 | print('')
80 | print(' -c <> | --configgile <>')
81 | print(' Use configuration file <>. You can write this configuration file with the -m option')
82 | print('')
83 | print(' -m <> | --makeconfig <>')
84 | print(' Create a configfile and use it. If <> already exits, it will be over written.')
85 | sys.exit(0)
86 | if o in ('-c', '--configfile'):
87 | #use existing configfile
88 | main(configfile=a)
89 | if o in ('-m', '--makeconfig'):
90 | #create new configfile and use it
91 | CK_configWriter.createConfig(configfile=a)
92 | main(configfile=a)
93 |
94 | main()
--------------------------------------------------------------------------------
/assets/augmentedreality.md:
--------------------------------------------------------------------------------
1 | ---
2 | permalink: /augmentedreality
3 | ---
4 | # CodeKlavier meets Augmented Reality 📱 🌱
5 |
6 | 
7 |
8 | The CodeKlavier is a system which enables a pianist to code through playing the piano as a performative experience. The CK+AR (CodeKlavier + Augmented Reality) is the next step in our artistic mission of combining classically inspired pianistic, new media, and live coding performance practises into an innovative, united genre. In the CK+AR, the piano playing becomes the interface for coding and the coding unfolds as piano playing and as a visual AR experience, making the three mediums indistinguishable from one another (AR visuals + piano playing + live programming).
9 |
10 | The coding is done in the CodeKlavier language, which implements lambda calculus to create numbers and arithmetic operations that can be translated into symbols to specify Lindenmayer systems. L-systems are formal grammars that consist of a set of symbols (alphabet), a starting point (axiom) and a set of production rules which define symbol substitution. The production rules are applied recursively to successive generations, creating a tree-like structure. These structures, together with additional information extracted from the piano playing, is then used to construct the AR visuals as well as a sonic scape.
11 |
12 | 
13 |
14 | Our inspiration for working with L-systems comes primarily from its roots in nature and organic growth which we would like to bring to the musical and programming paradigms. Whilst L-systems are already widely used in generative art and music, we are interessted in exploring how this fairly simple model can be used by the piano coder to express complex structures and how its rules will shape the pianistic improvisation. Furthermore, Lindenmayer’s work was done here at the University of Utrecht in 1968 and building upon it through artistic exploration makes the Netherlands a particularly special location for the development of this project.
15 |
16 | We are collaborating with Patrick Borgeat for this CodeKlavier extension. Patrick is creating the augmented reality and L-systems engine.
17 |
18 | ## Impression
19 | Please watch our [short trailer](https://youtu.be/p65YavCUEuQ) for an impression
20 |
21 | ## Setup
22 | The CK+AR is best presented as a combination of a live performance (15 mins), a pre or post-talk, and an interactive installation where the public can create their own L-system “trees” with assistance from us if necessary. However, this structure is flexible and may be adjusted in discussion with the creators and venue.
23 |
24 | ### There are two primary modes of presentation:
25 | CodeKlavier with the AR as visuals on a large shared screen:
26 | This requires minimal equipment and setup time where the AR visuals are projected on a large screen in the performance space. The equipment required for such a presentation is an acoustic 88 key piano, Stereo PA system (with subwoofers and monitor if available), large screen and powerful projector or large LCD screen.
27 |
28 | ### CodeKlavier with the AR as a true interactive AR experience:
29 | In this type of presentation the audience is free to move around at all times so as to experience the augmented reality visuals from different perspectives. Each audience member will be able to either download an Android app or use an Android smartphone or tablet device provided for the performance. The equipment needed for such a performance would be all of the above alongside the provision of ±30 android tablets or smartphones.
30 |
31 |
32 | We would like to thank the Creative Industries Fund NL and our other sponsors for making this project possible.
33 | www.codeklavier.space
34 |
35 |
36 |
--------------------------------------------------------------------------------
/hello_world/instructions_nkk.py:
--------------------------------------------------------------------------------
1 | """
2 | Tutorial for the Hello World NKK
3 | """
4 | import configparser
5 | import getopt
6 | import rtmidi
7 | import sys
8 | import time
9 |
10 | # CodeKlavier Modules
11 | import CK_configWriter
12 | from CK_Setup import Setup
13 | from Mapping import Mapping_HelloWorld_NKK
14 | from Instructions import Instructions
15 |
16 | def main (configfile='../default_setup.ini'):
17 | # Start the CodeKlavier
18 | #Read config and settings
19 | config = configparser.ConfigParser()
20 | config.read(configfile, encoding='utf8')
21 |
22 | try:
23 | myPort = config['midi'].getint('port')
24 | device_id = config['midi'].getint('noteon_id')
25 | except KeyError:
26 | raise LookupError('Missing key information in the config file.')
27 |
28 | if (myPort == None or device_id == None):
29 | raise LookupError('Missing key information in the config file.')
30 |
31 | codeK = Setup()
32 | tutorial = Instructions()
33 | codeK.open_port(myPort)
34 | codeK.open_port_out(myPort)
35 |
36 | # Use your favourite mapping of the keys
37 | mapping = Mapping_HelloWorld_NKK()
38 |
39 | # class to handle the midi input and map it to characters
40 | #TODO: this is ugly! Move this to the CodeKlavier module
41 | class HelloWorld(object):
42 | def __init__(self, port):
43 | self.port = port
44 |
45 | def __call__(self, event, data=None):
46 | message, deltatime = event
47 | # print(message)
48 | if message[2] > 0: #only noteOn
49 | if (message[0] == device_id):
50 | mapping.mapping(message[1])
51 |
52 | codeK.set_callback(HelloWorld(myPort))
53 |
54 | tutorial.do_tutorial()
55 | codeK.send_message([0x90, 108, 127]) #send enter to codespace
56 | tutorial.level_four()
57 |
58 | # Loop to program to keep listening for midi input
59 | try:
60 | timer = time.time()
61 | while True:
62 | time.sleep(0.01)
63 | except KeyboardInterrupt:
64 | print('')
65 | finally:
66 | # print("Bye-Bye :(")
67 | codeK.end()
68 |
69 | if (__name__ == '__main__'):
70 | try:
71 | options, args = getopt.getopt(sys.argv[1:],'hc:m:',['help', 'configfile=', 'makeconfig='])
72 | selected_options = [x[0] for x in options]
73 | except getopt.GetoptError:
74 | print('Something went wrong with parsing the options')
75 | if ('-c' in selected_options or '--configfile' in selected_options) \
76 | and ('-m' in selected_options or '--makeconfig' in selected_options):
77 | #cannot deal with creating a new one and using a specified config
78 | raise ValueError('Chooce either the "configfile-option" or the option to create a configfile. Not both.')
79 | for o, a in options:
80 | if o in ('-h', '--help'):
81 | print('Usage: python3 instructions.py [OPTION]')
82 | print('')
83 | print('Where [OPTION] is:')
84 | print(' -h | --help')
85 | print(' Print this help text.')
86 | print('')
87 | print(' -c <> | --configgile <>')
88 | print(' Use configuration file <>. You can write this configuration file with the -m option')
89 | print('')
90 | print(' -m <> | --makeconfig <>')
91 | print(' Create a configfile and use it. If <> already exits, it will be over written.')
92 | sys.exit(0)
93 | if o in ('-c', '--configfile'):
94 | #use existing configfile
95 | main(configfile=a)
96 | if o in ('-m', '--makeconfig'):
97 | #create new configfile and use it
98 | CK_configWriter.createConfig(configfile=a)
99 | main(configfile=a)
100 |
101 | #no options were supplied: instructions hello_world with default settings
102 | main()
103 |
--------------------------------------------------------------------------------
/CodeKlavier/text_classes.py:
--------------------------------------------------------------------------------
1 | """
2 | classes for the Buffered Text Typer.
3 | Done For the Huyens Festival 2018 to type poems by Constantijn Huygens
4 |
5 | """
6 | import rtmidi
7 | from Mapping import Mapping_Ckalculator
8 |
9 |
10 | class TextPrint(object):
11 | """ class to type one character of a pre-loaded text on every midi note on event
12 | """
13 |
14 | def __init__(self, port, noteonid, pedal_id, text_id):
15 | """Setup the class
16 |
17 | :param int port: the portnumber
18 | :param int dict mapping: the mapping to use
19 | :param int noteonid: the note-on id
20 | :param int text_id: the id of the text to load
21 | """
22 | self.mapscheme = Mapping_Ckalculator(True, False)
23 | self.port = port
24 | self.noteonid = noteonid
25 | self.pedalid = pedal_id
26 | self.text = text_id
27 | self.counter = 0
28 |
29 | def printText(self, event, data=None):
30 | """Deal with the call function
31 |
32 | :param event: ?
33 | :param data: ?
34 | """
35 | message, deltatime = event
36 | if message[0] != 254:
37 | if (message[0] == self.noteonid and message[2] > 0):
38 | text = self.loadText(text_id=self.text)
39 |
40 | if self.counter < len(text):
41 | print(text[self.counter])
42 | self.mapscheme.formatAndSend(text[self.counter], display=1, spacing=False, spacechar='')
43 |
44 | self.counter += 1
45 |
46 | def loadText(self, path=None, text_id=1):
47 | """ Load a text from a file
48 |
49 | :param path string: the path to the file containing the text
50 | "param text_id int: choose the text to load
51 | TODO: add loading, now it's hardcoded text
52 | """
53 | if text_id == '1':
54 | text = 'OP MIJNEN GEBOORT-DAGH\n\n\
55 | Noch eens September, en noch eens die vierde dagh\n\
56 | Die mij verschijnen sagh!\n\
57 | Hoe veel Septembers, Heer, en hoe veel’ vierde dagen\n\
58 | Wilt ghij mij noch verdragen?\n\
59 | Ick bidd om geen verlang: ’tkan redelyck bestaen,\n\
60 | Het ghen’ ick heb gegaen:\n\
61 | En van mijn’ wiegh tot hier zijn soo veel dusend schreden\n\
62 | Die ick heb doorgetreden,\n\
63 | (Met vallen, lieve God, en opstaen, soo ghij weett,)\n\
64 | Dat die all ’t selve leed\n\
65 | En all’ de selve vreughd naer mij hadd door te reisen,\n\
66 | Sich drijmael sou bepeisen\n\
67 | Wat besten oorber waer, gelaten of gedaen.\n\
68 | Mij, Heere, laet vrij gaen;\n\
69 | Mijn’ roll is afgespeelt, en all wat kan gebeuren\n\
70 | Van lacchen en van treuren\n\
71 | Is mij te beurt geweest, en all wat beuren sal\n\
72 | Sal ’tselve niet met all,\n\
73 | En d’ oude schaduw zijn van dingen die wat schijnen\n\
74 | En komende verdwijnen.\n\
75 | Wat wacht ick meer op aerd, waerom en scheid’ ick niet?\n\
76 | ’K wacht, Heer, dat ghij ’tgebiedt.\n\
77 | Maer, magh ick noch een’ gunst by d’andere begeeren,\n\
78 | Laet mij soo scheiden leeren,\n\
79 | Dat yeder een die ’t siet mijn scheiden en het sijn\n\
80 | Wensch’ eenerhand te zijn.\n'
81 | else:
82 | text = 'DROOMEN YDELHEIT\n\n\
83 | Wie weet wat droomen is? ick weet het; en wie niet,\n\
84 | Die op sijn selven, neen; die in syn selven siet?\n\
85 | Siet innewaerts, en denckt wat dencken is: dat’s droomen.\n\
86 | Die sonder dencken is, is aen syn’ dood gekomen.\n\
87 | Maer slapen scheelt soo veel van dood zijn, als de dood\n\
88 | Van swijmen, en ’t geroll, van ’tliggen van een’ kloot.\n\
89 | Wij dencken slapende: maer dampen die doen slapen\n\
90 | Doen dat wij ons in ons aen schaduwen vergapen.\n\
91 | De Reden doet wat, maer belemmert en verwert;\n\
92 | Soo komt dat droomen ernst, en dencken duncken werdt.\n\
93 | Gaet en bouwt redenen van hopen of van schroomen\n\
94 | Op bij de Sonn of by de Maen gesufte droomen:\n\
95 | Wat dunckt u, is ’t niet seer all eenerley gedrocht,\n\
96 | Of wat ick hebb gedacht, of wat mij heeft gedocht?'
97 |
98 | return text
99 |
--------------------------------------------------------------------------------
/doc/build/html/search.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Search — CodeKlavier 0.3.0 documentation
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
58 | Please activate JavaScript to enable the search
59 | functionality.
60 |
61 |
62 |
63 | From here you can search these documents. Enter your search
64 | words into the box below and click "search". Note that the search
65 | function will automatically search for all of the words. Pages
66 | containing fewer words won't appear in the result list.
67 |
95 |
99 |
100 |
--------------------------------------------------------------------------------
/hello_world/hello_world_nkk.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import configparser
4 | import getopt
5 | import rtmidi
6 | import sys
7 | import time
8 |
9 | # CodeKlavier Modules
10 | import CK_configWriter
11 | from CK_Setup import Setup
12 | from hello_classes import HelloWorld
13 | from Instructions import Instructions
14 | from Mapping import Mapping_HelloWorld_NKK
15 |
16 | def main(configfile='../default_setup.ini'):
17 | """
18 | Start hello world!
19 |
20 | :param int configfile: use this configuration file. Defaults to 'default_setup.ini'.
21 | """
22 |
23 | #Read config and settings
24 | config = configparser.ConfigParser()
25 | config.read(configfile, encoding='utf8')
26 |
27 | try:
28 | myPort = config['midi'].getint('port')
29 | device_id = config['midi'].getint('noteon_id')
30 | except KeyError:
31 | raise LookupError('Missing key information in the config file.')
32 |
33 | if (myPort == None or device_id == None):
34 | raise LookupError('Missing key information in the config file.')
35 |
36 | codeK = Setup()
37 | tutorial = Instructions()
38 | codeK.open_port(myPort)
39 | codeK.open_port_out(myPort)
40 |
41 | # Use your favourite mapping of the keys
42 | mapping = Mapping_HelloWorld_NKK()
43 |
44 | # class to handle the midi input and map it to characters
45 | #TODO: this is ugly! Move this to the CodeKlavier module
46 | class HelloWorld(object):
47 | def __init__(self, port):
48 | self.port = port
49 |
50 | def __call__(self, event, data=None):
51 | message, deltatime = event
52 | # print(message)
53 | if message[2] > 0: #only noteOn
54 | if (message[0] == device_id):
55 | mapping.mapping(message[1])
56 | # forwarding only note on messages to tutorial terminal for NKK:
57 | codeK.send_message([message[0], message[1], message[2]])
58 | if (message[0] == 176): #hardcoded pedal id (not pretty)
59 | mapping.stopSC(message[1])
60 |
61 | codeK.set_callback(HelloWorld(myPort))
62 |
63 | # Loop to program to keep listening for midi input
64 | try:
65 | # timer = time.time()
66 | while True:
67 | if tutorial.mode():
68 | break
69 | time.sleep(0.01)
70 | except KeyboardInterrupt:
71 | print('')
72 | finally:
73 | # print("Bye-Bye :(")
74 | codeK.end()
75 |
76 | if (__name__ == '__main__'):
77 | try:
78 | options, args = getopt.getopt(sys.argv[1:],'hc:m:',['help', 'configfile=', 'makeconfig='])
79 | selected_options = [x[0] for x in options]
80 | except getopt.GetoptError:
81 | print('Something went wrong with parsing the options')
82 | if ('-c' in selected_options or '--configfile' in selected_options) \
83 | and ('-m' in selected_options or '--makeconfig' in selected_options):
84 | #cannot deal with creating a new one and using a specified config
85 | raise ValueError('Chooce either the "configfile-option" or the option to create a configfile. Not both.')
86 | for o, a in options:
87 | if o in ('-h', '--help'):
88 | print('Usage: python3 hello_world.py [OPTION]')
89 | print('')
90 | print('Where [OPTION] is:')
91 | print(' -h | --help')
92 | print(' Print this help text.')
93 | print('')
94 | print(' -c <> | --configgile <>')
95 | print(' Use configuration file <>. You can write this configuration file with the -m option')
96 | print('')
97 | print(' -m <> | --makeconfig <>')
98 | print(' Create a configfile and use it. If <> already exits, it will be over written.')
99 | sys.exit(0)
100 | if o in ('-c', '--configfile'):
101 | #use existing configfile
102 | main(configfile=a)
103 | if o in ('-m', '--makeconfig'):
104 | #create new configfile and use it
105 | CK_configWriter.createConfig(configfile=a)
106 | main(configfile=a)
107 |
108 | #no options were supplied: run hello_world with default settings
109 | main()
110 |
--------------------------------------------------------------------------------
/doc/build/html/_static/pygments.css:
--------------------------------------------------------------------------------
1 | .highlight .hll { background-color: #ffffcc }
2 | .highlight { background: #eeffcc; }
3 | .highlight .c { color: #408090; font-style: italic } /* Comment */
4 | .highlight .err { border: 1px solid #FF0000 } /* Error */
5 | .highlight .k { color: #007020; font-weight: bold } /* Keyword */
6 | .highlight .o { color: #666666 } /* Operator */
7 | .highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */
8 | .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
9 | .highlight .cp { color: #007020 } /* Comment.Preproc */
10 | .highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */
11 | .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
12 | .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
13 | .highlight .gd { color: #A00000 } /* Generic.Deleted */
14 | .highlight .ge { font-style: italic } /* Generic.Emph */
15 | .highlight .gr { color: #FF0000 } /* Generic.Error */
16 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
17 | .highlight .gi { color: #00A000 } /* Generic.Inserted */
18 | .highlight .go { color: #333333 } /* Generic.Output */
19 | .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
20 | .highlight .gs { font-weight: bold } /* Generic.Strong */
21 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
22 | .highlight .gt { color: #0044DD } /* Generic.Traceback */
23 | .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
24 | .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
25 | .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
26 | .highlight .kp { color: #007020 } /* Keyword.Pseudo */
27 | .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
28 | .highlight .kt { color: #902000 } /* Keyword.Type */
29 | .highlight .m { color: #208050 } /* Literal.Number */
30 | .highlight .s { color: #4070a0 } /* Literal.String */
31 | .highlight .na { color: #4070a0 } /* Name.Attribute */
32 | .highlight .nb { color: #007020 } /* Name.Builtin */
33 | .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
34 | .highlight .no { color: #60add5 } /* Name.Constant */
35 | .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
36 | .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
37 | .highlight .ne { color: #007020 } /* Name.Exception */
38 | .highlight .nf { color: #06287e } /* Name.Function */
39 | .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
40 | .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
41 | .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
42 | .highlight .nv { color: #bb60d5 } /* Name.Variable */
43 | .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
44 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */
45 | .highlight .mb { color: #208050 } /* Literal.Number.Bin */
46 | .highlight .mf { color: #208050 } /* Literal.Number.Float */
47 | .highlight .mh { color: #208050 } /* Literal.Number.Hex */
48 | .highlight .mi { color: #208050 } /* Literal.Number.Integer */
49 | .highlight .mo { color: #208050 } /* Literal.Number.Oct */
50 | .highlight .sa { color: #4070a0 } /* Literal.String.Affix */
51 | .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
52 | .highlight .sc { color: #4070a0 } /* Literal.String.Char */
53 | .highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */
54 | .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
55 | .highlight .s2 { color: #4070a0 } /* Literal.String.Double */
56 | .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
57 | .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
58 | .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
59 | .highlight .sx { color: #c65d09 } /* Literal.String.Other */
60 | .highlight .sr { color: #235388 } /* Literal.String.Regex */
61 | .highlight .s1 { color: #4070a0 } /* Literal.String.Single */
62 | .highlight .ss { color: #517918 } /* Literal.String.Symbol */
63 | .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
64 | .highlight .fm { color: #06287e } /* Name.Function.Magic */
65 | .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
66 | .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
67 | .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
68 | .highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */
69 | .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */
--------------------------------------------------------------------------------
/CodeKlavier/CK_rec.py:
--------------------------------------------------------------------------------
1 | """CodeKlavier recording of midi events in .csv format.
2 |
3 | For Machine Learning PIA
4 | """
5 |
6 | from CK_Setup import Setup
7 | import time
8 | import configparser
9 | import re
10 | import os
11 |
12 |
13 | class CK_Rec(object):
14 | """
15 | Class to handle the recording of midi events in .csv format
16 | """
17 |
18 | def __init__(self, configfile=None):
19 | self._configfile = configfile
20 | self._deltamem = []
21 |
22 | def delta_difference(self, deltatime_in):
23 | # activesense compensation
24 | ck_deltatime_mem = self._deltamem
25 |
26 | ck_deltatime_mem.append(deltatime_in)
27 | #print('deltatimes stack: ', ck_deltatetime_mem)
28 |
29 | if len(ck_deltatime_mem) > 2:
30 | ck_deltatime_mem = ck_deltatime_mem[-2:]
31 |
32 | if len(ck_deltatime_mem) == 2:
33 | dif = ck_deltatime_mem[1] - ck_deltatime_mem[0]
34 | if dif < 0:
35 | dif = 0
36 | return dif
37 | else:
38 | return 0
39 |
40 | def record(self, framesize=10):
41 | """
42 | Run a basic miditest to see how the CodeKlavier is receiving your midi.
43 | """
44 |
45 | timestamp = time.strftime("%y-%m-%d")
46 | ck_deltatime = 0
47 | per_note = 0
48 | recfile = open('ml_data/_', 'w')
49 | headers = ''
50 |
51 | #Read config and settings
52 | config = configparser.ConfigParser()
53 | config.read(self._configfile, encoding='utf8')
54 |
55 | try:
56 | myPort = config['midi'].getint('port')
57 | note_on = config['midi'].getint('noteon_id')
58 | note_off = config['midi'].getint('noteoff_id')
59 | except KeyError:
60 | raise LookupError('Missing key information in the config file.')
61 |
62 | if (myPort == None or note_on == None):
63 | raise LookupError('Missing key information in the config file.')
64 |
65 | codeK = Setup()
66 | codeK.open_port(myPort)
67 | print('your note on id is: ', note_on, '\n')
68 | print("CodeKlavier is RECORDING. Press Control-C to save and exit.")
69 | for i in range(0,framesize):
70 | if framesize == 1:
71 | index = ''
72 | else:
73 | index = str(i)
74 | headers += 'midi_note'+index+',velocity'+index+',duration'+index+',label'+index
75 |
76 | recfile.write(headers+'\n')
77 | data_line = ''
78 | deltatime_mem = {}
79 | ostinato_length = 9
80 | note_counter = 1
81 |
82 |
83 | try:
84 | while True:
85 | msg = codeK.get_message()
86 |
87 | if msg:
88 | message, deltatime = msg
89 | ck_deltatime += deltatime
90 | per_note += deltatime
91 | if message[0] != 254:
92 | if message[0] == note_on:
93 | deltatime_mem[message[1]] = ck_deltatime
94 | velocity = message[2]
95 | if message[0] == note_off:
96 |
97 | if note_counter > 9:
98 | note_counter = 1
99 |
100 | per_note = 0
101 | dif = self.delta_difference(per_note)
102 | #midimsg = list(map(str, message)) #full msg not needed
103 | midinote = message[1]
104 | label = note_counter/ostinato_length
105 | #label = 0
106 | note_duration = ck_deltatime - deltatime_mem.pop(midinote)
107 | data_line += str(midinote) + ',' + str(velocity) + ',' + str(note_duration) + ',' + str(label)
108 | data_line += '\n'
109 | clean_line = re.sub(r"\[?\]?", '', data_line)
110 | print(clean_line)
111 | recfile.write(clean_line)
112 | data_line = ''
113 | note_counter += 1
114 |
115 | time.sleep(0.01)
116 |
117 | except KeyboardInterrupt:
118 | print('saving recording...')
119 | finally:
120 | recfile.close()
121 | title = input('Dear CK user, please type a comprehensive title for the recording and press ENTER:');
122 | usertitle = title+'_'+timestamp+'.csv'
123 | os.rename("ml_data/_", "ml_data/"+usertitle)
124 | print("recording saved with title: ", usertitle)
125 | codeK.end()
126 |
--------------------------------------------------------------------------------
/ml_data/deprecated tests/test7 (mixed, last was a mistake (and incomplete)_18-11-18.csv:
--------------------------------------------------------------------------------
1 | source_id0,midi_note0,velocity0,ck_deltatime0,dif_deltatime0,source_id1,midi_note1,velocity1,ck_deltatime1,dif_deltatime1,source_id2,midi_note2,velocity2,ck_deltatime2,dif_deltatime2,source_id3,midi_note3,velocity3,ck_deltatime3,dif_deltatime3,source_id4,midi_note4,velocity4,ck_deltatime4,dif_deltatime4,source_id5,midi_note5,velocity5,ck_deltatime5,dif_deltatime5,source_id6,midi_note6,velocity6,ck_deltatime6,dif_deltatime6,source_id7,midi_note7,velocity7,ck_deltatime7,dif_deltatime7,source_id8,midi_note8,velocity8,ck_deltatime8,dif_deltatime8,source_id9,midi_note9,velocity9,ck_deltatime9,dif_deltatime9,
2 | 144,54,64,6.062783583000001,0,144,60,59,6.285908555000001,0,128,54,64,6.288989408000001,0.003080853,128,60,68,6.4763552650000005,0.18736585700000002,144,67,56,6.497915975000001,0,144,54,58,6.677899485000001,0,128,67,60,6.681048008000001,0.0031485230000000003,144,60,59,6.868776190000001,0,128,54,65,6.875277893000001,0.006501703,128,60,67,7.073225893,0.19794800000000004,
3 | 144,54,61,0,0,128,67,57,0.0021533050000000003,0.0021533050000000003,144,60,57,0.189864975,0,128,54,64,0.203171925,0.013306950000000001,144,67,54,0.414192185,0,128,60,62,0.4205487,0.006356515,128,67,71,0.552846693,0.132297993,144,58,71,2.278121065,0,144,68,74,2.486542223,0,128,58,65,2.4959246349999997,0.009382412000000001,
4 | 144,69,64,0,0,128,69,66,0.16153591,0.16153591,144,58,61,0.17745243,0,144,68,72,0.344554935,0,128,58,67,0.359301038,0.014746103000000002,128,68,68,0.5252448780000001,0.16594384,144,69,68,0.535958055,0,128,69,60,0.695357678,0.159399623,144,58,63,0.708585243,0,144,68,71,0.8753163150000001,0,
5 | 144,69,59,0,0,128,69,49,0.113731125,0.113731125,144,56,68,1.7224430930000003,0,128,56,66,1.8723975480000004,0.14995445500000001,144,64,65,1.8776299250000004,0,128,64,73,2.0160827880000003,0.138452863,144,67,65,2.044361228,0,144,56,65,2.1644145050000003,0,128,67,67,2.1796328880000004,0.015218383,128,56,69,2.2979575950000006,0.118324707,
6 | 144,67,54,0,0,128,67,55,0.099195855,0.099195855,144,56,62,0.111723995,0,144,64,63,0.23169214300000002,0,128,56,65,0.241289938,0.009597795000000001,128,64,46,0.34975129000000005,0.108461352,144,67,56,0.37050215000000003,0,128,67,71,0.435907343,0.065405193,144,55,62,1.2650660230000002,0,128,55,68,1.3642798230000002,0.09921380000000002,
7 | 144,68,63,0,0,128,68,92,0.06807840700000001,0.06807840700000001,144,55,60,0.10172652200000001,0,128,55,71,0.21127188000000002,0.10954535800000001,144,62,74,0.23194463200000004,0,128,62,77,0.34815004200000005,0.11620541000000001,144,68,85,0.35186406700000006,0,128,68,68,0.45316971000000006,0.101305643,144,55,71,0.45645156500000006,0,144,62,85,0.5741913970000001,0,
8 | 144,68,94,0,0,128,62,77,0.026568805,0.026568805,128,68,70,0.120422205,0.0938534,144,53,37,1.147272867,0,128,53,60,1.2511507020000001,0.103877835,144,61,56,1.2709216920000002,0,128,61,50,1.3764703970000003,0.10554870499999999,144,62,61,1.3993737750000004,0,144,53,74,1.5036762800000003,0,128,62,49,1.5073228700000003,0.0036465900000000003,
9 | 144,62,92,0,0,128,61,77,0.009641498,0.009641498,144,53,90,0.12661824300000002,0,128,62,65,0.14326901500000003,0.016650772,144,61,93,0.23921698500000002,0,128,53,75,0.30550846000000004,0.066291475,144,62,98,0.35535468000000003,0,128,61,78,0.37356593000000005,0.018211250000000002,128,62,76,0.5095270380000001,0.135961108,144,61,93,1.6449963680000002,0,
10 | 144,62,85,0,0,128,54,71,0.013838725000000001,0.013838725000000001,144,61,94,0.13167795799999998,0,128,62,78,0.16579129799999998,0.03411334,144,54,83,0.259693005,0,128,61,75,0.287617425,0.027924420000000002,144,62,77,0.40375927,0,128,54,70,0.416449413,0.012690143000000001,128,62,75,0.544577898,0.12812848500000001,144,61,67,0.54707714,0,
11 | 144,54,57,0,0,128,54,69,0.128902983,0.128902983,144,62,48,0.156030578,0,128,62,69,0.22924780800000003,0.07321723000000001,144,57,60,1.7021975900000001,0,128,57,75,1.8380733900000001,0.13587580000000002,144,54,63,1.865284715,0,128,54,62,1.996122658,0.130837943,144,63,65,2.0186285600000002,0,128,63,60,2.1585361680000004,0.13990760800000002,
12 | 144,54,62,0,0,128,57,70,0.009816625,0.009816625,144,63,67,0.14594683,0,128,54,67,0.15594304,0.00999621,144,57,63,0.28427703800000004,0,128,63,67,0.28904292800000003,0.00476589,144,54,65,0.43409522,0,128,57,63,0.436065795,0.001970575,128,54,65,0.6009904549999999,0.16492466000000003,144,63,61,0.6032709629999999,0,
13 | 144,56,62,0,0,128,56,65,0.127815548,0.127815548,144,54,63,0.13151921,0,128,54,63,0.26626166,0.13474245,144,63,56,0.27572379,0,128,63,49,0.384066793,0.10834300300000002,144,56,57,0.391614198,0,128,56,42,0.5240965200000001,0.132482322,144,54,62,0.52747856,0,144,63,61,0.6689682430000001,0,
14 | 144,56,57,0,0,144,54,59,0.13237284200000002,0,128,56,68,0.13487225700000002,0.002499415,128,54,65,0.256250195,0.121377938,144,63,61,0.28541220700000003,0,128,63,49,0.40369447,0.11828226300000001,144,51,75,1.2782725850000003,0,144,61,71,1.3974889320000001,0,128,51,67,1.4092276270000001,0.011738695,128,61,71,1.5074283750000002,0.098200748,
15 | 144,51,80,0,0,128,62,70,0.007639095,0.007639095,144,61,82,0.119292115,0,128,51,70,0.14953111,0.030238995,128,61,75,0.241094305,0.091563195,144,62,81,0.24333047200000002,0,144,51,86,0.36518933500000006,0,128,62,74,0.37977523500000004,0.0145859,144,61,87,0.49404500200000007,0,128,51,72,0.5279920650000001,0.033947063,
16 |
--------------------------------------------------------------------------------
/assets/ACTIVITIES.md:
--------------------------------------------------------------------------------
1 | ---
2 | permalink: /activities
3 | ---
4 |
5 | # CodeKlavier Activities 🎹🎤
6 |
7 | ### This page gives a run down of public CodeKlavier presentations and milestones to date:
8 | (newest on top)
9 |
10 | May/June 2023: Recording videos of ARquatic and MercTippets for HashiCorps HashiDays 2023
11 |
12 | Winter 2022/23: "The Pianist Gardener" version of ARquatic in [ART+](https://artplus.app/)
13 |
14 | September/October 2022: ARquatic tour of botanical gardens around the Netherlands
15 |
16 | February 2022: Release book chapter "The CodeKlavier: Appropriating the piano as a live coding instrument" in [Rethinking the Musial Instrument](https://www.cambridgescholars.com/product/978-1-5275-7789-3)
17 |
18 | Summer 2021: ARquatic, CodeKlavier's music and augmented reality experience, has its premier and performances in the Netherlands.
19 |
20 | January 2021: CodeKlavier meets Mercury, Mercury Live Coding Sessions. Watch the video [here](https://youtu.be/e4sPKOlaYS8)
21 |
22 | October 2020: CodeKlavier meets Fokker organ. [Muziekgebouw Amsterdam](https://www.muziekgebouw.nl/nl/agenda/9130/Anne_Veinberg_Felipe_Ignacio_Noriega_Alcaraz/Anne_Veinberg_in_de_hoofdrol)
23 |
24 | August 2019: Paper, lecture and performance at [FARM Berlin 2019](https://icfp19.sigplan.org/home/farm-2019). Watch the video [here](https://youtu.be/K1ai2N9bSqI). Third residency with Patrick Borgeat working on the AR extension
25 |
26 | June 2019: Second residency with Patrick Borgeat working on the AR extension.
27 |
28 | May 2019: Performaces of the CKalcuλator at Sounds like Soup on the 19th and at Young Amsterdam Artists concert on the 23rd. Both concerts are in Amsterdam. Our second residency with Patrick Borgeat working on the AR extension will take place.
29 |
30 | March 2019: First residency with Patrick Borgeat working on the AR extension. Watch the teaser [here](https://youtu.be/p65YavCUEuQ)
31 |
32 | February 2019: Talk and performance with the Ckalcuλator at [Lambda Days](http://www.lambdadays.org/lambdadays2019) in Poland. Watch the video [here](https://youtu.be/0fL40oLU8C4)
33 |
34 | January 2019: Performance of new hybrid version for Disklavier at [Conlon X Gaudeamus](https://gaudeamus.nl/events/gaudeamus-x-conlon-disklavier-projection-works/) - Watch the [trailer](https://youtu.be/GHEOdT-t4Us)!
35 | We also performed with the CKalculator at the [International Conference on Live Coding](http://iclc.livecodenetwork.org/2019/ingles.html)
36 |
37 | November 2018: Performance at Splendor
38 |
39 | October 2018: Performance at [ARTikulationen in Graz](http://doctorartium.kug.ac.at/pdf/ARTikulationen2018Programm3.pdf). This was the first time we used our custom built KeyScanner.
40 |
41 | September 2018: Performance at the [Huygens Festival](https://huygensfestival.nl/) in Voorburg, Netherlands. We also did an [interview with Dennis Kastrup](https://www.radioeins.de/programm/sendungen/modo1316/strom-und-drang/codeklavier.html) about the project for Radio Eins.
42 |
43 | August 2018: CodeKlavier paper and performance are presented at the [International Computer Music Conference](https://icmc2018.org/) in Daegu, Korea! In the proceedings you can find our first CodeKlavier published paper.
44 |
45 | July 2018: CodeKlavier received its custom built KeyScanner by Andrew McPherson.
46 |
47 | June 2018: Performance and lecture-demonstration at MuSA 2018 at IMWI Karlsruhe, Germany. Our presentation included a special CodeKlavier "presentation mode" where we used various CodeKlavier piano techniques to live code the presentation. This event also featurde a performance of Huygbrid and a more developed version of the CKalculator.
48 | There were also performances of Huygbrid (previously Hybrid) and CKalculator at Ephemere in Studio Loos, Netherlands. Watch the video of CKalculator [here](https://youtu.be/Ea4pUYqb8BA).
49 |
50 | May 2018: Performance of two new prototypes, Hybrid and CKalculator at WORM in Rotterdam as part of the Algo~rhythms series.
51 |
52 | March 2018: Performance at the Huygens Festival Amuse in Voorburg, NL and at In-Sonora Festival in Madrid, Spain. Video from In-Sonora [here]( https://www.youtube.com/watch?v=F5O_WUdtOqY&t=5149s)
53 |
54 | February 2018: Recording of [Motippets](https://youtu.be/nzsW1w38JEc) version 1.
55 |
56 | December 2017: Mini-tour! "hello world" and Motippets were performed at the International Conference on Live Coding in Morelia, Mexico - watch video of Motippets [here](https://youtu.be/Kk71xkodu0k). We also gave a lecture-presentation at the Tandon School of Engineering, hosted by LiveCode.NYC, in New York and performed "hello world" at the Uncaged Toy Piano Festival. Watch video [here](https://youtu.be/N_Vpo5jzH_c).
57 |
58 | October 2017: CodeKlavier received a 2 year grant for further development from the [Creative Industries Fund NL](http://m.stimuleringsfonds.nl/nl/toekenningen/codeklavier/4410/) and our angel sponsor.
59 |
60 | September 2017: "hello world" is performed at the Gaudeamus Muziek week - a contemporary music festival held annually in Utrecht, Netherlands. A special interactive version of "hello world" is created as an interactive installation for Leiden's [Evening of Art and Science](http://nachtvankunstenkennis.nl/act/codeklavier).
61 |
62 | August 2017: [Still Hacking Anyway 2017, NL](https://sha2017.org/).
63 | Our first live presentation of the CodeKlavier. We also performed "Code Our Glance" where we play as a duo. A video of the event is available [here](https://youtu.be/efU7trVAPvA).
64 |
65 | May 2017: "hello world" is awarded the Conlon and Uncaged Festival's Composition Prize. Watch the video [here](https://youtu.be/ytpB8FB6VTU)
66 |
67 | April 2017: CodeKlavier received the starter's phase grant from the Creative Industries Fund NL.
68 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CodeKlavier
2 |
3 | ### Live coding with the piano as interface.
4 |
5 | An open source project by Felipe Ignacio Noriega and Anne Veinberg.
6 |
7 | CodeKlavier development started in April 2017 and currently has five modules (newest on top):
8 | + [*ARquatic*](https://codeklavier.space/arquatic) (A CodeKlavier Augmented Reality experience!)
9 | + [*Ckalcuλator*](https://github.com/narcode/codeklavier/tree/master/ckalculator) (Lambda-calculus with the piano!)
10 | + [*Hybrid*](https://github.com/narcode/codeklavier/blob/master/hybrid/README.md) (switching between the first two prototypes and includes a custom code display via udp sockets)
11 | + [*Motippets*](https://github.com/narcode/codeklavier/tree/master/motippets) (coding via pianistic gestures/motifs)
12 | + [*hello world*](https://github.com/narcode/codeklavier/blob/master/hello_world) (proof of concept prototype, with 1-1 mapping of piano keys to alphanumeric characters)
13 |
14 | More information about the specific prototypes can be found in their respective directories.
15 |
16 | ### Latest
17 | CodeKlavier made two videos for this year's [HashiDays event](https://hashidays.com/online/). The first is [ARquatic](https://codeklavier.space/arquatic) and the second uses the [Motippets](https://github.com/narcode/codeklavier/tree/master/motippets) module to code in [Mercury](https://www.timohoogland.com/mercury-livecoding/). With thanks to Simon Kelaita and Patrick Borgeat for the audio and video editing respectively.
18 |
19 | ### CodeKlavier in action
20 | Checkout our [videos page](https://codeklavier.space/videos) to see the Codeklavier in action or visit the [Activities page](https://codeklavier.space/activities) for info on past and future performances.
21 |
22 | ### Goals
23 |
24 |
The dream:
🐍🎹 An intuitive programming language with the piano as interface.
25 |
26 |
The starting-to-be-graspable dream:
👩🏼💻 A programming language for the piano as interface
27 |
28 |
The long term goal:
🎼🎧 a live coding music-domain programming language for the piano as interface
29 |
30 |
The mid term goal:
💾📌 strategy-specific releases of mini-language approaches for live coding through the piano
31 |
32 |
The short term goal:
📆📈 research-release-evaluation cycles of prototypes which tackle specific aspects of the system
33 |
34 |
35 |
36 | ## Equipment
37 | 1. An acoustic-MIDI piano such as a Disklavier, any piano fitted with a silent system or an acoustic intrument in combination with a MOOG piano bar or other MIDI keyscanner. We use a MIDI KeyScanner developed by Andrew McPherson and his team at Queen Mary University of London. If an acoustic-MIDI piano is not available, any 88-key MIDI keyboard will suffice providing this instrument is of suitable sensitivity for the pianist.
38 |
39 | 2. MIDI interface (if not integrated in the piano)
40 |
41 | ## Libraries
42 | Install with pip3
43 |
44 | 1. python-rtmidi
45 | 2. pynput
46 | 3. sphinx
47 | 4. numpy
48 | 5. python-osc (if you want to use the AR module and Caffeine Extension)
49 | 6. websockets (idem)
50 |
51 | Run ``pip3 install -r requirements.txt`` to install the required libraries.
52 |
53 | ## Modules
54 | __For this version please add the CodeKlavier directory to your sys.path so the CK modules are recognized__
55 |
56 | You can run the ``setPythonPath.sh`` every time you start a new shell (type ``. setPythonPath.sh`` - not the **dot-space** before the command), or put the following lines in your ``~/.bash_profile`` or ``~/.bashrc`` or equivalent add the following lines (make sure you have the correct path!):
57 |
58 | `# Modules for the CodeKlavier
59 | PYTHONPATH="/path/to/your/codeklavier/project/folder:$PYTHONPATH"
60 | export PYTHONPATH`
61 |
62 | As an example, the path to the Codeklavier in my system looks like this:
63 |
64 | `
65 | PYTHONPATH="/Users/narcodeb/Development/Repos/codeklavier-python/CodeKlavier:$PYTHONPATH"
66 | `
67 | ## Extensions
68 |
69 | There are a number of different code output extensions for the CodeKlavier. The loading ini file for these can be found in the CodeKlavier-Extensions repository[https://github.com/codeklavier/codeklavier-extensions]. You will need to download/clone this directory in order to run CodeKlavier.
70 |
71 | If you are interested in collaborating on an extension for the CodeKlavier, don't hesitate to get in touch.
72 |
73 | Currently, outpute extensions exist for SuperCollider, Mercury, JavaScript, Augmented Reality and Hydra.
74 |
75 |
76 | ## Test run
77 | After installing the libraries, plug in your midi device and run the miditest by ``python3 miditest.py``. After you complete the setup and configuration, you will see the midi messages on the screen. After that run codeklavier.py -p hybrid -i base.ini (be sure to change the directory too match your setup Try playing an upward C major 3 note arpeggio starting on middle C. If everything works, your test is complete and you are ready to explore CK!
78 |
79 |
80 | ## Watch
81 | [Codeklavier Videos](http://codeklavier.space/videos)
82 |
83 | ## Publications
84 | [Publications page](https://codeklavier.space/publications)
85 |
86 | ## Support
87 | This project was made possible by the Creative Industries Fund NL, our angel sponsor and the festivals and venues that book us for paid concerts. However, our initial funding has come to an end so if you believe in the project and would like to support it, please consider "buying us a coffee". Every little bit counts and we greatly appreciate your support!
88 |
89 | [](https://ko-fi.com/J3J7PGIE)
90 |
--------------------------------------------------------------------------------
/ml_data/deprecated tests/test6 (soft and fast but perhaps some notes were missing - although this could be nice to include)_18-11-18.csv:
--------------------------------------------------------------------------------
1 | source_id0,midi_note0,velocity0,ck_deltatime0,dif_deltatime0,source_id1,midi_note1,velocity1,ck_deltatime1,dif_deltatime1,source_id2,midi_note2,velocity2,ck_deltatime2,dif_deltatime2,source_id3,midi_note3,velocity3,ck_deltatime3,dif_deltatime3,source_id4,midi_note4,velocity4,ck_deltatime4,dif_deltatime4,source_id5,midi_note5,velocity5,ck_deltatime5,dif_deltatime5,source_id6,midi_note6,velocity6,ck_deltatime6,dif_deltatime6,source_id7,midi_note7,velocity7,ck_deltatime7,dif_deltatime7,source_id8,midi_note8,velocity8,ck_deltatime8,dif_deltatime8,source_id9,midi_note9,velocity9,ck_deltatime9,dif_deltatime9,
2 | 144,67,48,1.8868562629999999,0,128,67,59,1.9758020749999998,0.088945812,144,66,65,1.997615083,0,128,66,73,2.077318293,0.07970321,144,62,59,2.1133731879999997,0,128,62,79,2.1725996149999998,0.059226427000000005,144,67,61,2.215369005,0,128,67,48,2.3282239899999997,0.112854985,144,66,68,2.3310755179999996,0,128,66,51,2.4354641199999993,0.104388602,
3 | 144,67,56,0,0,128,67,53,0.09797993,0.09797993,144,66,63,0.10297469000000001,0,128,66,52,0.20895676500000002,0.10598207500000001,144,62,44,0.24562450500000002,0,128,62,76,0.30708053500000004,0.06145603,144,67,37,1.421438622,0,128,67,75,1.4906765549999998,0.069237933,144,63,52,1.51137631,0,128,63,62,1.60053826,0.08916195,
4 | 144,67,55,0,0,144,63,68,0.124005798,0,128,67,68,0.127151615,0.0031458170000000004,128,63,50,0.233829543,0.106677928,144,61,61,0.245698223,0,144,67,52,0.338251183,0,128,61,54,0.355313948,0.017062765,128,67,53,0.441702845,0.08638889699999999,144,63,62,0.457831678,0,128,63,54,0.5614809430000001,0.103649265,
5 | 144,61,51,0,0,128,61,74,0.070543172,0.070543172,144,57,63,0.10861849200000001,0,128,57,58,0.201593917,0.092975425,144,68,59,0.241352635,0,128,68,92,0.306725515,0.06537288000000001,144,61,58,0.338315805,0,128,61,86,0.40257418500000003,0.06425838,144,57,58,0.44338468700000006,0,128,57,47,0.5562617350000001,0.11287704800000001,
6 | 144,61,62,0,0,128,61,81,0.07594386,0.07594386,144,57,65,0.11274866,0,128,57,65,0.214730712,0.101982052,144,68,70,0.243203477,0,128,68,61,0.327048765,0.083845288,144,60,59,1.415729647,0,128,60,66,1.491246072,0.075516425,144,61,68,1.520806535,0,128,61,72,1.598224572,0.07741803700000001,
7 | 144,60,59,0,0,128,60,61,0.081202967,0.081202967,144,61,65,0.10149604200000001,0,128,61,84,0.163497652,0.062001610000000006,144,62,54,0.225847607,0,128,62,56,0.319299477,0.09345187,144,60,59,0.33695379,0,128,60,62,0.42094466199999997,0.08399087200000001,144,61,63,0.44473342,0,128,61,61,0.528822605,0.08408918500000001,
8 | 144,54,63,0,0,128,54,56,0.10524609500000001,0.10524609500000001,144,67,58,0.12148470500000001,0,128,67,51,0.22679453,0.105309825,144,62,52,0.245747127,0,128,62,83,0.299346587,0.05359946,144,54,67,0.337350265,0,128,54,61,0.461386545,0.12403628000000001,144,67,68,0.468471087,0,128,67,74,0.57884731,0.11037622300000001,
9 | 144,54,64,0,0,144,67,62,0.13307375800000001,0,128,54,54,0.14201680000000003,0.008943042,128,67,75,0.24195408000000002,0.09993728,144,62,54,0.25825056,0,128,62,74,0.350286148,0.092035588,144,66,67,1.469213883,0,144,53,61,1.5805727980000002,0,128,66,62,1.5881718750000002,0.007599077,128,53,75,1.6990996400000002,0.110927765,
10 | 144,66,70,0,0,128,66,101,0.079640242,0.079640242,144,53,60,0.120097172,0,128,53,77,0.32389360700000003,0.203796435,144,60,62,0.35407048500000005,0,128,60,69,0.520164295,0.16609381,144,66,71,0.536272717,0,128,66,59,0.678589515,0.14231679800000002,144,53,64,0.68131658,0,128,53,71,0.781292247,0.099975667,
11 | 144,61,61,0,0,128,61,69,0.07833892,0.07833892,144,62,56,0.14132165800000002,0,128,62,70,0.210251348,0.06892969,144,54,51,0.243647915,0,128,54,50,0.347452745,0.10380483000000001,144,61,66,0.353666315,0,128,61,53,0.458288648,0.10462233300000001,144,62,52,0.5012952350000001,0,128,62,80,0.55832097,0.057025735,
12 | 144,61,58,0,0,128,61,50,0.10794929,0.10794929,144,62,54,0.14016156000000002,0,128,62,83,0.19389723500000003,0.053735675,144,54,37,0.251195345,0,128,54,75,0.31092237300000003,0.059727028,144,53,54,1.032670553,0,128,53,62,1.117339528,0.08466897500000001,144,55,43,1.240617228,0,128,55,58,1.3336262250000002,0.09300899700000001,
13 | 144,54,59,0,0,128,53,73,0.00196274,0.00196274,128,54,52,0.09459922200000001,0.092636482,144,55,45,0.11633676200000001,0,128,55,56,0.209847212,0.09351045000000001,144,53,59,0.21354583,0,128,53,75,0.338446457,0.124900627,144,54,59,0.34245324,0,128,54,52,0.43687398499999996,0.094420745,144,55,45,0.442367635,0,
14 | 144,50,54,0,0,128,50,57,0.09655761800000001,0.09655761800000001,144,58,50,0.10478052800000001,0,128,58,63,0.18125972000000004,0.076479192,144,59,66,0.21117118300000004,0,128,59,59,0.316456638,0.105285455,144,50,61,0.334400415,0,144,58,49,0.44480853,0,128,50,45,0.45315796799999997,0.008349438,128,58,57,0.530252785,0.07709481700000001,
15 | 144,50,54,0,0,144,58,55,0.10554438700000002,0,128,50,66,0.12660373700000002,0.02105935,128,58,70,0.21415414200000005,0.08755040500000001,144,59,32,0.25918018000000004,0,128,59,76,0.3183984800000001,0.0592183,144,49,63,1.4907783350000001,0,128,49,62,1.6157231650000001,0.12494483,144,50,65,1.6244229170000002,0,128,50,68,1.7222447170000004,0.09782180000000001,
16 | 144,49,67,0,0,128,61,50,0.018309055,0.018309055,144,50,65,0.14896258,0,128,49,68,0.162186567,0.013223987000000001,128,50,47,0.262956725,0.10077015800000001,144,61,45,0.26696406500000003,0,144,49,65,0.37527611000000005,0,128,61,65,0.3888882920000001,0.013612182,144,50,62,0.50788158,0,128,49,69,0.5108087120000001,0.0029271320000000003,
17 | 144,50,56,0,0,128,50,88,0.049004173000000005,0.049004173000000005,144,48,54,0.11778967800000001,0,128,48,43,0.24846509500000002,0.13067541700000002,144,51,55,0.260061553,0,128,51,96,0.309089898,0.049028345,144,50,52,0.35531594299999997,0,128,50,72,0.8417685580000001,0.48645261500000003,144,48,51,0.886868863,0,128,48,66,1.08601721,0.199148347,
18 |
--------------------------------------------------------------------------------
/assets/arquaticathome.md:
--------------------------------------------------------------------------------
1 | ---
2 | permalink: /arquaticathome
3 | ---
4 |
5 |
6 | ## ARquatic at Home - A CodeKlavier Augmented Reality Home Experience
7 |
8 | Codeklavier’s ‘ARquatic at Home’ is an online event that brings music and Augmented Reality (AR) together to provide a unique live experience in the comfort of one's own home.
9 |
10 | In ARquatic, music provides the DNA of an underwater world that unfolds before your eyes. Full of fantasy structures artificially built from L-system rules, ‘ARquatic at Home’ will transform your home into a new-age theater you never imagined it to be.
11 |
12 | ## Streams
13 |
14 | Thursday December 2 \
15 | 'ARquatic at Home' - Special stream for Music and Mixed Reality seminar, Nottingham University \
16 | Time: 16:20 British Time
17 | The link of the stream is here [https://youtu.be/0sU8zzKJWyA](https://youtu.be/0sU8zzKJWyA) or click on the video below.
18 |
19 |
20 |
21 | Sunday December 5 \
22 | 'ARquatic at Home' - part of [ChOreOgraph|ng COd|ng](http://varia.zone/en/cc-nlcl.html) \
23 | Time: 14-16h GMT+1
24 |
25 |
26 | ## Past Streams
27 |
28 | Friday August 6 \
29 | 'ARquatic at Home' - Special stream for those in lockdown or stuck at home due to bad weather \
30 | Time: 20:30 Sydney/Melbourne (AUS) or 12:30 Central European Time.
31 | The link of the stream is here [https://youtu.be/F4cGi9Xy0_E](https://youtu.be/F4cGi9Xy0_E) or click on the video below.
32 |
33 |
34 |
35 | ARquatic can also be a live experience, for live show dates please visit our [ARquatic website](https://codeklavier.space/arquatic)
36 |
37 | ## Setting Up
38 |
39 | 'ARquatic at Home' is best experienced when having the streamed video page set up on a desktop or TV connected to a sound system for the duration of the show. The ARquatic App should be downloaded on a separate mobile device. For an optimal AR experience, a well-lit room is best. The app is available for download [here for Apple](https://apps.apple.com/nl/app/arquatic/id1557620712?l=en) and [here for Android](https://play.google.com/store/apps/details?id=space.codeklavier.arquatic&hl=en_US&gl=US). You will need an Apple iPhone SE/6S model (or later) or one of the Android phones listed [here](https://developers.google.com/ar/devices). You can also simply follow the link for the app download and try out the demo channel. If you do not own an AR supported device, a non-AR version will still show visuals on your Android phone.
40 |
41 |
42 | ## Motivation
43 | Our inspiration for working with L-systems comes primarily from its roots in nature and organic growth which we would like to bring to the musical and programming paradigms. Whilst L-systems are already widely used in generative art and music, we are interested in exploring how this simple model can be used by the piano coder to express complex structures and how its rules will shape the pianistic improvisation. Furthermore, Lindenmayer’s work was done at the University of Utrecht in 1968 and building upon it through artistic exploration, makes the Netherlands a particularly special location for the presentation of this project.
44 |
45 |
46 | ## About the Project
47 |
48 | ARquatic is a CodeKlavier project which combines live music, live coding and AR as an artistic experience unlike any other. The [CodeKlavier](https://codeklavier.space/) enables the pianist to grow the AR creatures by coding their structures through her playing with L-system rules. At the same time, the pianist and collaborating laptop musician are taking the audience on an enchanting musical and visual journey.
49 |
50 | ### About the technology
51 |
52 | The ‘ARquatic’ experience is made possible by three key technological elements and stages; CodeKlavier, Lindemayer and Unity.
53 |
54 | CodeKlavier: a system that enables the pianist to code by playing the piano. In ‘ARquatic Live’, this pianist is coding with lambda calculus to create numbers. These numbers are then translated into symbols used in the Lindenmayer systems engine.
55 |
56 | The L-systems engine is the second element and transforms the symbols into formal grammars defining the starting point and L-system rules. Together these form the L-system trees creating the structures of the AR visual elements which you see.
57 |
58 | These structures, along with some characteristics of the piano playing, are then applied to the visuals designed by Patrick Borgeat and rendered in Unity. This is the final step of the technological process and produces the AR visuals which you experience during the show on the ARquatic app.
59 |
60 | ## Credits
61 | [Anne Veinberg](https://anneveinberg.com/) - piano, CodeKlavier development \
62 | [Felipe Ignacio Noriega](https://felipeignacio.info/) - live electronics, CodeKlavier development \
63 | [Patrick Borgeat](https://borgeat.de/) - visuals, app development \
64 | Simon Kelaita - audio mixing, video recording
65 |
66 | ## Sponsors
67 | CodeKlavier was made possible by the Creative Industries Fonds NL and our angel sponsor
68 |
69 | The performances in June and August are made possible the Fonds Podium Kunsten Balkonscenes grant
70 |
71 | ## Questions?
72 | Email arquatic@codeklavier.space
73 |
74 | ## Support
75 | This project was made possible by the Creative Industries Fonds NL and our angel sponsor. Ongoing work is limited to preparations for gigs at festivals and venues that book us for concerts. Do you believe in the project and would like to support us further? please consider "buying us a coffee". Every little bit counts and we greatly appreciate your support!
76 |
77 | [](https://ko-fi.com/J3J7PGIE)
78 |
--------------------------------------------------------------------------------
/codeklavier.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | """
3 | CodeKlavier Masterscript
4 |
5 | This script will help you run the Codeklavier
6 | """
7 |
8 | import configparser
9 | import getopt
10 | import sys
11 | import time
12 |
13 | import importlib
14 |
15 | from CK_Setup import Setup, BColors
16 | from CK_rec import CK_Rec
17 | import CK_config
18 |
19 |
20 |
21 | ck_deltatime_mem = []
22 |
23 | VERSIONS = ('ckar', 'ckalculator', 'hybrid')
24 |
25 | def doHelp():
26 | """
27 | Show the help for running this script.
28 | """
29 | print(BColors.HEADER + 'This script will help you to run the 🎹 CodeKlavier 🎹' + BColors.ENDC)
30 | print('')
31 | print(BColors.CKGREEN + 'Usage: ./codeklaver.py [OPTION]' + BColors.ENDC)
32 | print('Where [OPTION] is:')
33 | print(BColors.BOLD + '-h | --help' + BColors.ENDC)
34 | print('Show this help text.')
35 |
36 | print('')
37 | print(BColors.BOLD + '-p | --play' + BColors.WARNING + ' <>' + BColors.ENDC)
38 | print('Boot CodeKlavier with version <>')
39 | print('These versions are available: ' + (', ').join(VERSIONS))
40 | print('')
41 | print(BColors.BOLD + '-i | --ini' + BColors.WARNING + ' <>' + BColors.ENDC)
42 | print('Boot CodeKlavier with configuration from <>')
43 | print('')
44 | print(BColors.BOLD + '-r | --rec' + BColors.ENDC)
45 | print('Boot CodeKlavier to record MIDI for machine learning')
46 | print('')
47 | print(BColors.BOLD + '-t | --test' + BColors.ENDC)
48 | print('Test and visualize if Codeklavier is receving MIDI')
49 | print('')
50 | print(BColors.UNDERLINE + 'Example:' + BColors.ENDC)
51 | print(BColors.CKGREEN + './codeklavier.py -p hybrid' + BColors.ENDC)
52 | print('')
53 |
54 | def miditest(configfile='default_setup.ini'):
55 | """
56 | Run a basic miditest to see how the CodeKlavier is receiving your midi.
57 |
58 | :param string configfile: Path to the configuration file (default: default_setup.ini)
59 | """
60 | #Read config and settings
61 | config = configparser.ConfigParser()
62 | config.read(configfile, encoding='utf8')
63 |
64 | try:
65 | myPort = config['midi'].getint('port')
66 | device_id = config['midi'].getint('noteon_id')
67 | pedal = config['midi'].getint('pedal_id')
68 | sostenuto = config['midi'].getint('pedal_midi_id')
69 | except KeyError:
70 | raise LookupError('Missing key information in the config file.')
71 |
72 | if (myPort == None or device_id == None):
73 | raise LookupError('Missing key information in the config file.')
74 |
75 | codeK = Setup()
76 | codeK.open_port(myPort)
77 | print('your device id is: ', device_id, '\n')
78 | print("CodeKlavier is ON. Press Control-C to exit.")
79 | try:
80 | while True:
81 | msg = codeK.get_message()
82 |
83 | if msg:
84 | message, deltatime = msg
85 | if message[0] in [device_id, pedal, sostenuto]:
86 | print('deltatime: ', deltatime, 'msg: ', message)
87 |
88 | time.sleep(0.01)
89 |
90 | except KeyboardInterrupt:
91 | print('')
92 | finally:
93 | print("Bye-Bye :(")
94 | codeK.end()
95 |
96 | def boot(configfile='default_setup.ini', version=None):
97 | """
98 | Boot a specific version from the CodeKlavier
99 |
100 | :param string configfile: Path to the configuration file (default: default_setup.ini)
101 | :param string version: name of the version to boot
102 | """
103 | if (version not in VERSIONS):
104 | raise ValueError(BColors.WARNING + 'This version doesn\'t exist. Please retry.' + BColors.ENDC)
105 |
106 | if version == 'ckar':
107 | version = 'ckalculator'
108 | module = importlib.import_module(version)
109 | version = getattr(module, version)
110 | eval(version.main(ar_hook=True))
111 | else:
112 | module = importlib.import_module(version)
113 | version = getattr(module, version)
114 | eval(version.main())
115 |
116 | if __name__ == '__main__':
117 | """
118 | Catch the arguments that were used to start this function.
119 |
120 | Options are h, c, p, t, r
121 | """
122 |
123 | showHelp = False
124 | test = False
125 | record = False
126 | config = None
127 | play = None
128 |
129 | try:
130 | options, args = getopt.getopt(sys.argv[1:],'h:p:i:rt',['help', 'play=', 'ini=', 'rec', 'test'])
131 | selected_options = [x[0] for x in options]
132 |
133 | for o, a in options:
134 | if o in ('-h', '--help'):
135 | showHelp = True
136 | if o in ('-p', '--play'):
137 | play = a
138 | if o in ('-i', '--ini'):
139 | config = a
140 | if o in ('-t', '--test'):
141 | test = True
142 | if o in ('-r', '--rec'):
143 | record = True
144 |
145 | except getopt.GetoptError:
146 | print('Something went wrong parsing the optional arguments')
147 |
148 | if showHelp:
149 | doHelp()
150 | sys.exit(0)
151 |
152 | if config == None:
153 | CK_config.inifile = 'default_setup.ini'
154 | else:
155 | CK_config.inifile = config
156 |
157 | if test:
158 | miditest(configfile=CK_config.inifile)
159 | sys.exit(0)
160 |
161 | if record:
162 | rec = CK_Rec(configfile=CK_config.inifile)
163 | rec.record(framesize=1)
164 | sys.exit(0)
165 |
166 | if play:
167 | boot(configfile=config, version=play)
168 | sys.exit(0)
169 |
170 | #no arguments -> print help
171 | doHelp()
172 | sys.exit(0)
173 |
174 |
175 |
--------------------------------------------------------------------------------
/doc/build/html/RunCodeKlavier.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Run codeklavier — CodeKlavier 0.3.0 documentation
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
To help you run CodeKlavier, we have made a “run all” master wrapper script. It is in the CodeKlavier root directory and it is called codeklavier.py. You can run it by typng ./codeklavier.py-i and the script will start in interactive mode. Run ./codeklavier.py--help to get more help.
Make sure you set the pythonpath before you start the script You can set the pythonpath by runnin .setPythonPath.sh from the root CodeKlavier directory (note the dot-space at the beginning) or add the pythonpath to your bash_profile.
105 |
109 |
110 |
--------------------------------------------------------------------------------
/doc/source/conf.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 | #
4 | # CodeKlavier documentation build configuration file, created by
5 | # sphinx-quickstart on Thu Feb 1 22:04:39 2018.
6 | #
7 | # This file is execfile()d with the current directory set to its
8 | # containing dir.
9 | #
10 | # Note that not all possible configuration values are present in this
11 | # autogenerated file.
12 | #
13 | # All configuration values have a default; values that are commented out
14 | # serve to show the default.
15 |
16 | # If extensions (or modules to document with autodoc) are in another directory,
17 | # add these directories to sys.path here. If the directory is relative to the
18 | # documentation root, use os.path.abspath to make it absolute, like shown here.
19 | #
20 | import os
21 | import sys
22 | sys.path.insert(0, os.path.abspath('.'))
23 | sys.path.insert(0, os.path.abspath('../../'))
24 |
25 |
26 | # -- General configuration ------------------------------------------------
27 |
28 | # If your documentation needs a minimal Sphinx version, state it here.
29 | #
30 | # needs_sphinx = '1.0'
31 |
32 | # Add any Sphinx extension module names here, as strings. They can be
33 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
34 | # ones.
35 | extensions = ['sphinx.ext.autodoc',
36 | 'sphinx.ext.githubpages']
37 |
38 | # Add any paths that contain templates here, relative to this directory.
39 | templates_path = ['_templates']
40 |
41 | # The suffix(es) of source filenames.
42 | # You can specify multiple suffix as a list of string:
43 | #
44 | # source_suffix = ['.rst', '.md']
45 | source_suffix = '.rst'
46 |
47 | # The master toctree document.
48 | master_doc = 'index'
49 |
50 | # General information about the project.
51 | project = 'CodeKlavier'
52 | copyright = '2018, CodeKlavier Team'
53 | author = 'CodeKlavier Team'
54 |
55 | # The version info for the project you're documenting, acts as replacement for
56 | # |version| and |release|, also used in various other places throughout the
57 | # built documents.
58 | #
59 | # The short X.Y version.
60 | version = '0.3'
61 | # The full version, including alpha/beta/rc tags.
62 | release = '0.3.0'
63 |
64 | # The language for content autogenerated by Sphinx. Refer to documentation
65 | # for a list of supported languages.
66 | #
67 | # This is also used if you do content translation via gettext catalogs.
68 | # Usually you set "language" from the command line for these cases.
69 | language = None
70 |
71 | # List of patterns, relative to source directory, that match files and
72 | # directories to ignore when looking for source files.
73 | # This patterns also effect to html_static_path and html_extra_path
74 | exclude_patterns = []
75 |
76 | # The name of the Pygments (syntax highlighting) style to use.
77 | pygments_style = 'sphinx'
78 |
79 | # If true, `todo` and `todoList` produce output, else they produce nothing.
80 | todo_include_todos = False
81 |
82 |
83 | # -- Options for HTML output ----------------------------------------------
84 |
85 | # The theme to use for HTML and HTML Help pages. See the documentation for
86 | # a list of builtin themes.
87 | #
88 | html_theme = 'alabaster'
89 | html_theme = "classic"
90 | html_theme = "bizstyle"
91 |
92 | # Theme options are theme-specific and customize the look and feel of a theme
93 | # further. For a list of options available for each theme, see the
94 | # documentation.
95 | #
96 | # html_theme_options = {}
97 |
98 | # Add any paths that contain custom static files (such as style sheets) here,
99 | # relative to this directory. They are copied after the builtin static files,
100 | # so a file named "default.css" will overwrite the builtin "default.css".
101 | html_static_path = ['_static']
102 |
103 | # Custom sidebar templates, must be a dictionary that maps document names
104 | # to template names.
105 | #
106 | # This is required for the alabaster theme
107 | # refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
108 | html_sidebars = {
109 | '**': [
110 | 'relations.html', # needs 'show_related': True theme option to display
111 | 'searchbox.html',
112 | ]
113 | }
114 |
115 |
116 | # -- Options for HTMLHelp output ------------------------------------------
117 |
118 | # Output file base name for HTML help builder.
119 | htmlhelp_basename = 'CodeKlavierdoc'
120 |
121 | html_show_sourcelink = False
122 | html_copy_source = False
123 |
124 |
125 | # -- Options for LaTeX output ---------------------------------------------
126 |
127 | latex_elements = {
128 | # The paper size ('letterpaper' or 'a4paper').
129 | #
130 | # 'papersize': 'letterpaper',
131 |
132 | # The font size ('10pt', '11pt' or '12pt').
133 | #
134 | # 'pointsize': '10pt',
135 |
136 | # Additional stuff for the LaTeX preamble.
137 | #
138 | # 'preamble': '',
139 |
140 | # Latex figure (float) alignment
141 | #
142 | # 'figure_align': 'htbp',
143 | }
144 |
145 | # Grouping the document tree into LaTeX files. List of tuples
146 | # (source start file, target name, title,
147 | # author, documentclass [howto, manual, or own class]).
148 | latex_documents = [
149 | (master_doc, 'CodeKlavier.tex', 'CodeKlavier Documentation',
150 | 'CodeKlavier Team', 'manual'),
151 | ]
152 |
153 |
154 | # -- Options for manual page output ---------------------------------------
155 |
156 | # One entry per manual page. List of tuples
157 | # (source start file, name, description, authors, manual section).
158 | man_pages = [
159 | (master_doc, 'codeklavier', 'CodeKlavier Documentation',
160 | [author], 1)
161 | ]
162 |
163 |
164 | # -- Options for Texinfo output -------------------------------------------
165 |
166 | # Grouping the document tree into Texinfo files. List of tuples
167 | # (source start file, target name, title, author,
168 | # dir menu entry, description, category)
169 | texinfo_documents = [
170 | (master_doc, 'CodeKlavier', 'CodeKlavier Documentation',
171 | author, 'CodeKlavier', 'One line description of project.',
172 | 'Miscellaneous'),
173 | ]
174 |
--------------------------------------------------------------------------------
/doc/build/html/modules.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | CodeKlavier — CodeKlavier 0.3.0 documentation
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
134 |
138 |
139 |
--------------------------------------------------------------------------------
/easter eggs:
--------------------------------------------------------------------------------
1 | # midinumber : easteregg text ICLC
2 | 9: Average number of times we pkill scsynth in a CK session
3 | 11: Number of functions in our CKalculator
4 | 16: This is our CodeKlavier's 16th performance
5 | 38: Number of performances at this ICLC
6 | 47: Click Nilson's lifetime
7 | 184: Number of past Alogiraves listed on algorave.com
8 | 190: Keys on stage
9 | 239: CK followers on facebook - you should like us now!
10 | 532: Days since CodeKlavier's first public performance
11 | 660: Days of working on the CodeKlavier
12 | 860: Madrid was founded in this year
13 | 1126: Approximate number of km that we are currently above sea level
14 | 1700: The piano has been around since then
15 | 1930: Year lambda calculus was first introduced by Alonso Church
16 | 1960: Year that lambda calculus gained place in computer science and linguistics
17 | 1982: Felipe was born
18 | 1986: Anne was born
19 |
20 | # midinumber : easteregg text Lambda Days
21 |
22 | 9: Average number of times we pkill scsynth in a CK session
23 | 17: This is CodeKlavier's 17th performance
24 | 38: Number of talks at Lambda Days this year
25 | 40: Pages in the current draft of a history of F#
26 | 105: Krakow's tallest building in meters.
27 | 190: Keys on stage
28 | 220: Approximate number of km that we are currently above sea level
29 | 234: CK followers on facebook - you should like us now!
30 | 327: Krakow's total city area in meters2.
31 | 564: Days since CodeKlavier's first public performance
32 | 643: Number of braces in F#
33 | 691: Days of working on the CodeKlavier
34 | 1700: The piano has been around since then
35 | 1860: Ignacy Jan Paderewski - the only pianist, composer and active politician was born.
36 | 1903: Alonzo Church was born
37 | 1910: The first volume of Principia Mathematica by Russel and White was published in this year
38 | 1912: The second volume of Principia Mathematica by Russel and White was published in this year.
39 | 1913: The third volume of Principia Mathematica by Russel and White was published in this year.
40 | 1930: Year lambda calculus was first introduced by Alonso Church
41 | 1960: Year that lambda calculus gained place in computer science and linguistics
42 | 1982: Felipe was born
43 | 1986: Anne was born
44 | 1990: Haskell first appeared.
45 | 1995: JavaScript was invented by Brendan Eich
46 | 1999: Erlang was founded
47 | 2009: Idris appeared.
48 | 2020: HOPL IV submission year
49 | 3011: Null checks in the C# project described by Don Syme
50 |
51 | Easter Eggs Lambda
52 | [easter eggs]
53 | # midinumber : easteregg text
54 | 9: Average number of times we pkill scsynth in a CK session
55 | 17: This is CodeKlavier's 17th performance
56 | 38: Number of talks at Lambda Days this year
57 | 105: Krakow's tallest building in meters.
58 | 190: Keys on stage
59 | 220: Approximate number of km that we are currently above sea level
60 | 234: CK followers on facebook - you should like us now!
61 | 327: Krakow's total city area in meters2.
62 | 564: Days since CodeKlavier's first public performance
63 | 643: Number of braces in F#
64 | 691: Days of working on the CodeKlavier
65 | 1700: The piano has been around since then
66 | 1860: Ignacy Jan Paderewski - the only pianist, composer and active politician was born.
67 | 1903: Alonzo Church was born
68 | 1910: The first volume of Principia Mathematica by Russel and White was published in this year
69 | 1912: The second volume of Principia Mathematica by Russel and White was published in this year.
70 | 1913: The third volume of Principia Mathematica by Russel and White was published in this year.
71 | 11: Number of functions in our CKalculator
72 | 16: This is our CodeKlavier's 16th performance
73 | 47: Click Nilson's lifetime
74 | 184: Number of past Alogiraves listed on algorave.com
75 | 239: CK followers on facebook - you should like us now!
76 | 532: Days since CodeKlavier's first public performance
77 | 660: Days of working on the CodeKlavier
78 | 860: Madrid was founded in this year
79 | 1126: Approximate number of km that we are currently above sea level
80 | 1930: Year lambda calculus was first introduced by Alonso Church
81 | 1960: Year that lambda calculus gained place in computer science and linguistics
82 | 1982: Felipe was born
83 | 1986: Anne was born
84 | 1990: Haskell first appeared.
85 | 1995: JavaScript was invented by Brendan Eich
86 | 1999: Erlang was founded
87 | 2009: Idris appeared.
88 | 2020: HOPL IV submission year
89 | 3011: Null checks in the C# project described by Don Syme
90 |
91 | EasterEggs- soup
92 | 8: Ingredients in vegan asparugus soup - olive oil, garlic, asparagus, gold potatoes,salt, pepper, vegetable broth.
93 | 9: Average number of times we pkill scsynth in a CK session
94 | 11: Number of lambda functions in our CKalculator
95 | 17: Years since the first residents moved to Ijburg
96 | 18: This is CodeKlavier's 18th performance
97 | 47: Click Nilson's lifetime
98 | 190: Keys on stage
99 | 220: Area of Ijburg in ha
100 | 251: CK followers on facebook - you should like us now!
101 | 652: Days since CodeKlavier's first public performance
102 | 778: Days of working on the CodeKlavier
103 | 1700: The piano has been around since then
104 | 1903: Alonzo Church was born
105 | 1910: The first volume of Principia Mathematica by Russel and White was published in this year
106 | 1912: The second volume of Principia Mathematica by Russel and White was published in this year.
107 | 1913: The third volume of Principia Mathematica by Russel and White was published in this year.
108 | 1930: Year lambda calculus was first introduced by Alonso Church
109 | 1960: Year that lambda calculus gained place in computer science and linguistics
110 | 1982: Felipe was born
111 | 1986: Anne was born
112 | 1990: Haskell first appeared.
113 | 1995: "No soup for you". Also, JavaScript was invented by Brendan Eich.
114 | 1999: Erlang was founded
115 | 2009: Idris appeared.
116 | 2020: HOPL IV submission year
117 | 6000: The earliest archaeological evidence for the consumption of soup dates back to 6000 BC, and it was hippopotamus soup.
118 |
119 | Easter Eggs YAA
120 | 5: Number of YAA prize winners in 2018
121 | 9: Average number of times we pkill scsynth in a CK session
122 | 11: Number of lambda functions in our CKalculator
123 | 16: Weeks it takes for a fetus to drink and pee
124 | 19: This is CodeKlavier's 19th performance
125 | 178: Years since Arti was built
126 | 190: Keys on stage
127 | 251: CK followers on facebook - you should like us now!
128 | 657: Days since CodeKlavier's first public performance
129 | 785: Days of working on the CodeKlavier
130 | 1700: The piano has been around since then
131 | 1903: Alonzo Church was born
132 | 1910: The first volume of Principia Mathematica by Russel and White was published in this year
133 | 1912: The second volume of Principia Mathematica by Russel and White was published in this year.
134 | 1913: The third volume of Principia Mathematica by Russel and White was published in this year.
135 | 1930: Year lambda calculus was first introduced by Alonso Church
136 | 1960: Year that lambda calculus gained place in computer science and linguistics
137 | 1982: Felipe was born
138 | 1986: Anne was born
139 | 1990: Haskell first appeared.
140 | 1995: JavaScript was invented by Brendan Eich.
141 | 1999: Erlang was founded
142 | 2009: Idris appeared.
143 | 2011: Felipe and Anne met during their studies at CVA
144 | 2012: YAA was founded
145 | 2015: Year that Felipe won the YAA
146 | 2020: HOPL IV submission year
147 |
--------------------------------------------------------------------------------