Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Config.py599
-rwxr-xr-xcommon/Generation/Drunk.py162
-rwxr-xr-xcommon/Generation/GenerationConstants.py184
-rwxr-xr-xcommon/Generation/GenerationParametersWindow.py383
-rw-r--r--common/Generation/GenerationPitch.py40
-rw-r--r--common/Generation/GenerationRythm.py213
-rwxr-xr-xcommon/Generation/Generator.py167
-rwxr-xr-xcommon/Generation/Utils.py74
-rw-r--r--common/Generation/VariationPitch.py82
-rw-r--r--common/Generation/VariationRythm.py74
-rw-r--r--common/Generation/__init__.py0
-rw-r--r--common/Generation/bList.py97
-rw-r--r--common/Resources/Desktops/desktop0206
-rw-r--r--common/Resources/Desktops/desktop1206
-rw-r--r--common/Resources/Desktops/desktop2206
-rw-r--r--common/Resources/Desktops/desktop3206
-rw-r--r--common/Resources/Desktops/desktop4206
-rw-r--r--common/Resources/Desktops/desktop5206
-rw-r--r--common/Resources/Desktops/desktop6206
-rw-r--r--common/Resources/Desktops/desktop7206
-rw-r--r--common/Resources/Desktops/desktop8206
-rw-r--r--common/Resources/Desktops/desktop9206
-rw-r--r--common/Resources/Images/TamTam.pngbin0 -> 12771 bytes
-rw-r--r--common/Resources/Images/acguit.pngbin0 -> 10779 bytes
-rw-r--r--common/Resources/Images/acguitsel.pngbin0 -> 9552 bytes
-rwxr-xr-xcommon/Resources/Images/alarm.pngbin0 -> 8794 bytes
-rwxr-xr-xcommon/Resources/Images/alarmsel.pngbin0 -> 8302 bytes
-rw-r--r--common/Resources/Images/all.pngbin0 -> 13361 bytes
-rw-r--r--common/Resources/Images/allsel.pngbin0 -> 14000 bytes
-rw-r--r--common/Resources/Images/animals.pngbin0 -> 15944 bytes
-rw-r--r--common/Resources/Images/animalssel.pngbin0 -> 16536 bytes
-rwxr-xr-xcommon/Resources/Images/arrowEditDown.pngbin0 -> 3058 bytes
-rwxr-xr-xcommon/Resources/Images/arrowEditDownDown.pngbin0 -> 3037 bytes
-rwxr-xr-xcommon/Resources/Images/arrowEditDownOver.pngbin0 -> 3058 bytes
-rw-r--r--common/Resources/Images/arrowEditLeft.pngbin0 -> 456 bytes
-rwxr-xr-xcommon/Resources/Images/arrowEditLeftDown.pngbin0 -> 3003 bytes
-rwxr-xr-xcommon/Resources/Images/arrowEditLeftOver.pngbin0 -> 3058 bytes
-rw-r--r--common/Resources/Images/arrowEditRight.pngbin0 -> 454 bytes
-rwxr-xr-xcommon/Resources/Images/arrowEditRightDown.pngbin0 -> 3014 bytes
-rwxr-xr-xcommon/Resources/Images/arrowEditRightOver.pngbin0 -> 3049 bytes
-rwxr-xr-xcommon/Resources/Images/arrowEditUp.pngbin0 -> 3045 bytes
-rwxr-xr-xcommon/Resources/Images/arrowEditUpDown.pngbin0 -> 3030 bytes
-rwxr-xr-xcommon/Resources/Images/arrowEditUpOver.pngbin0 -> 3046 bytes
-rw-r--r--common/Resources/Images/basse.pngbin0 -> 9265 bytes
-rw-r--r--common/Resources/Images/bassesel.pngbin0 -> 7934 bytes
-rw-r--r--common/Resources/Images/beat1.pngbin0 -> 679 bytes
-rw-r--r--common/Resources/Images/beat10.pngbin0 -> 1003 bytes
-rw-r--r--common/Resources/Images/beat11.pngbin0 -> 722 bytes
-rw-r--r--common/Resources/Images/beat2.pngbin0 -> 672 bytes
-rw-r--r--common/Resources/Images/beat3.pngbin0 -> 620 bytes
-rw-r--r--common/Resources/Images/beat4.pngbin0 -> 984 bytes
-rw-r--r--common/Resources/Images/beat5.pngbin0 -> 651 bytes
-rw-r--r--common/Resources/Images/beat6.pngbin0 -> 947 bytes
-rw-r--r--common/Resources/Images/beat7.pngbin0 -> 663 bytes
-rw-r--r--common/Resources/Images/beat8.pngbin0 -> 721 bytes
-rw-r--r--common/Resources/Images/beat9.pngbin0 -> 1005 bytes
-rw-r--r--common/Resources/Images/bird.pngbin0 -> 9311 bytes
-rw-r--r--common/Resources/Images/birdsel.pngbin0 -> 8048 bytes
-rw-r--r--common/Resources/Images/bottle.pngbin0 -> 8387 bytes
-rw-r--r--common/Resources/Images/bottlesel.pngbin0 -> 7674 bytes
-rwxr-xr-xcommon/Resources/Images/bubbles.pngbin0 -> 9571 bytes
-rwxr-xr-xcommon/Resources/Images/bubblessel.pngbin0 -> 8695 bytes
-rwxr-xr-xcommon/Resources/Images/byke.pngbin0 -> 14257 bytes
-rwxr-xr-xcommon/Resources/Images/bykesel.pngbin0 -> 12502 bytes
-rwxr-xr-xcommon/Resources/Images/camera.pngbin0 -> 9598 bytes
-rwxr-xr-xcommon/Resources/Images/camerasel.pngbin0 -> 9467 bytes
-rwxr-xr-xcommon/Resources/Images/car.pngbin0 -> 7720 bytes
-rwxr-xr-xcommon/Resources/Images/carsel.pngbin0 -> 7354 bytes
-rw-r--r--common/Resources/Images/cat.pngbin0 -> 13255 bytes
-rw-r--r--common/Resources/Images/catsel.pngbin0 -> 12546 bytes
-rwxr-xr-xcommon/Resources/Images/cello.pngbin0 -> 12080 bytes
-rwxr-xr-xcommon/Resources/Images/cellosel.pngbin0 -> 10904 bytes
-rw-r--r--common/Resources/Images/check.pngbin0 -> 1862 bytes
-rw-r--r--common/Resources/Images/checkOff.svg7
-rw-r--r--common/Resources/Images/checkOn.svg14
-rwxr-xr-xcommon/Resources/Images/chimes.pngbin0 -> 8878 bytes
-rwxr-xr-xcommon/Resources/Images/chimessel.pngbin0 -> 8340 bytes
-rw-r--r--common/Resources/Images/clang.pngbin0 -> 10702 bytes
-rw-r--r--common/Resources/Images/clangsel.pngbin0 -> 10306 bytes
-rw-r--r--common/Resources/Images/clarinette.pngbin0 -> 5628 bytes
-rw-r--r--common/Resources/Images/clarinettesel.pngbin0 -> 4700 bytes
-rw-r--r--common/Resources/Images/cling.pngbin0 -> 14855 bytes
-rw-r--r--common/Resources/Images/clingsel.pngbin0 -> 13973 bytes
-rw-r--r--common/Resources/Images/complex1.pngbin0 -> 2084 bytes
-rw-r--r--common/Resources/Images/complex2.pngbin0 -> 1930 bytes
-rw-r--r--common/Resources/Images/complex3.pngbin0 -> 1862 bytes
-rw-r--r--common/Resources/Images/complex4.pngbin0 -> 1914 bytes
-rw-r--r--common/Resources/Images/complex5.pngbin0 -> 1890 bytes
-rw-r--r--common/Resources/Images/complex6.pngbin0 -> 1912 bytes
-rw-r--r--common/Resources/Images/complex7.pngbin0 -> 1938 bytes
-rw-r--r--common/Resources/Images/complex8.pngbin0 -> 1791 bytes
-rw-r--r--common/Resources/Images/concret.pngbin0 -> 9928 bytes
-rw-r--r--common/Resources/Images/concretsel.pngbin0 -> 10472 bytes
-rwxr-xr-xcommon/Resources/Images/crash.pngbin0 -> 8027 bytes
-rwxr-xr-xcommon/Resources/Images/crashsel.pngbin0 -> 7362 bytes
-rw-r--r--common/Resources/Images/dice.pngbin0 -> 11085 bytes
-rw-r--r--common/Resources/Images/diceProp.pngbin0 -> 2613 bytes
-rw-r--r--common/Resources/Images/dicePropSel.pngbin0 -> 2721 bytes
-rw-r--r--common/Resources/Images/diceblur.pngbin0 -> 13327 bytes
-rw-r--r--common/Resources/Images/diceinst.pngbin0 -> 8634 bytes
-rw-r--r--common/Resources/Images/diceinstsel.pngbin0 -> 8003 bytes
-rw-r--r--common/Resources/Images/didjeridu.pngbin0 -> 9087 bytes
-rw-r--r--common/Resources/Images/didjeridusel.pngbin0 -> 8296 bytes
-rw-r--r--common/Resources/Images/dog.pngbin0 -> 12824 bytes
-rw-r--r--common/Resources/Images/dogsel.pngbin0 -> 12298 bytes
-rw-r--r--common/Resources/Images/door.pngbin0 -> 10469 bytes
-rw-r--r--common/Resources/Images/doorsel.pngbin0 -> 10272 bytes
-rwxr-xr-xcommon/Resources/Images/dru0.pngbin0 -> 2313 bytes
-rwxr-xr-xcommon/Resources/Images/dru1.pngbin0 -> 2708 bytes
-rwxr-xr-xcommon/Resources/Images/dru2.pngbin0 -> 3293 bytes
-rwxr-xr-xcommon/Resources/Images/dru3.pngbin0 -> 4062 bytes
-rwxr-xr-xcommon/Resources/Images/dru4.pngbin0 -> 5015 bytes
-rw-r--r--common/Resources/Images/drum1kit.pngbin0 -> 14900 bytes
-rw-r--r--common/Resources/Images/drum1kitsel.pngbin0 -> 13729 bytes
-rw-r--r--common/Resources/Images/drum1kitselgen.pngbin0 -> 13887 bytes
-rw-r--r--common/Resources/Images/drum2kit.pngbin0 -> 14882 bytes
-rw-r--r--common/Resources/Images/drum2kitsel.pngbin0 -> 13869 bytes
-rw-r--r--common/Resources/Images/drum2kitselgen.pngbin0 -> 13964 bytes
-rw-r--r--common/Resources/Images/drum3kit.pngbin0 -> 15880 bytes
-rw-r--r--common/Resources/Images/drum3kitsel.pngbin0 -> 14679 bytes
-rw-r--r--common/Resources/Images/drum3kitselgen.pngbin0 -> 14801 bytes
-rw-r--r--common/Resources/Images/drum4kit.pngbin0 -> 12904 bytes
-rw-r--r--common/Resources/Images/drum4kitsel.pngbin0 -> 10888 bytes
-rw-r--r--common/Resources/Images/drum4kitselgen.pngbin0 -> 11047 bytes
-rw-r--r--common/Resources/Images/drum5kit.pngbin0 -> 14999 bytes
-rw-r--r--common/Resources/Images/drum5kitsel.pngbin0 -> 13580 bytes
-rw-r--r--common/Resources/Images/drum5kitselgen.pngbin0 -> 13712 bytes
-rw-r--r--common/Resources/Images/duck.pngbin0 -> 9694 bytes
-rw-r--r--common/Resources/Images/duck2.pngbin0 -> 11299 bytes
-rw-r--r--common/Resources/Images/duck2sel.pngbin0 -> 8960 bytes
-rw-r--r--common/Resources/Images/ducksel.pngbin0 -> 8652 bytes
-rw-r--r--common/Resources/Images/editTam.pngbin0 -> 10701 bytes
-rw-r--r--common/Resources/Images/editTamDown.pngbin0 -> 11789 bytes
-rw-r--r--common/Resources/Images/editTamOver.pngbin0 -> 9958 bytes
-rw-r--r--common/Resources/Images/electronic.pngbin0 -> 12476 bytes
-rw-r--r--common/Resources/Images/electronicsel.pngbin0 -> 13161 bytes
-rw-r--r--common/Resources/Images/flute.pngbin0 -> 6248 bytes
-rw-r--r--common/Resources/Images/flutesel.pngbin0 -> 5266 bytes
-rw-r--r--common/Resources/Images/gam.pngbin0 -> 12581 bytes
-rw-r--r--common/Resources/Images/gamsel.pngbin0 -> 11893 bytes
-rwxr-xr-xcommon/Resources/Images/generic.pngbin0 -> 8768 bytes
-rwxr-xr-xcommon/Resources/Images/genericsel.pngbin0 -> 8015 bytes
-rw-r--r--common/Resources/Images/guit.pngbin0 -> 9996 bytes
-rwxr-xr-xcommon/Resources/Images/guit2.pngbin0 -> 8352 bytes
-rwxr-xr-xcommon/Resources/Images/guit2sel.pngbin0 -> 7611 bytes
-rw-r--r--common/Resources/Images/guitsel.pngbin0 -> 8589 bytes
-rw-r--r--common/Resources/Images/harmonica.pngbin0 -> 9120 bytes
-rw-r--r--common/Resources/Images/harmonicasel.pngbin0 -> 8638 bytes
-rw-r--r--common/Resources/Images/harmonium.pngbin0 -> 13371 bytes
-rw-r--r--common/Resources/Images/harmoniumsel.pngbin0 -> 12936 bytes
-rwxr-xr-xcommon/Resources/Images/helpShow1.jpgbin0 -> 32969 bytes
-rwxr-xr-xcommon/Resources/Images/helpShow2.jpgbin0 -> 87871 bytes
-rwxr-xr-xcommon/Resources/Images/helpShow3.jpgbin0 -> 79367 bytes
-rwxr-xr-xcommon/Resources/Images/helpShow4.jpgbin0 -> 85694 bytes
-rwxr-xr-xcommon/Resources/Images/helpShow5.jpgbin0 -> 75364 bytes
-rwxr-xr-xcommon/Resources/Images/helpShow6.jpgbin0 -> 60244 bytes
-rwxr-xr-xcommon/Resources/Images/helpShow7.jpgbin0 -> 52708 bytes
-rwxr-xr-xcommon/Resources/Images/helpShow8.jpgbin0 -> 70312 bytes
-rwxr-xr-xcommon/Resources/Images/helpShow9.jpgbin0 -> 52295 bytes
-rw-r--r--common/Resources/Images/helpTam.pngbin0 -> 11789 bytes
-rw-r--r--common/Resources/Images/helpTamDown.pngbin0 -> 10701 bytes
-rw-r--r--common/Resources/Images/helpTamOver.pngbin0 -> 9958 bytes
-rw-r--r--common/Resources/Images/hit.pngbin0 -> 973 bytes
-rw-r--r--common/Resources/Images/hitSelected.pngbin0 -> 1171 bytes
-rw-r--r--common/Resources/Images/horse.pngbin0 -> 15048 bytes
-rw-r--r--common/Resources/Images/horsesel.pngbin0 -> 13520 bytes
-rwxr-xr-xcommon/Resources/Images/instr0.pngbin0 -> 1700 bytes
-rwxr-xr-xcommon/Resources/Images/instr1.pngbin0 -> 2032 bytes
-rwxr-xr-xcommon/Resources/Images/instr2.pngbin0 -> 2350 bytes
-rwxr-xr-xcommon/Resources/Images/instr3.pngbin0 -> 2748 bytes
-rwxr-xr-xcommon/Resources/Images/instr4.pngbin0 -> 3212 bytes
-rw-r--r--common/Resources/Images/jam-blockMask.pngbin0 -> 4242 bytes
-rw-r--r--common/Resources/Images/kalimba.pngbin0 -> 10500 bytes
-rw-r--r--common/Resources/Images/kalimbasel.pngbin0 -> 9964 bytes
-rw-r--r--common/Resources/Images/keyboard.pngbin0 -> 5602 bytes
-rw-r--r--common/Resources/Images/keyboardsel.pngbin0 -> 6201 bytes
-rw-r--r--common/Resources/Images/koto.pngbin0 -> 9666 bytes
-rw-r--r--common/Resources/Images/kotosel.pngbin0 -> 8872 bytes
-rw-r--r--common/Resources/Images/laugh.pngbin0 -> 14044 bytes
-rw-r--r--common/Resources/Images/laughsel.pngbin0 -> 13332 bytes
-rw-r--r--common/Resources/Images/mando.pngbin0 -> 8705 bytes
-rw-r--r--common/Resources/Images/mandosel.pngbin0 -> 7728 bytes
-rw-r--r--common/Resources/Images/marimba.pngbin0 -> 14598 bytes
-rw-r--r--common/Resources/Images/marimbasel.pngbin0 -> 13469 bytes
-rw-r--r--common/Resources/Images/marquis.pngbin0 -> 1341 bytes
-rw-r--r--common/Resources/Images/mic1.pngbin0 -> 4231 bytes
-rw-r--r--common/Resources/Images/mic1sel.pngbin0 -> 3988 bytes
-rw-r--r--common/Resources/Images/mic2.pngbin0 -> 4365 bytes
-rw-r--r--common/Resources/Images/mic2sel.pngbin0 -> 4122 bytes
-rw-r--r--common/Resources/Images/mic3.pngbin0 -> 4375 bytes
-rw-r--r--common/Resources/Images/mic3sel.pngbin0 -> 4145 bytes
-rw-r--r--common/Resources/Images/mic4.pngbin0 -> 4225 bytes
-rw-r--r--common/Resources/Images/mic4sel.pngbin0 -> 4062 bytes
-rw-r--r--common/Resources/Images/miniTam.pngbin0 -> 30569 bytes
-rw-r--r--common/Resources/Images/miniTamDown.pngbin0 -> 36042 bytes
-rw-r--r--common/Resources/Images/miniTamOver.pngbin0 -> 33015 bytes
-rw-r--r--common/Resources/Images/miniplay.pngbin0 -> 970 bytes
-rw-r--r--common/Resources/Images/mysounds.pngbin0 -> 7908 bytes
-rw-r--r--common/Resources/Images/mysoundssel.pngbin0 -> 8350 bytes
-rw-r--r--common/Resources/Images/note.pngbin0 -> 1034 bytes
-rw-r--r--common/Resources/Images/noteSelected.pngbin0 -> 1281 bytes
-rw-r--r--common/Resources/Images/ocarina.pngbin0 -> 6891 bytes
-rw-r--r--common/Resources/Images/ocarinasel.pngbin0 -> 6601 bytes
-rw-r--r--common/Resources/Images/ounk.pngbin0 -> 12569 bytes
-rw-r--r--common/Resources/Images/ounksel.pngbin0 -> 11792 bytes
-rw-r--r--common/Resources/Images/ow.pngbin0 -> 13340 bytes
-rw-r--r--common/Resources/Images/owsel.pngbin0 -> 12320 bytes
-rw-r--r--common/Resources/Images/pageThumbnailBG.pngbin0 -> 1154 bytes
-rw-r--r--common/Resources/Images/pageThumbnailBG0.pngbin0 -> 1068 bytes
-rw-r--r--common/Resources/Images/pageThumbnailBG1.pngbin0 -> 1073 bytes
-rw-r--r--common/Resources/Images/pageThumbnailBG2.pngbin0 -> 1037 bytes
-rw-r--r--common/Resources/Images/pageThumbnailBG3.pngbin0 -> 1094 bytes
-rwxr-xr-xcommon/Resources/Images/pageThumbnailBut0.pngbin0 -> 927 bytes
-rwxr-xr-xcommon/Resources/Images/pageThumbnailBut0Down.pngbin0 -> 945 bytes
-rwxr-xr-xcommon/Resources/Images/pageThumbnailBut1.pngbin0 -> 917 bytes
-rwxr-xr-xcommon/Resources/Images/pageThumbnailBut1Down.pngbin0 -> 937 bytes
-rwxr-xr-xcommon/Resources/Images/pageThumbnailBut2.pngbin0 -> 919 bytes
-rwxr-xr-xcommon/Resources/Images/pageThumbnailBut2Down.pngbin0 -> 944 bytes
-rwxr-xr-xcommon/Resources/Images/pageThumbnailBut3.pngbin0 -> 916 bytes
-rwxr-xr-xcommon/Resources/Images/pageThumbnailBut3Down.pngbin0 -> 934 bytes
-rw-r--r--common/Resources/Images/pageThumbnailMask.pngbin0 -> 500 bytes
-rw-r--r--common/Resources/Images/people.pngbin0 -> 17115 bytes
-rw-r--r--common/Resources/Images/peoplesel.pngbin0 -> 17596 bytes
-rw-r--r--common/Resources/Images/percussions.pngbin0 -> 15245 bytes
-rw-r--r--common/Resources/Images/percussionssel.pngbin0 -> 15815 bytes
-rw-r--r--common/Resources/Images/piano.pngbin0 -> 11422 bytes
-rw-r--r--common/Resources/Images/pianosel.pngbin0 -> 10785 bytes
-rwxr-xr-xcommon/Resources/Images/plane.pngbin0 -> 12105 bytes
-rwxr-xr-xcommon/Resources/Images/planesel.pngbin0 -> 10920 bytes
-rw-r--r--common/Resources/Images/reverb0.pngbin0 -> 890 bytes
-rw-r--r--common/Resources/Images/reverb1.pngbin0 -> 888 bytes
-rw-r--r--common/Resources/Images/reverb2.pngbin0 -> 939 bytes
-rw-r--r--common/Resources/Images/reverb3.pngbin0 -> 992 bytes
-rw-r--r--common/Resources/Images/reverb4.pngbin0 -> 1035 bytes
-rw-r--r--common/Resources/Images/reverb5.pngbin0 -> 1090 bytes
-rw-r--r--common/Resources/Images/rhodes.pngbin0 -> 10014 bytes
-rw-r--r--common/Resources/Images/rhodessel.pngbin0 -> 8396 bytes
-rw-r--r--common/Resources/Images/sampleBG.pngbin0 -> 36405 bytes
-rw-r--r--common/Resources/Images/sampleNoteMask.pngbin0 -> 2963 bytes
-rw-r--r--common/Resources/Images/saxo.pngbin0 -> 8445 bytes
-rw-r--r--common/Resources/Images/saxosel.pngbin0 -> 7424 bytes
-rw-r--r--common/Resources/Images/scrollBar.pngbin0 -> 584 bytes
-rw-r--r--common/Resources/Images/sheep.pngbin0 -> 11805 bytes
-rw-r--r--common/Resources/Images/sheepsel.pngbin0 -> 10623 bytes
-rw-r--r--common/Resources/Images/shenai.pngbin0 -> 6780 bytes
-rw-r--r--common/Resources/Images/shenaisel.pngbin0 -> 5808 bytes
-rw-r--r--common/Resources/Images/sitar.pngbin0 -> 9766 bytes
-rw-r--r--common/Resources/Images/sitarsel.pngbin0 -> 8536 bytes
-rwxr-xr-xcommon/Resources/Images/slap.pngbin0 -> 11935 bytes
-rwxr-xr-xcommon/Resources/Images/slapsel.pngbin0 -> 10959 bytes
-rw-r--r--common/Resources/Images/sliderDrum.pngbin0 -> 1294 bytes
-rw-r--r--common/Resources/Images/sliderEditTempo.pngbin0 -> 1272 bytes
-rw-r--r--common/Resources/Images/sliderEditVolume.pngbin0 -> 1242 bytes
-rw-r--r--common/Resources/Images/sliderInst1.pngbin0 -> 1284 bytes
-rw-r--r--common/Resources/Images/sliderInst2.pngbin0 -> 1252 bytes
-rw-r--r--common/Resources/Images/sliderInst3.pngbin0 -> 1263 bytes
-rw-r--r--common/Resources/Images/sliderInst4.pngbin0 -> 1272 bytes
-rw-r--r--common/Resources/Images/sliderbutbleu.pngbin0 -> 1744 bytes
-rw-r--r--common/Resources/Images/sliderbutjaune.pngbin0 -> 1770 bytes
-rw-r--r--common/Resources/Images/sliderbutred.pngbin0 -> 1562 bytes
-rw-r--r--common/Resources/Images/sliderbutvert.pngbin0 -> 1769 bytes
-rw-r--r--common/Resources/Images/sliderbutviolet.pngbin0 -> 1654 bytes
-rw-r--r--common/Resources/Images/sliderlong.pngbin0 -> 251 bytes
-rw-r--r--common/Resources/Images/slidershort.pngbin0 -> 244 bytes
-rw-r--r--common/Resources/Images/stop.pngbin0 -> 807 bytes
-rw-r--r--common/Resources/Images/strings.pngbin0 -> 11888 bytes
-rw-r--r--common/Resources/Images/stringssel.pngbin0 -> 12428 bytes
-rw-r--r--common/Resources/Images/synthTam.pngbin0 -> 7525 bytes
-rw-r--r--common/Resources/Images/synthTamDown.pngbin0 -> 8297 bytes
-rw-r--r--common/Resources/Images/synthTamOver.pngbin0 -> 7569 bytes
-rw-r--r--common/Resources/Images/synthlabMask.pngbin0 -> 4884 bytes
-rw-r--r--common/Resources/Images/tchiwo.pngbin0 -> 10240 bytes
-rw-r--r--common/Resources/Images/tchiwosel.pngbin0 -> 9545 bytes
-rw-r--r--common/Resources/Images/tempo1.pngbin0 -> 1546 bytes
-rw-r--r--common/Resources/Images/tempo2.pngbin0 -> 1847 bytes
-rw-r--r--common/Resources/Images/tempo3.pngbin0 -> 2354 bytes
-rw-r--r--common/Resources/Images/tempo4.pngbin0 -> 2130 bytes
-rw-r--r--common/Resources/Images/tempo5.pngbin0 -> 2733 bytes
-rw-r--r--common/Resources/Images/tempo6.pngbin0 -> 2322 bytes
-rw-r--r--common/Resources/Images/tempo7.pngbin0 -> 3351 bytes
-rw-r--r--common/Resources/Images/tempo8.pngbin0 -> 2960 bytes
-rw-r--r--common/Resources/Images/trackBG.pngbin0 -> 4740 bytes
-rw-r--r--common/Resources/Images/trackBGDrum.pngbin0 -> 5216 bytes
-rw-r--r--common/Resources/Images/trackBGDrumSelected.pngbin0 -> 4922 bytes
-rw-r--r--common/Resources/Images/trackBGSelected.pngbin0 -> 4491 bytes
-rw-r--r--common/Resources/Images/triangle.pngbin0 -> 8220 bytes
-rw-r--r--common/Resources/Images/trianglesel.pngbin0 -> 6643 bytes
-rw-r--r--common/Resources/Images/trumpet.pngbin0 -> 8326 bytes
-rw-r--r--common/Resources/Images/trumpetsel.pngbin0 -> 7294 bytes
-rw-r--r--common/Resources/Images/tuba.pngbin0 -> 10558 bytes
-rw-r--r--common/Resources/Images/tubasel.pngbin0 -> 9921 bytes
-rw-r--r--common/Resources/Images/violin.pngbin0 -> 10071 bytes
-rw-r--r--common/Resources/Images/violinsel.pngbin0 -> 8386 bytes
-rw-r--r--common/Resources/Images/voix.pngbin0 -> 11567 bytes
-rw-r--r--common/Resources/Images/voixsel.pngbin0 -> 10996 bytes
-rw-r--r--common/Resources/Images/volume0.pngbin0 -> 725 bytes
-rw-r--r--common/Resources/Images/volume1.pngbin0 -> 1034 bytes
-rw-r--r--common/Resources/Images/volume2.pngbin0 -> 1478 bytes
-rw-r--r--common/Resources/Images/volume3.pngbin0 -> 1987 bytes
-rw-r--r--common/Resources/Images/water.pngbin0 -> 14819 bytes
-rw-r--r--common/Resources/Images/watersel.pngbin0 -> 12868 bytes
-rw-r--r--common/Resources/Images/winds.pngbin0 -> 14332 bytes
-rw-r--r--common/Resources/Images/windssel.pngbin0 -> 14955 bytes
-rw-r--r--common/Resources/Images/zap.pngbin0 -> 11170 bytes
-rw-r--r--common/Resources/Images/zapsel.pngbin0 -> 12286 bytes
-rw-r--r--common/Resources/Loops/loop1.ttl5
-rw-r--r--common/Resources/Loops/loop2.ttl44
-rw-r--r--common/Resources/Loops/loop3.ttl9
-rwxr-xr-xcommon/Resources/Sounds/acguitbin0 -> 32360 bytes
-rwxr-xr-xcommon/Resources/Sounds/alarmbin0 -> 55744 bytes
-rwxr-xr-xcommon/Resources/Sounds/banjobin0 -> 32360 bytes
-rwxr-xr-xcommon/Resources/Sounds/bassebin0 -> 32516 bytes
-rwxr-xr-xcommon/Resources/Sounds/birdbin0 -> 32804 bytes
-rwxr-xr-xcommon/Resources/Sounds/bottlebin0 -> 19206 bytes
-rwxr-xr-xcommon/Resources/Sounds/bubblesbin0 -> 40364 bytes
-rwxr-xr-xcommon/Resources/Sounds/bykebin0 -> 32726 bytes
-rwxr-xr-xcommon/Resources/Sounds/camerabin0 -> 22564 bytes
-rwxr-xr-xcommon/Resources/Sounds/carbin0 -> 63940 bytes
-rwxr-xr-xcommon/Resources/Sounds/catbin0 -> 18160 bytes
-rwxr-xr-xcommon/Resources/Sounds/cellobin0 -> 24340 bytes
-rwxr-xr-xcommon/Resources/Sounds/chimesbin0 -> 107098 bytes
-rwxr-xr-xcommon/Resources/Sounds/clangbin0 -> 41150 bytes
-rwxr-xr-xcommon/Resources/Sounds/clarinettebin0 -> 31830 bytes
-rwxr-xr-xcommon/Resources/Sounds/clingbin0 -> 31758 bytes
-rwxr-xr-xcommon/Resources/Sounds/crashbin0 -> 20352 bytes
-rwxr-xr-xcommon/Resources/Sounds/diceinstbin0 -> 12658 bytes
-rwxr-xr-xcommon/Resources/Sounds/didjeridubin0 -> 60788 bytes
-rwxr-xr-xcommon/Resources/Sounds/dogbin0 -> 22332 bytes
-rwxr-xr-xcommon/Resources/Sounds/doorbin0 -> 33640 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum1chinebin0 -> 20480 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum1crashbin0 -> 64044 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum1floortombin0 -> 38498 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum1hardridebin0 -> 80044 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum1hatpedalbin0 -> 23022 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum1hatshoulderbin0 -> 28508 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum1kickbin0 -> 32044 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum1ridebellbin0 -> 80044 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum1snarebin0 -> 32044 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum1snaresidestickbin0 -> 5726 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum1splashbin0 -> 48044 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum1tombin0 -> 37152 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum2darbukadoombin0 -> 38652 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum2darbukafingerbin0 -> 22470 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum2darbukapiedbin0 -> 32106 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum2darbukapiedsoftbin0 -> 24454 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum2darbukarollbin0 -> 27176 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum2darbukaslapbin0 -> 25672 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum2darbukatakbin0 -> 12882 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum2hatflangerbin0 -> 64246 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum2hatpiedbin0 -> 14638 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum2hatpied2bin0 -> 14460 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum2tambourinepiedbin0 -> 33262 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum2tambourinepiedsoftbin0 -> 19470 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum3cowbellbin0 -> 15950 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum3cowbelltipbin0 -> 12872 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum3cupbin0 -> 15926 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum3djembelowbin0 -> 32080 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum3djembemidbin0 -> 15050 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum3djembesidestickbin0 -> 13602 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum3djembeslapbin0 -> 24090 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum3djembestickmidbin0 -> 25722 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum3metalstandbin0 -> 16108 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum3pedalpercbin0 -> 16160 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum3rainstickbin0 -> 56454 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum3tambourinehighbin0 -> 15996 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum3tambourinelowbin0 -> 15506 bytes
-rw-r--r--common/Resources/Sounds/drum4afrofeetbin0 -> 23774 bytes
-rw-r--r--common/Resources/Sounds/drum4fingersnbin0 -> 33644 bytes
-rw-r--r--common/Resources/Sounds/drum4mutecuicbin0 -> 12738 bytes
-rw-r--r--common/Resources/Sounds/drum4stompbassbin0 -> 22026 bytes
-rw-r--r--common/Resources/Sounds/drum4tambouribin0 -> 21382 bytes
-rw-r--r--common/Resources/Sounds/drum4tr707clapbin0 -> 11456 bytes
-rw-r--r--common/Resources/Sounds/drum4tr707openbin0 -> 29702 bytes
-rw-r--r--common/Resources/Sounds/drum4tr808closedbin0 -> 7530 bytes
-rw-r--r--common/Resources/Sounds/drum4tr808snbin0 -> 17474 bytes
-rw-r--r--common/Resources/Sounds/drum4tr909bassbin0 -> 61846 bytes
-rw-r--r--common/Resources/Sounds/drum4tr909kickbin0 -> 27516 bytes
-rw-r--r--common/Resources/Sounds/drum4tr909snbin0 -> 20920 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum5agogoaigubin0 -> 22366 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum5agogogravebin0 -> 19796 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum5bongoaiguouvertbin0 -> 11418 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum5bongograveouvertbin0 -> 14442 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum5congaaiguouvertbin0 -> 16146 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum5congagravefermebin0 -> 9674 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum5congagraveouvertbin0 -> 14490 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum5guiroretourbin0 -> 14462 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum5quicaaigubin0 -> 10410 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum5quicamediumbin0 -> 11398 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum5timablesaiguslapbin0 -> 33698 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum5timablesslapbin0 -> 37170 bytes
-rwxr-xr-xcommon/Resources/Sounds/drum5vibraslapbin0 -> 52238 bytes
-rwxr-xr-xcommon/Resources/Sounds/duckbin0 -> 12942 bytes
-rwxr-xr-xcommon/Resources/Sounds/duck2bin0 -> 7840 bytes
-rwxr-xr-xcommon/Resources/Sounds/flutebin0 -> 26902 bytes
-rwxr-xr-xcommon/Resources/Sounds/gambin0 -> 31848 bytes
-rwxr-xr-xcommon/Resources/Sounds/guidice1bin0 -> 10610 bytes
-rwxr-xr-xcommon/Resources/Sounds/guidice10bin0 -> 12298 bytes
-rwxr-xr-xcommon/Resources/Sounds/guidice2bin0 -> 16130 bytes
-rwxr-xr-xcommon/Resources/Sounds/guidice3bin0 -> 14980 bytes
-rwxr-xr-xcommon/Resources/Sounds/guidice4bin0 -> 14128 bytes
-rwxr-xr-xcommon/Resources/Sounds/guidice5bin0 -> 9760 bytes
-rwxr-xr-xcommon/Resources/Sounds/guidice6bin0 -> 12658 bytes
-rwxr-xr-xcommon/Resources/Sounds/guidice7bin0 -> 11148 bytes
-rwxr-xr-xcommon/Resources/Sounds/guidice8bin0 -> 11720 bytes
-rwxr-xr-xcommon/Resources/Sounds/guidice9bin0 -> 12376 bytes
-rwxr-xr-xcommon/Resources/Sounds/guitbin0 -> 32432 bytes
-rwxr-xr-xcommon/Resources/Sounds/guit2bin0 -> 57108 bytes
-rwxr-xr-xcommon/Resources/Sounds/harmonicabin0 -> 10396 bytes
-rwxr-xr-xcommon/Resources/Sounds/harmoniumbin0 -> 16948 bytes
-rwxr-xr-xcommon/Resources/Sounds/horsebin0 -> 36966 bytes
-rwxr-xr-xcommon/Resources/Sounds/kalimbabin0 -> 14496 bytes
-rwxr-xr-xcommon/Resources/Sounds/kotobin0 -> 29288 bytes
-rw-r--r--common/Resources/Sounds/lab1bin0 -> 44 bytes
-rw-r--r--common/Resources/Sounds/lab2bin0 -> 44 bytes
-rw-r--r--common/Resources/Sounds/lab3bin0 -> 44 bytes
-rw-r--r--common/Resources/Sounds/lab4bin0 -> 44 bytes
-rw-r--r--common/Resources/Sounds/lab5bin0 -> 44 bytes
-rw-r--r--common/Resources/Sounds/lab6bin0 -> 44 bytes
-rwxr-xr-xcommon/Resources/Sounds/laughbin0 -> 18112 bytes
-rwxr-xr-xcommon/Resources/Sounds/mandobin0 -> 20786 bytes
-rwxr-xr-xcommon/Resources/Sounds/marimbabin0 -> 13322 bytes
-rwxr-xr-xcommon/Resources/Sounds/mic1bin0 -> 44 bytes
-rwxr-xr-xcommon/Resources/Sounds/mic2bin0 -> 44 bytes
-rwxr-xr-xcommon/Resources/Sounds/mic3bin0 -> 44 bytes
-rwxr-xr-xcommon/Resources/Sounds/mic4bin0 -> 44 bytes
-rwxr-xr-xcommon/Resources/Sounds/ocarinabin0 -> 8650 bytes
-rwxr-xr-xcommon/Resources/Sounds/ounkbin0 -> 15232 bytes
-rwxr-xr-xcommon/Resources/Sounds/owbin0 -> 20300 bytes
-rwxr-xr-xcommon/Resources/Sounds/pianobin0 -> 96828 bytes
-rwxr-xr-xcommon/Resources/Sounds/planebin0 -> 69662 bytes
-rwxr-xr-xcommon/Resources/Sounds/rhodesbin0 -> 30080 bytes
-rwxr-xr-xcommon/Resources/Sounds/saxobin0 -> 29702 bytes
-rwxr-xr-xcommon/Resources/Sounds/sheepbin0 -> 39768 bytes
-rwxr-xr-xcommon/Resources/Sounds/shenaibin0 -> 14716 bytes
-rwxr-xr-xcommon/Resources/Sounds/sitarbin0 -> 27164 bytes
-rwxr-xr-xcommon/Resources/Sounds/slapbin0 -> 17534 bytes
-rwxr-xr-xcommon/Resources/Sounds/trianglebin0 -> 58652 bytes
-rwxr-xr-xcommon/Resources/Sounds/trumpetbin0 -> 20246 bytes
-rwxr-xr-xcommon/Resources/Sounds/tubabin0 -> 25876 bytes
-rwxr-xr-xcommon/Resources/Sounds/violinbin0 -> 21884 bytes
-rwxr-xr-xcommon/Resources/Sounds/voixbin0 -> 39052 bytes
-rwxr-xr-xcommon/Resources/Sounds/waterbin0 -> 19512 bytes
-rwxr-xr-xcommon/Resources/Sounds/zapbin0 -> 24218 bytes
-rw-r--r--common/Resources/SynthFiles/synthFile1bin0 -> 12288 bytes
-rw-r--r--common/Resources/SynthFiles/synthFile10bin0 -> 12288 bytes
-rw-r--r--common/Resources/SynthFiles/synthFile2bin0 -> 12288 bytes
-rw-r--r--common/Resources/SynthFiles/synthFile3bin0 -> 12288 bytes
-rw-r--r--common/Resources/SynthFiles/synthFile4bin0 -> 12288 bytes
-rw-r--r--common/Resources/SynthFiles/synthFile5bin0 -> 12288 bytes
-rw-r--r--common/Resources/SynthFiles/synthFile6bin0 -> 12288 bytes
-rw-r--r--common/Resources/SynthFiles/synthFile7bin0 -> 12288 bytes
-rw-r--r--common/Resources/SynthFiles/synthFile8bin0 -> 12288 bytes
-rw-r--r--common/Resources/SynthFiles/synthFile9bin0 -> 12288 bytes
-rw-r--r--common/Resources/__init__.py0
-rw-r--r--common/Resources/crop.csd72
-rw-r--r--common/Resources/tamtamorc.csd1096
-rw-r--r--common/Resources/tooltips_en.py128
-rw-r--r--common/Resources/tooltips_fr.py153
-rw-r--r--common/Util/CSoundClient.py356
-rw-r--r--common/Util/CSoundNote.py77
-rw-r--r--common/Util/Clooper/Makefile21
-rw-r--r--common/Util/Clooper/SoundClient.i14
-rw-r--r--common/Util/Clooper/__init__.py0
-rw-r--r--common/Util/Clooper/aclient.cpp1090
-rwxr-xr-xcommon/Util/Clooper/aclient.sobin0 -> 59030 bytes
-rw-r--r--common/Util/Clooper/audio.cpp223
-rw-r--r--common/Util/Clooper/cmd_csound.cpp22
-rw-r--r--common/Util/Clooper/log.cpp52
-rw-r--r--common/Util/Clooper/ttest.c53
-rw-r--r--common/Util/Clooper/ttest.h15
-rw-r--r--common/Util/Clooper/ttest.i15
-rw-r--r--common/Util/Clooper/ttest.py54
-rw-r--r--common/Util/Clooper/ttest_wrap.c3042
-rw-r--r--common/Util/ControlStream.py225
-rw-r--r--common/Util/Credits.py39
-rw-r--r--common/Util/InstrumentDB.py143
-rw-r--r--common/Util/InstrumentPanel.py379
-rw-r--r--common/Util/Instrument_.py392
-rw-r--r--common/Util/KeyboardWindow.py181
-rw-r--r--common/Util/LoopSettings.py230
-rw-r--r--common/Util/Network.py569
-rw-r--r--common/Util/NoteDB.py811
-rw-r--r--common/Util/NoteLooper.py199
-rw-r--r--common/Util/Profiler.py93
-rw-r--r--common/Util/Sound.py289
-rw-r--r--common/Util/ThemeWidgets.py1276
-rw-r--r--common/Util/Trackpad.py93
-rw-r--r--common/Util/__init__.py0
-rw-r--r--common/__init__.py0
489 files changed, 15616 insertions, 0 deletions
diff --git a/common/Config.py b/common/Config.py
new file mode 100644
index 0000000..47dd713
--- /dev/null
+++ b/common/Config.py
@@ -0,0 +1,599 @@
+# -*- coding: utf-8 -*-
+import os
+import Util.InstrumentDB as InstrumentDB
+
+QUICKLOAD = os.path.isfile("QUICKLOAD") # skip loading inessential comenents to speed things up
+
+SugarMode = True
+try:
+ from sugar import env
+except ImportError:
+ SugarMode = False
+
+if os.path.isfile("DEBUG"):
+ f = open("DEBUG")
+ l = f.read(10)
+ f.close()
+ if len(l): DEBUG = int( l )
+ else: DEBUG = 99
+else:
+ DEBUG = 0
+print "Debug Level %d" % (DEBUG)
+
+
+TAM_TAM_ROOT = os.path.dirname(os.path.abspath(__file__))
+print 'INFO: loaded TAMTAM_ROOT=%s' % TAM_TAM_ROOT
+
+
+#PATHS
+if os.path.isdir('/usr/share/activities/TamTamEdit.activity/Resources/Sounds'):
+ SOUNDS_DIR = "/usr/share/activities/TamTamEdit.activity/Resources/Sounds"
+else:
+ SOUNDS_DIR = TAM_TAM_ROOT + "/Resources/Sounds"
+FILES_DIR = TAM_TAM_ROOT + "/Resources"
+TUNE_DIR='/'
+SYNTH_DIR='/'
+if SugarMode == True:
+ PREF_DIR = env.get_profile_path() + '/tamtam'
+ TUNE_DIR=env.get_profile_path() + '/tamtam/tunes'
+ SYNTH_DIR=env.get_profile_path() + '/tamtam/synthlab'
+ SNDS_DIR=env.get_profile_path() + '/tamtam/snds'
+ SCRATCH_DIR = PREF_DIR + "/.scratch/"
+else:
+ PREF_DIR = os.getenv('HOME') + '/.tamtam'
+ TUNE_DIR= os.getenv('HOME') + '/.tamtam/tunes'
+ SYNTH_DIR= os.getenv('HOME') + '/.tamtam/synthlab'
+ SNDS_DIR= os.getenv('HOME') + '/.tamtam/snds'
+ SCRATCH_DIR = PREF_DIR + "/.scratch/"
+
+#PLUGIN
+PLUGIN_DEBUG = PREF_DIR + "/clooper.log"
+PLUGIN_VERBOSE = 0
+PLUGIN_UNIVORC = TAM_TAM_ROOT + "/Resources/tamtamorc.csd"
+PLUGIN_KSMPS = 64
+PLUGIN_RATE = 16000
+#PLUGIN_KSMPS = 64
+#PLUGIN_RATE = 22050
+
+## PLUGIN ALSA PARAMETERS:
+
+## for macbook pro
+#PLUGIN_PERIOD = 1024
+#PLUGIN_NPERIODS = 4
+
+## for XO with root
+#PLUGIN_PERIOD = 256
+#PLUGIN_NPERIODS = 2
+
+## for XO as normal user
+PLUGIN_PERIOD = 256 #512
+PLUGIN_NPERIODS = 2
+
+##############
+## SOUNDS
+##############
+KIT_ELEMENT = 24 * [0]
+for i in range(0,13):
+ KIT_ELEMENT += 2 * [i]
+KIT_ELEMENT = tuple(KIT_ELEMENT)
+
+class Instrument:
+ def __init__( self, name, instrumentId, csoundInstrumentId, instrumentRegister, soundClass, category, loopStart, loopEnd, crossDur, kit = None ):
+ self.name = name
+ self.instrumentId = instrumentId
+ self.csoundInstrumentId = csoundInstrumentId
+ self.instrumentRegister = instrumentRegister
+ self.soundClass = soundClass
+ self.category = category
+ self.loopStart = loopStart
+ self.loopEnd = loopEnd
+ self.crossDur = crossDur
+ self.kit = kit
+ #print (self.name, self.instrumentId, self.csoundInstrumentId, self.instrumentRegister, self.soundClass, self.category, self.loopStart, self.loopEnd, self.crossDur)
+
+LOW, MID, HIGH, PUNCH = range( 4 )
+
+# Sounds categories: musicInst, animals, drum, people, electronic, concret, mic
+#INSTRUMENTS ( csound table, csound instrument, register, instrumentClass, category )
+INSTRUMENT_TABLE_OFFSET = 5000
+INST_FREE = 5000
+INST_TIED = 5001
+INST_SIMP = 5011
+INST_PERC = 5021
+
+CATEGORIES = ['all','animals','concret','keyboard','people','percussions','strings','winds', 'mysounds']
+
+instrumentDB = InstrumentDB.getRef()
+
+_nextInstrumentId = [0]
+INSTRUMENTS = {}
+def _addInstrument( name, csoundInstrumentId, instrumentRegister, soundClass, category, loopStart, loopEnd, crossDur, kit = None ):
+ if not QUICKLOAD or name[0:4] == "drum" or name in ["flute", "kalimba"]: # quick load
+ INSTRUMENTS[name] = Instrument( name, _nextInstrumentId[0], csoundInstrumentId, instrumentRegister, soundClass, category, loopStart, loopEnd, crossDur, kit )
+ instrumentDB.addInstrumentFromArgs( name, name, instrumentRegister, loopStart, loopEnd, crossDur, name, FILES_DIR+"/Images/"+name+".png", [ category ] )
+ _nextInstrumentId[0] += 1
+
+
+_addInstrument( "mic1", INST_TIED, MID, 'melo', 'mic', .01, 1.99, .01 )
+_addInstrument( "mic2", INST_TIED, MID, 'melo', 'mic', .01, 1.99, .01 )
+_addInstrument( "mic3", INST_TIED, MID, 'melo', 'mic', .01, 1.99, .01 )
+_addInstrument( "mic4", INST_TIED, MID, 'melo', 'mic', .01, 1.99, .01 )
+_addInstrument( "lab1", INST_SIMP, MID, 'melo', 'lab', 0, 0, 0 )
+_addInstrument( "lab2", INST_SIMP, MID, 'melo', 'lab', 0, 0, 0 )
+_addInstrument( "lab3", INST_SIMP, MID, 'melo', 'lab', 0, 0, 0 )
+_addInstrument( "lab4", INST_SIMP, MID, 'melo', 'lab', 0, 0, 0 )
+_addInstrument( "lab5", INST_SIMP, MID, 'melo', 'lab', 0, 0, 0 )
+_addInstrument( "lab6", INST_SIMP, MID, 'melo', 'lab', 0, 0, 0 )
+_addInstrument( "ounk", INST_SIMP, MID, 'melo', 'animals', 0, 0, 0 )
+_addInstrument( "gam", INST_TIED, HIGH, 'melo', 'percussions', .69388, .7536, .02922 )
+_addInstrument( "guit", INST_TIED, MID, 'melo', 'strings', .08592, .75126, .33571 )
+_addInstrument( "koto", INST_TIED, HIGH, 'melo', 'strings', .56523, .70075, .05954 )
+_addInstrument( "clarinette", INST_TIED, MID, 'melo', 'winds', .57905, .73319, .04934 )
+_addInstrument( "flute", INST_TIED, MID, 'melo', 'winds', .47169, .53693, .02481 )
+_addInstrument( "drum1hatpedal", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum1hatshoulder", INST_SIMP, HIGH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum1hardride", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum1ridebell", INST_SIMP, HIGH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum1snare", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum1snaresidestick", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum1crash", INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum1splash", INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum1tom", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum1floortom", INST_SIMP, LOW, 'drum', 'drum', 0, 0, 0)
+_addInstrument( "drum1chine", INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum1kick", INST_SIMP, LOW, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "piano", INST_TIED, MID, 'melo', 'keyboard', 0.8883, 1.420524, .13575 )
+_addInstrument( "dog", INST_SIMP, MID, 'melo', 'animals', 0, 0, 0 )
+_addInstrument( "duck", INST_SIMP, MID, 'melo', 'animals', 0, 0, 0 )
+_addInstrument( "drum2darbukadoom", INST_SIMP, LOW, 'drum', 'drum', 0, 0 ,0 )
+_addInstrument( "drum2darbukapied", INST_SIMP, LOW, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum2darbukapiedsoft", INST_SIMP, LOW, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum2hatflanger", INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum2darbukatak", INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum2darbukafinger", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum2darbukaroll", INST_SIMP, HIGH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum2darbukaslap", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum2hatpied", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum2tambourinepied", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum2hatpied2", INST_SIMP, HIGH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum2tambourinepiedsoft", INST_SIMP, HIGH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum3cowbell", INST_SIMP, HIGH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum3cowbelltip", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0)
+_addInstrument( "drum3cup", INST_SIMP, HIGH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum3djembelow", INST_SIMP, LOW, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum3djembemid", INST_SIMP, HIGH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum3djembesidestick", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum3djembeslap", INST_SIMP, LOW, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum3djembestickmid", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum3metalstand", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum3pedalperc", INST_SIMP, LOW, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum3rainstick", INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum3tambourinehigh", INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum3tambourinelow", INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "harmonica", INST_TIED, MID, 'melo', 'winds', .1531, .19188, .01792 )
+_addInstrument( "alarm", INST_TIED, MID, 'melo', 'concret', .02, .19133, .01 )
+_addInstrument( "bird", INST_TIED, MID, 'melo', 'animals', .1, 1, .05 )
+_addInstrument( "cat", INST_SIMP, MID, 'melo', 'animals', 0, 0, 0 )
+_addInstrument( "duck2", INST_SIMP, MID, 'melo', 'animals', 0, 0, 0 )
+_addInstrument( "bottle", INST_TIED, MID, 'melo', 'concret', .20532, .41064, .05292 )
+_addInstrument( "clang", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "ow", INST_SIMP, MID, 'melo', 'people', 0, 0, 0 )
+_addInstrument( "sheep", INST_SIMP, MID, 'melo', 'animals', 0, 0, 0 )
+_addInstrument( "water", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "zap", INST_TIED, MID, 'melo', 'keyboard', .299, .7323, .09895 )
+_addInstrument( "trumpet", INST_TIED, MID, 'melo', 'winds', .39934, .45537, .02729)
+_addInstrument( "bubbles", INST_TIED, MID, "melo", 'concret', 0.02, 1.177, 0.02)
+_addInstrument( "marimba", INST_TIED, MID, "melo", 'percussions', .26545, .33098, .03087)
+_addInstrument( "triangle", INST_TIED, MID, "melo", 'percussions', 1.21002, 1.31805, .01268)
+_addInstrument( "laugh", INST_SIMP, MID, 'melo', 'people', 0, 0, 0 )
+_addInstrument( "voix", INST_TIED, MID, 'melo', 'people', .89608, .96092, .02343 )
+_addInstrument( "cling", INST_TIED, MID, 'melo', 'keyboard', .09096, .7878, .18026 )
+_addInstrument( "byke", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "door", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "basse", INST_TIED, MID, 'melo', 'strings', 0.50470875, 0.833315, 0.09375 )
+_addInstrument( "acguit", INST_TIED, MID, 'melo', 'strings', 0.5123225, 0.7491675, 0.08475 )
+_addInstrument( "diceinst", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "didjeridu", INST_TIED, LOW, 'melo', 'winds', .55669, 1.73704, .09178 )
+_addInstrument( "harmonium", INST_TIED, MID, 'melo', 'keyboard', .04674, .41073, .18384 )
+_addInstrument( "horse", INST_SIMP, MID, 'melo', 'animals', 0, 0, 0 )
+_addInstrument( "kalimba", INST_TIED, MID, 'melo', 'percussions', .20751, .30161, .04658 )
+_addInstrument( "mando", INST_TIED, MID, 'melo', 'strings', 0.316548, 0.532008, 0.02875 )
+_addInstrument( "ocarina", INST_TIED, MID, 'melo', 'winds', .06612, .19033, .01776 )
+_addInstrument( "rhodes", INST_TIED, MID, 'melo', 'keyboard', 0.58100625, 0.821625, 0.067 )
+_addInstrument( "saxo", INST_TIED, MID, 'melo', 'winds', .53722, .6583, .05264 )
+_addInstrument( "shenai", INST_TIED, MID, 'melo', 'winds', .29003, .33072, .00634 )
+_addInstrument( "sitar", INST_TIED, MID, 'melo', 'strings', .63187, .67882, .01654 )
+_addInstrument( "tuba", INST_TIED, LOW, 'melo', 'winds', .51063, .58384, .035 )
+_addInstrument( "violin", INST_TIED, MID, 'melo', 'strings', .105, .30656, .028 )
+_addInstrument( "guidice1", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "guidice2", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "guidice3", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "guidice4", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "guidice5", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "guidice6", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "guidice7", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "guidice8", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "guidice9", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "guidice10", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "drum4afrofeet", INST_SIMP, LOW, 'drum', 'drum', 0, 0 ,0 )
+_addInstrument( "drum4fingersn", INST_SIMP, HIGH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum4mutecuic", INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum4stompbass", INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum4tambouri", INST_SIMP, HIGH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum4tr707clap", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum4tr707open", INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum4tr808closed", INST_SIMP, HIGH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum4tr808sn", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum4tr909bass", INST_SIMP, LOW, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum4tr909kick", INST_SIMP, LOW, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum4tr909sn", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum5timablesslap", INST_SIMP, LOW, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum5congagraveouvert", INST_SIMP, LOW, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum5timablesaiguslap", INST_SIMP, LOW, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum5congagraveferme", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum5guiroretour", INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum5vibraslap", INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum5congaaiguouvert", INST_SIMP, MID, 'drum', 'drum', 0, 0 ,0 )
+_addInstrument( "drum5quicamedium", INST_SIMP, PUNCH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum5quicaaigu", INST_SIMP, MID, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum5agogograve", INST_SIMP, HIGH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum5bongoaiguouvert", INST_SIMP, HIGH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum5agogoaigu", INST_SIMP, HIGH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "drum5bongograveouvert", INST_SIMP, HIGH, 'drum', 'drum', 0, 0, 0 )
+_addInstrument( "camera", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "car", INST_TIED, MID, 'melo', 'concret', .67, 1.05761, .01 )
+#_addInstrument( "cello", INST_TIED, MID, 'melo', 'strings', .194, .7211, .017 )
+_addInstrument( "chimes", INST_TIED, MID, 'melo', 'percussions', .09, 2.97633, .01 )
+_addInstrument( "crash", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "guit2", INST_TIED, MID, 'melo', 'strings', .33, 1.1583, .02 )
+_addInstrument( "plane", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+_addInstrument( "slap", INST_SIMP, MID, 'melo', 'concret', 0, 0, 0 )
+
+try:
+ ifile = open(PREF_DIR + '/sounds_settings', 'r')
+ for line in ifile.readlines():
+ list = line.split()
+ _addInstrument(list[0], int(list[1]), int(list[2]), list[3], list[4], float(list[5]), float(list[6]), float(list[7]))
+except:
+ pass
+
+
+DRUM1KIT = { 24 : INSTRUMENTS["drum1kick"],
+ 26 : INSTRUMENTS["drum1floortom"],
+ 28 : INSTRUMENTS["drum1tom"],
+ 30 : INSTRUMENTS["drum1chine"],
+ 32 : INSTRUMENTS["drum1splash"],
+ 34 : INSTRUMENTS["drum1crash"],
+ 36 : INSTRUMENTS["drum1snaresidestick"],
+ 38 : INSTRUMENTS["drum1snaresidestick"],
+ 40 : INSTRUMENTS["drum1snare"],
+ 42 : INSTRUMENTS["drum1ridebell"],
+ 44 : INSTRUMENTS["drum1hardride"],
+ 46 : INSTRUMENTS["drum1hatshoulder"],
+ 48 : INSTRUMENTS["drum1hatpedal"] }
+
+DRUM2KIT = { 24 : INSTRUMENTS["drum2darbukadoom"],
+ 26 : INSTRUMENTS["drum2darbukapied"],
+ 28 : INSTRUMENTS["drum2darbukapiedsoft"],
+ 30 : INSTRUMENTS["drum2hatflanger"],
+ 32 : INSTRUMENTS["drum2darbukatak"],
+ 34 : INSTRUMENTS["drum2darbukatak"],
+ 36 : INSTRUMENTS["drum2darbukafinger"],
+ 38 : INSTRUMENTS["drum2darbukaroll"],
+ 40 : INSTRUMENTS["drum2darbukaslap"],
+ 42 : INSTRUMENTS["drum2hatpied"],
+ 44 : INSTRUMENTS["drum2tambourinepied"],
+ 46 : INSTRUMENTS["drum2hatpied2"],
+ 48 : INSTRUMENTS["drum2tambourinepiedsoft"] }
+
+DRUM3KIT = { 24 : INSTRUMENTS["drum3djembelow"],
+ 26 : INSTRUMENTS["drum3pedalperc"],
+ 28 : INSTRUMENTS["drum3djembeslap"],
+ 30 : INSTRUMENTS["drum3tambourinehigh"],
+ 32 : INSTRUMENTS["drum3tambourinelow"],
+ 34 : INSTRUMENTS["drum3rainstick"],
+ 36 : INSTRUMENTS["drum3djembemid"],
+ 38 : INSTRUMENTS["drum3djembesidestick"],
+ 40 : INSTRUMENTS["drum3djembestickmid"],
+ 42 : INSTRUMENTS["drum3cowbell"],
+ 44 : INSTRUMENTS["drum3cowbelltip"],
+ 46 : INSTRUMENTS["drum3cup"],
+ 48 : INSTRUMENTS["drum3metalstand"] }
+
+DRUM4KIT = { 24 : INSTRUMENTS["drum4afrofeet"],
+ 26 : INSTRUMENTS["drum4tr909kick"],
+ 28 : INSTRUMENTS["drum4tr909bass"],
+ 30 : INSTRUMENTS["drum4stompbass"],
+ 32 : INSTRUMENTS["drum4tr707open"],
+ 34 : INSTRUMENTS["drum4mutecuic"],
+ 36 : INSTRUMENTS["drum4tr808sn"],
+ 38 : INSTRUMENTS["drum4tr707clap"],
+ 40 : INSTRUMENTS["drum4tr909sn"],
+ 42 : INSTRUMENTS["drum4tambouri"],
+ 44 : INSTRUMENTS["drum4fingersn"],
+ 46 : INSTRUMENTS["drum4fingersn"],
+ 48 : INSTRUMENTS["drum4tr808closed"] }
+
+DRUM5KIT = { 24 : INSTRUMENTS["drum5timablesslap"],
+ 26 : INSTRUMENTS["drum5timablesaiguslap"],
+ 28 : INSTRUMENTS["drum5congagraveouvert"],
+ 30 : INSTRUMENTS["drum5quicamedium"],
+ 32 : INSTRUMENTS["drum5guiroretour"],
+ 34 : INSTRUMENTS["drum5vibraslap"],
+ 36 : INSTRUMENTS["drum5congagraveferme"],
+ 38 : INSTRUMENTS["drum5quicaaigu"],
+ 40 : INSTRUMENTS["drum5congaaiguouvert"],
+ 42 : INSTRUMENTS["drum5agogoaigu"],
+ 44 : INSTRUMENTS["drum5bongograveouvert"],
+ 46 : INSTRUMENTS["drum5agogograve"],
+ 48 : INSTRUMENTS["drum5bongoaiguouvert"] }
+
+_addInstrument( "drum1kit", 0, 0, 0, "kit", 0, 0, 0, DRUM1KIT )
+_addInstrument( "drum2kit", 0, 0, 0, "kit", 0, 0, 0, DRUM2KIT )
+_addInstrument( "drum3kit", 0, 0, 0, "kit", 0, 0, 0, DRUM3KIT )
+_addInstrument( "drum4kit", 0, 0, 0, "kit", 0, 0, 0, DRUM4KIT )
+_addInstrument( "drum5kit", 0, 0, 0, "kit", 0, 0, 0, DRUM5KIT )
+
+INSTRUMENTSID = {}
+for i in INSTRUMENTS:
+ INSTRUMENTSID[INSTRUMENTS[i].instrumentId] = INSTRUMENTS[i]
+
+
+#DRUMKITS = ['drum1kit', 'drum2kit', 'drum3kit', 'drum4kit']
+#DRUMSINSTRUMENTSDICT = [DRUM1KIT, DRUM2KIT, DRUM3KIT, DRUM4KIT]
+
+RECORDABLE_INSTRUMENTS = set( [ "mic1", "mic2", "mic3", "mic4" ] )
+RECORDABLE_INSTRUMENT_CSOUND_IDS = { "mic1" : 7,
+ "mic2" : 8,
+ "mic3" : 9,
+ "mic4" : 10 }
+
+#CSOUND COMMANDS
+CSOUND_LOAD_INSTRUMENT = 'f%d 0 0 -1 "%s" 0 0 0'
+CSOUND_MIC_RECORD = 'i5201 0 5 %d'
+CSOUND_UNLOAD_TABLES = 'i%d 0 0.1 %d' % (INST_FREE, len(INSTRUMENTS))
+CSOUND_NOTE_OFF = 'i %s.%s .2 0.01 1. 0. 0. 0.5 %d 0 0 0 0' %('%d','%d',INSTRUMENT_TABLE_OFFSET)
+CSOUND_LOAD_LS_INSTRUMENT = 'f4999 0 0 -1 \"%s\" 0 0 0'
+CSOUND_PLAY_LS_NOTE = 'i %i 0 -1'
+CSOUND_STOP_LS_NOTE = 'i 5022 0 0.5'
+
+#CSOUND COMMANDS - DEPRECATED
+
+LOAD_INSTRUMENT_COMMAND = \
+ "perf.InputMessage('f%d 0 0 -1 \"%s\" 0 0 0')\n"
+PLAY_NOTE_COMMAND = \
+ "perf.InputMessage('i %d.%d %f %f %f %f %f %f %d %f %f %d %f %f %f %f')\n"
+#TODO: add the extra three params to COMMAND_MINUS_DELAY, and instrument 5777 in univorc.csd
+PLAY_NOTE_COMMAND_MINUS_DELAY = \
+ "perf.InputMessage('i 5777 0.0 0.001 %d.%d %s %f %f %f %f %f %d %f %f %d %f')\n"
+PLAY_NOTE_OFF_COMMAND = \
+ "perf.InputMessage('i %s.%s .2 0.01 1. 0. 0. 0.5 %d 0 0 0 0')\n" \
+ % ('%d', '%d', INSTRUMENT_TABLE_OFFSET )
+MIC_RECORDING_COMMAND = \
+ "perf.InputMessage('i5201 0 5 %d')\n"
+UNLOAD_TABLES_COMMAND = \
+ "perf.InputMessage('i%d 0 0.1 %d')\n" % (INST_FREE, len(INSTRUMENTS))
+
+
+
+
+#################
+## GUI CONSTANTS
+#################
+
+LANGUAGE = 'En'
+IMAGE_ROOT = TAM_TAM_ROOT + '/Resources/Images/'
+
+MAIN_WINDOW_PADDING = 5
+
+BG_COLOR = '#404040'
+FG_COLOR = '#818286'
+
+NOTE_HEIGHT = 9 # pixels
+NOTE_IMAGE_PADDING = 6
+NOTE_IMAGE_PADDING_MUL2 = NOTE_IMAGE_PADDING*2
+NOTE_IMAGE_TAIL = 1059
+NOTE_IMAGE_ENDLENGTH = 12
+HIT_HEIGHT = 13 # pixels
+HIT_IMAGE_PADDING = 6
+HIT_IMAGE_PADDING_MUL2 = HIT_IMAGE_PADDING*2
+TRACK_SPACING = 4
+TRACK_SPACING_DIV2 = TRACK_SPACING//2
+TRACK_COLORS = [ ( "#00290B", "#00E847" ), \
+ ( "#3F0200", "#E72500" ), \
+ ( "#002642", "#0090EA" ), \
+ ( "#313D00", "#F9EF00" ), \
+ ( "#17083B", "#4A00ED" ) ]
+#TRACK_COLORS = [ ( "#00591B", "#00E847" ), \
+# ( "#6F1200", "#E72500" ), \
+# ( "#004682", "#0090EA" ), \
+# ( "#716D00", "#F9EF00" ), \
+# ( "#37187B", "#4A00ED" ) ]
+BEAT_COLOR = "#999999"
+BEAT_LINE_SIZE = 2
+PLAYHEAD_COLOR = "#666666"
+PLAYHEAD_SIZE = 2
+PLAYHEAD_SIZE_DIV2 = PLAYHEAD_SIZE/2.0
+MARQUEE_COLOR = "#FFFFFF"
+MARQUEE_SIZE = 2
+
+PAGE_BORDER_SIZE = 2
+PAGE_SELECTED_BORDER_SIZE = 5
+PAGE_WIDTH = 100
+PAGE_HEIGHT = 25
+
+PAGE_THUMBNAIL_WIDTH = 92
+PAGE_THUMBNAIL_WIDTH_DIV2 = PAGE_THUMBNAIL_WIDTH/2
+PAGE_THUMBNAIL_HEIGHT = 65
+
+THUMBNAIL_TRACK_RECT = [ ( 2, 4, 83, 10 ), \
+ ( 2, 14, 83, 10 ), \
+ ( 2, 24, 83, 10 ), \
+ ( 2, 34, 83, 10 ), \
+ ( 2, 44, 83, 13 ) ]
+THUMBNAIL_DRAG_COLOR = "#000000"
+THUMBNAIL_TRACK_COLOR = "#FF0000"
+THUMBNAIL_SELECTED_COLOR = "#2266FF"
+THUMBNAIL_DISPLAYED_COLOR = "#CC1133"
+
+TOOLBAR_BCK_COLOR = '#404040'
+WHITE_COLOR = '#FFFFFF'
+### miniTamTam/SYNTHLAB SPECIFIC ###
+INST_BCK_COLOR = '#999999'
+PANEL_BCK_COLOR = '#CCCCCC'
+PANEL_COLOR = '#CCCCCC'
+SL_LINE_COLOR = "#666666"
+SL_HIGHLIGHT_COLOR = "#FFFFFF"
+SL_OVER_WIRE_COLOR = "#FFFFFF"
+SL_OVER_GATE_COLOR = "#00FF18"
+SL_OVER_GATE_REJECT_COLOR = "#B30000"
+PANEL_RADIUS = 10
+PANEL_SPACING = 2
+
+###Instrument Panel###
+CATEGORY_BCK_COLOR = '#222222'
+INSTRUMENT_GRID_COLOR = '#CCCCCC'
+
+###Welcome Screen Specific###
+WS_PANEL_COLOR = '#404040'
+WS_BCK_COLOR = '#CCCCCC'
+
+# hardware keycodes for mod keys
+MOD_LSHIFT = 50
+MOD_RSHIFT = 62
+MOD_LCTRL = 37
+MOD_RCTRL = 109
+MOD_LALT = 64
+MOD_RALT = 113
+
+
+
+########
+## Things that don't belong!
+#######
+class _ModKeys:
+ def __init__( self ):
+ self.shiftDown = False
+ self.ctrlDown = False
+ self.altDown = False
+
+ def keyPress( self, code ):
+ if code == MOD_LSHIFT or code == MOD_RSHIFT: self.shiftDown = True
+ elif code == MOD_LCTRL or code == MOD_RCTRL: self.ctrlDown = True
+ elif code == MOD_LALT or code == MOD_RALT: self.altDown = True
+
+ def keyRelease( self, code ):
+ if code == MOD_LSHIFT or code == MOD_RSHIFT: self.shiftDown = False
+ elif code == MOD_LCTRL or code == MOD_RCTRL: self.ctrlDown = False
+ elif code == MOD_LALT or code == MOD_RALT: self.altDown = False
+
+ModKeys = _ModKeys()
+
+
+############
+## EDIT DEFAULTS
+############
+
+#DEFAULTS
+PLAYER_TEMPO = 100
+PLAYER_TEMPO_LOWER = 30
+PLAYER_TEMPO_UPPER = 160
+DEFAULT_VOLUME = 50
+
+#NUMERICAL CONSTANTS
+NUMBER_OF_POSSIBLE_PITCHES = 25
+MINIMUM_PITCH = 24
+MAXIMUM_PITCH = MINIMUM_PITCH + NUMBER_OF_POSSIBLE_PITCHES - 1
+NUMBER_OF_POSSIBLE_PITCHES_DRUM = 13
+PITCH_STEP_DRUM = 2
+MINIMUM_PITCH_DRUM = 24
+MAXIMUM_PITCH_DRUM = MINIMUM_PITCH_DRUM + PITCH_STEP_DRUM*(NUMBER_OF_POSSIBLE_PITCHES_DRUM - 1)
+MINIMUM_NOTE_DURATION = 1 # ticks
+MS_PER_MINUTE = 60000.0
+TICKS_PER_BEAT = 12
+TICKS_PER_BEAT_DIV2 = TICKS_PER_BEAT/2
+MAXIMUM_BEATS = 12 # maximum beats per page
+NUMBER_OF_TRACKS = 5
+NUMBER_OF_PAGES = 2
+
+MINIMUM_AMPLITUDE = 0
+MAXIMUM_AMPLITUDE = 1
+
+DEFAULT_GRID = 3
+DEFAULT_GRID_DIV2 = DEFAULT_GRID / 2.0
+
+
+####################
+## ToolTips
+####################
+LANGUAGE = 'en'
+exec 'from Resources.tooltips_%s import Tooltips' % LANGUAGE
+
+
+####################
+## KeyMapping
+####################
+
+LOOP_KEYS = [17, 18, 19, 20, 21, 32, 33, 34, 35, 45, 46, 47, 48, 51, 60, 61]
+# Key = Hardware Keycode Value = Note
+
+KEY_MAP_PIANO = {24:36, #Q
+ 25:38, #W
+ 26:40, #E
+ 27:41, #R
+ 28:43, #T
+ 29:45, #Y
+ 30:47, #U
+ 31:48, #I
+
+ 11:37, #2
+ 12:39, #3
+ 14:42, #5
+ 15:44, #6
+ 16:46, #7
+
+ 39:25, #S
+ 40:27, #D
+ 42:30, #G
+ 43:32, #H
+ 44:34, #J
+ 46:37, #L
+
+ 52:24, #Z
+ 53:26, #X
+ 54:28, #C
+ 55:29, #V
+ 56:31, #B
+ 57:33, #N
+ 58:35, #M
+ 59:36} #,
+
+KEY_MAP_NOTPIANO = {24:24, #Q
+ 25:25, #W
+ 26:26, #E
+ 27:27, #R
+ 28:28, #T
+ 29:29, #Y
+ 30:30, #U
+ 31:31, #I
+ 32:32, #O
+ 33:33, #P
+
+ 38:34, #A
+ 39:35, #S
+ 40:36, #D
+ 41:37, #F
+ 42:38, #G
+ 43:39, #H
+ 44:40, #J
+ 45:41, #K
+ 46:42, #L
+
+ 52:43, #Z
+ 53:44, #X
+ 54:45, #C
+ 55:46, #V
+ 56:47, #B
+ 57:48} #N
+
+KEY_MAP = KEY_MAP_PIANO
diff --git a/common/Generation/Drunk.py b/common/Generation/Drunk.py
new file mode 100755
index 0000000..1bc3bbb
--- /dev/null
+++ b/common/Generation/Drunk.py
@@ -0,0 +1,162 @@
+# Random:
+# Randomly choose, within a certain range, a new next value
+# arg 1: maxStepSize (negative value not allowed stepSize == 0)
+# arg 2: maximum value allowed
+
+import random
+
+class Drunk:
+ def __init__( self, minValue, maxValue, trackLength=None ):
+ self.minValue = min(minValue, maxValue)
+ self.maxValue = max(minValue, maxValue)
+ self.lastValue = random.randint( self.minValue, self.maxValue )
+
+
+ def getNextValue( self, maxStepSize, maxValue ):
+ if self.lastValue < 0 or self.lastValue > maxValue:
+ return random.randint( self.minValue, maxValue )
+
+ direction = self.getDirection( maxValue )
+ stepSize = self.getStepSize( direction, abs(maxStepSize), maxValue )
+
+ if maxStepSize < 0:
+ minStepSize = 1
+ else:
+ minStepSize = 0
+
+ self.lastValue += direction * random.randint( minStepSize, stepSize )
+
+ if self.lastValue < self.minValue:
+ self.lastValue = self.minValue
+ elif self.lastValue > maxValue: #instead of 14...
+ self.lastValue = maxValue
+ else:
+ self.lastValue = self.lastValue
+
+ return self.lastValue
+
+ def getDirection( self, maxValue ):
+ if self.lastValue == 0:
+ return 1
+ elif self.lastValue == maxValue:
+ return -1
+ else:
+ return random.choice( [ 1, -1 ] )
+
+ def getStepSize( self, direction, maxStepSize, maxValue, ):
+ if direction == -1:
+ return min( maxStepSize, self.lastValue )
+ else:
+ return min( maxStepSize, maxValue - self.lastValue )
+
+class DroneAndJump( Drunk ):
+ def __init__( self, minValue, maxValue, trackLength=None ):
+ Drunk.__init__( self, minValue, maxValue, trackLength=None )
+ self.minValue = min(minValue, maxValue)
+ self.maxValue = max(minValue, maxValue)
+ self.beforeLastValue = random.randint( self.minValue, self.maxValue ) #self.minValue
+ self.lastValue = self.beforeLastValue + 1
+
+ def getNextValue( self, maxStepSize, maxValue ):
+ if self.beforeLastValue != self.lastValue:
+ self.lastValue = self.beforeLastValue
+ return self.beforeLastValue
+
+ self.beforeLastValue = self.lastValue
+ self.lastValue = Drunk.getNextValue( self, abs(maxStepSize), maxValue )
+ return self.lastValue
+
+ def getStepSize( self, direction, maxStepSize, maxValue ):
+ if random.randint( 0, 100 ) < 42:
+ return Drunk.getStepSize( self, direction, maxStepSize, maxValue )
+ else:
+ return Drunk.getStepSize( self, direction, 0, maxValue )
+
+class Repeter( Drunk ):
+ def __init__( self, minValue, maxValue, trackLength=None ):
+ Drunk.__init__( self, minValue, maxValue, trackLength=None)
+ self.minValue = min(minValue, maxValue)
+ self.maxValue = max(minValue, maxValue)
+ self.lastValue = random.randint( self.minValue, self.maxValue)
+
+ def getNextValue( self, maxStepSize, maxValue ):
+ self.lastValue = Drunk.getNextValue( self, abs(maxStepSize), maxValue )
+ return self.lastValue
+
+ def getStepSize( self, direction, maxStepSize, maxValue ):
+ if random.randint( 0, 100 ) < 20:
+ return Drunk.getStepSize( self, direction, maxStepSize, maxValue )
+ else:
+ return Drunk.getStepSize( self, direction, 0, maxValue )
+
+class Loopseg( Drunk ):
+ def __init__( self, minValue, maxValue, trackLength=None ):
+ Drunk.__init__( self, minValue, maxValue, trackLength=None )
+ self.recordedValues = []
+ self.recordState = 2
+ self.recordPlayback = 0
+ self.loopPlayback = 1
+ self.recordLength = random.randint( 3, 6 )
+ self.recordLoopTime = random.randint( 1, 4 )
+
+ def getNextValue( self, maxStepSize, maxValue ):
+ if self.recordState == 2:
+ self.lastValue = Drunk.getNextValue( self, maxStepSize, maxValue )
+ self.recordState = random.choice([2, 2, 2, 1])
+
+ if len(self.recordedValues) != self.recordLength and self.recordState == 1:
+ self.lastValue = Drunk.getNextValue( self, maxStepSize, maxValue )
+ self.recordedValues.append( self.lastValue )
+ elif self.recordState == 1 or self.recordState == 0:
+ self.recordState = 0
+ if self.recordPlayback < self.recordLength:
+ self.loopAround()
+ else:
+ if self.loopPlayback < self.recordLoopTime:
+ self.recordPlayback = 0
+ self.loopPlayback += 1
+ self.loopAround()
+ else:
+ self.recordedValues = []
+ self.recordState = 2
+ self.recordPlayback = 0
+ self.loopPlayback = 1
+ self.recordLength = random.randint( 3, 6 )
+ self.recordLoopTime = random.randint( 1, 4 )
+ self.lastValue = Drunk.getNextValue( self, maxStepSize, maxValue )
+ self.recordedValues = [self.lastValue]
+ return self.lastValue
+
+ def loopAround( self ):
+ self.lastValue = self.recordedValues[self.recordPlayback]
+ self.recordPlayback += 1
+
+class Line:
+ def __init__(self, minValue, maxValue, trackLength=20):
+ maxVal = max(minValue, maxValue)
+ if maxVal == minValue:
+ self.reverse = True
+ minVal = maxValue
+ self.lastValue = maxVal
+ else:
+ self.reverse = False
+ minVal = minValue
+ self.lastValue = minVal
+
+ scale = float(maxVal - minVal)
+ if self.reverse:
+ self.inc = -scale/trackLength
+ else:
+ self.inc = scale/trackLength
+
+ def getNextValue(self, rand, maxValue):
+ self.val = self.lastValue + int(random.randint(0, rand)*random.choice([-0.5,0.5]))
+ if self.val < 0:
+ self.val = 0
+ elif self.val > maxValue:
+ self.val = maxValue
+ else:
+ self.val = self.val
+ self.lastValue = self.val+self.inc
+ return self.val
+
diff --git a/common/Generation/GenerationConstants.py b/common/Generation/GenerationConstants.py
new file mode 100755
index 0000000..29dd28b
--- /dev/null
+++ b/common/Generation/GenerationConstants.py
@@ -0,0 +1,184 @@
+import random
+
+class GenerationConstants:
+
+ TWO_ROOT_TWELVE = pow( 2, 1./12 )
+ MAX_NOTES_PER_BAR = 12
+
+ PHRASE_LENGTH = 4
+ PHRASE_COMPLEXITY = .5
+
+ TABLE_ONSET_VALUES = [ 3, 3, 6, 3, 6, 12, 4, 3, 6, 6, 12, 6, 12, 18, 8, 6, 12, 18, 12, 24, 12, 18, 36, 24, 36, 24, 48 ]
+ LOOP_TABLE_ONSET_VALUES = [ 3, 3, 6, 3, 6, 12, 6, 3, 6, 6, 12, 6, 12, 18, 12, 6, 12, 18, 12, 24, 12, 18, 12, 24, 18, 24, 24 ]
+
+ # scaling constants
+ MAJOR = 0
+ HARMONIC_MINOR = 1
+ NATURAL_MINOR = 2
+ PHRYGIEN = 3
+ DORIEN = 4
+ LYDIEN = 5
+ MYXOLYDIEN = 6
+
+ SCALES = { MAJOR : [ -12, -10, -8, -7, -5, -3, -1, 0, 2, 4, 5, 7, 9, 11, 12 ],
+ HARMONIC_MINOR : [ -12, -10, -9, -7, -5, -4, -1, 0, 2, 3, 5, 7, 8, 11, 12 ],
+ NATURAL_MINOR : [ -12, -10, -9, -7, -5, -4, -2, 0, 2, 3, 5, 7, 8, 10, 12 ],
+ PHRYGIEN : [ -12, -11, -9, -7, -5, -4, -2, 0, 1, 3, 5, 7, 8, 10, 12 ],
+ DORIEN : [ -12, -10, -9, -7, -5, -3, -2, 0, 2, 3, 5, 7, 9, 10, 12 ],
+ LYDIEN : [ -12, -10, -8, -6, -5, -3, -1, 0, 2, 4, 6, 7, 9, 11, 12 ],
+ MYXOLYDIEN : [ -12, -10, -8, -7, -5, -3, -2, 0, 2, 4, 5, 7, 9, 10, 12 ]}
+
+
+ # Default parameters for algorithmic generation
+
+ RYTHM_DENSITY_BANK = [.25, .88, .72, 1, .25]
+ RYTHM_REGU_BANK = [.75, .8, .85, .4, .5]
+ PITCH_REGU_BANK = [.5, .8, 0, .85, .9]
+ PITCH_STEP_BANK = [.5, .3, 1, .22, .85]
+ DURATION_BANK = [.8, 1, .8, 1, 1]
+ SILENCE_BANK = [.2, .5, .25, .55, .12]
+ SCALE_BANK = [MAJOR, NATURAL_MINOR, LYDIEN, HARMONIC_MINOR, MYXOLYDIEN]
+
+ chooseDefault = random.randint(0,4)
+ DEFAULT_DENSITY = RYTHM_DENSITY_BANK[chooseDefault]
+ DEFAULT_RYTHM_REGULARITY = RYTHM_REGU_BANK[chooseDefault]
+ DEFAULT_PITCH_REGULARITY = PITCH_REGU_BANK[chooseDefault]
+ DEFAULT_STEP = PITCH_STEP_BANK[chooseDefault]
+ DEFAULT_DURATION = DURATION_BANK[chooseDefault]
+ DEFAULT_SILENCE = SILENCE_BANK[chooseDefault]
+ DEFAULT_PATTERN = [random.randint(0,3) for x in range(4)]
+ DEFAULT_SCALE = SCALE_BANK[chooseDefault]
+
+ DEFAULT_RYTHM_METHOD = 0
+ DEFAULT_PITCH_METHOD = 0
+ DEFAULT_PAN = 0.5
+
+ DEFAULT_PITCH_VARIATION = 0 # 0 = 'melodic' 1 = 'harmonic'
+ DEFAULT_RYTHM_VARIATION = 0 # 0 = 'Cellule' 1 = 'Xnoise'
+
+ DEFAULT_TONIQUE = 36
+
+ I = [ 0, 2, 4, 7, 9, 11, 14 ]
+ II = [ 1, 3, 5, 8, 10, 12 ]
+ III = [ 2, 4, 6, 9, 11, 13 ]
+ IV = [ 0, 3, 5, 7, 10, 12, 14 ]
+ V = [ 1, 4, 6, 8, 11, 13 ]
+ VI = [ 0, 2, 5, 7, 9, 12, 14 ]
+ VII = [ 1, 3, 6, 8, 10, 13 ]
+
+ CHORDS_TABLE = [ I, V, I, II, V, I, VI, II, V, I, IV, VI, II, V, I, V, VI ]
+# CHORDS_TABLE = [I, V, I, V, I, V, I, V, I, V, I, V, I, V ]
+ # pitch patterns constants
+ # PITCH_PATTERNS = [ 'Drunk', 'DroneAndJump', 'Repeter', 'Loopseg' ]
+
+ # Parameters for probability scaling function
+ REPETITION_SCALE_MIN_MAPPING = 0
+ REPETITION_SCALE_MAX_MAPPING = 25
+ REPETITION_SCALE_STEPS = 25
+ DENSITY_SCALE_MIN_MAPPING = 0
+ DENSITY_SCALE_MAX_MAPPING = 38
+ DENSITY_SCALE_STEPS = 38
+ ARTICULATION_SCALE_MIN_MAPPING = .6
+ ARTICULATION_SCALE_MAX_MAPPING = 1
+ ARTICULATION_SCALE_STEPS = 10
+
+ # Rythmic durations, in ticks, and how many to complete figure (celluleRythmSequence)
+ DOUBLE_TICK_DUR = 3
+ DOUBLE_HOW_MANY = 2
+ HALF_TRIPLET_TICK_DUR = 4
+ HALF_TRIPLET_HOW_MANY = 3
+ HOLE_TRIPLET_TICK_DUR = 8
+ HOLE_TRIPLET_HOW_MANY = 3
+
+ # Random generators default values (xnoiseRythmSequence)
+ RANDOM_BETA_PARAM = 0.004
+ RANDOM_EXPO_PARAM = 5
+ RANDOM_GAUSS_PARAM1 = 0.5
+ RANDOM_GAUSS_PARAM2 = 0.1
+ RANDOM_WEIBULL_PARAM1 = 0.5
+
+ RANDOM_WEIBULL_PARAM2 = 2.5
+
+ # Onsets probability tables (drumRythmSequence)
+
+ PUNCH_ACCENTS = [ [],
+ [ 0 ],
+ [ 0, 1 ],
+ [ 0, 2, 1 ],
+ [ 0, 2, 3, 1 ],
+ [ 0, 3, 2, 4, 1],
+ [ 0, 3, 2, 5, 1, 4 ],
+ [ 0, 2, 4, 6, 5, 3, 1 ],
+ [ 0, 4, 2, 6, 3, 7, 5, 1 ],
+ [ 0, 4, 6, 2, 8, 5, 3, 7, 1],
+ [ 0, 6, 4, 8, 2, 5, 7, 3, 9, 1],
+ [ 0, 4, 6, 10, 8, 2, 5, 7, 9, 3, 1],
+ [0, 6, 4, 2, 8, 10, 7, 5, 3, 9, 11, 1] ]
+
+
+ LOW_ACCENTS = [ [],
+ [ 0 ],
+ [ 0, 1 ],
+ [ 0, 2, 1 ],
+ [ 0, 2, 3, 1 ],
+ [ 0, 3, 2, 4, 1 ],
+ [ 0, 3, 2, 5, 1, 4 ],
+ [ 0, 2, 4, 6, 5, 3, 1 ],
+ [ 0, 4, 2, 6, 3, 7, 5, 1 ],
+ [ 0, 4, 6, 2, 8, 5, 3, 7, 1 ],
+ [ 0, 6, 4, 8, 2, 5, 7, 3, 9, 1 ],
+ [ 0, 4, 6, 10, 8, 2, 5, 7, 9, 3, 1 ],
+ [0, 6, 4, 2, 8, 10, 7, 5, 3, 9, 11, 1 ] ]
+
+ MID_ACCENTS = [ [],
+ [ 0, 1 ],
+ [ 0, 2, 3, 1 ],
+ [ 0, 2, 4, 3, 1, 5 ],
+ [ 0, 4, 6, 2, 7, 1, 3, 5 ],
+ [ 0, 6, 4, 8, 2, 1, 5, 3, 9, 7 ],
+ [ 0, 6, 11, 5, 3, 9, 10, 2, 8, 7, 1, 4 ],
+ [ 0, 4, 8, 12, 10, 13, 11, 9, 3, 2, 6, 5, 7, 1 ],
+ [ 0, 8, 4, 12, 6, 14, 2, 10, 7, 15, 1, 9, 3, 11, 5, 13 ],
+ [ 0, 8, 16, 4, 12, 14, 6, 2, 10, 7, 15, 1, 9, 3, 17, 11, 5, 13],
+ [ 0, 10, 8, 4, 16, 12, 6, 14, 18, 2, 7, 9, 15, 3, 1, 19, 5, 11, 13, 17],
+ [ 0, 8, 10, 16, 4, 20, 6, 12, 18, 14, 2, 9, 7, 3, 15, 21, 19, 1, 5, 11, 17, 13],
+ [ 0, 10, 8, 4, 16, 6, 20, 22, 18, 12, 2, 14, 7, 9, 15, 3, 19, 1, 21, 5, 23, 17, 11, 13] ]
+
+ HIGH_ACCENTS = [ [],
+ [ 1, 0 ],
+ [ 1, 3, 2, 0 ],
+ [ 5, 1, 3, 4, 2, 0 ],
+ [ 5, 3, 1, 7, 2, 6, 4, 0 ],
+ [ 7, 9, 3, 5, 1, 2, 8, 4, 6, 0 ],
+ [ 4, 1, 7, 5, 3, 9, 10, 2, 8, 11, 6, 0 ],
+ [ 1, 7, 8, 5, 10, 13, 11, 9, 3, 2, 6, 12, 4, 0 ],
+ [ 13, 5, 11, 3, 9, 1, 15, 10, 7, 2, 14, 6, 12, 4, 8, 0 ],
+ [ 13, 5, 11, 17, 3, 9, 1, 15, 7, 10, 2, 6, 14, 12, 4, 16, 8, 0 ],
+ [ 17, 13, 11, 5, 19, 1, 3, 15, 9, 7, 2, 18, 14, 6, 12, 16, 4, 8, 10, 0 ],
+ [ 13, 17, 11, 5, 1, 19, 21, 15, 3, 7, 9, 2, 14, 18, 12, 6, 20, 4, 16, 10, 8, 0 ],
+ [ 13, 11, 17, 23, 5, 21, 1, 19, 3, 15, 9, 7, 14, 2, 12, 18, 22, 20, 6, 16, 4, 8, 10, 0 ] ]
+
+ DRUM_PUNCH_ACCENTS = [[], [0], [0, 12], [0, 24, 12], [0, 24, 36, 12], [0, 36, 24, 48, 12], [0, 36, 24, 60, 12, 48], [0, 24, 48, 72, 60, 36, 12], [0, 48, 24, 72, 36, 84, 60, 12], [0, 48, 72, 24, 96, 60, 36, 84, 12], [0, 72, 48, 96, 24, 60, 84, 36, 108, 12], [0, 48, 72, 120, 96, 24, 60, 84, 108, 36, 12], [0, 72, 48, 24, 96, 120, 84, 60, 36, 108, 132, 12]]
+ DRUM_LOW_ACCENTS = [[], [0], [0, 12], [0, 24, 12], [0, 24, 36, 12], [0, 36, 24, 48, 12], [0, 36, 24, 60, 12, 48], [0, 24, 48, 72, 60, 36, 12], [0, 48, 24, 72, 36, 84, 60, 12], [0, 48, 72, 24, 96, 60, 36, 84, 12], [0, 72, 48, 96, 24, 60, 84, 36, 108, 12], [0, 48, 72, 120, 96, 24, 60, 84, 108, 36, 12], [0, 72, 48, 24, 96, 120, 84, 60, 36, 108, 132, 12]]
+ DRUM_MID_ACCENTS = [[], [0, 6], [0, 12, 18, 6], [0, 12, 24, 18, 6, 30], [0, 24, 36, 12, 42, 6, 18, 30], [0, 36, 24, 48, 12, 6, 30, 18, 54, 42], [0, 36, 66, 30, 18, 54, 60, 12, 48, 42, 6, 24], [0, 24, 48, 72, 60, 78, 66, 54, 18, 12, 36, 30, 42, 6], [0, 48, 24, 72, 36, 84, 12, 60, 42, 90, 6, 54, 18, 66, 30, 78], [0, 48, 96, 24, 72, 84, 36, 12, 60, 42, 90, 6, 54, 18, 102, 66, 30, 78], [0, 60, 48, 24, 96, 72, 36, 84, 108, 12, 42, 54, 90, 18, 6, 114, 30, 66, 78, 102], [0, 48, 60, 96, 24, 120, 36, 72, 108, 84, 12, 54, 42, 18, 90, 126, 114, 6, 30, 66, 102, 78], [0, 60, 48, 24, 96, 36, 120, 132, 108, 72, 12, 84, 42, 54, 90, 18, 114, 6, 126, 30, 138, 102, 66, 78]]
+ DRUM_HIGH_ACCENTS = [[], [6, 0], [6, 18, 12, 0], [30, 6, 18, 24, 12, 0], [30, 18, 6, 42, 12, 36, 24, 0], [42, 54, 18, 30, 6, 12, 48, 24, 36, 0], [24, 6, 42, 30, 18, 54, 60, 12, 48, 66, 36, 0], [6, 42, 48, 30, 60, 78, 66, 54, 18, 12, 36, 72, 24, 0], [78, 30, 66, 18, 54, 6, 90, 60, 42, 12, 84, 36, 72, 24, 48, 0], [78, 30, 66, 102, 18, 54, 6, 90, 42, 60, 12, 36, 84, 72, 24, 96, 48, 0], [102, 78, 66, 30, 114, 6, 18, 90, 54, 42, 12, 108, 84, 36, 72, 96, 24, 48, 60, 0], [78, 102, 66, 30, 6, 114, 126, 90, 18, 42, 54, 12, 84, 108, 72, 36, 120, 24, 96, 60, 48, 0], [78, 66, 102, 138, 30, 126, 6, 114, 18, 90, 54, 42, 84, 12, 72, 108, 132, 120, 36, 96, 24, 48, 60, 0]]
+
+ # Gain boundaries
+ GAIN_MAX_BOUNDARY = 1.
+ GAIN_MID_MAX_BOUNDARY = .9
+ GAIN_MID_MIN_BOUNDARY = .75
+ GAIN_MIN_BOUNDARY = .65
+
+ # pitch mapping for drum kit
+ DRUMPITCH = {25: 24, 27: 26, 29: 28, 31: 30, 33: 32, 35: 34, 37: 36, 39: 38, 41: 40, 43: 42, 45: 44, 47: 46 }
+
+ DRUM_COMPLEXITY1 = [ [ 24 ], [30] , [ 40 ], [ 46 ] ]
+ DRUM_COMPLEXITY2 = [ [ 24, 28 ], [ 30, 32 ], [ 36, 40 ], [ 46, 48 ] ]
+ DRUM_COMPLEXITY3 = [ [ 24, 26, 28 ], [ 30, 32, 34 ], [ 36, 38, 40 ], [ 42, 46, 48 ] ]
+ DRUM_COMPLEXITY4 = [ [ 24, 26, 28 ], [ 30, 32, 34 ], [ 36, 38, 40 ], [ 42, 44, 46, 48 ] ]
+
+ TRANSPOSE = [0.5, 0.52973154717964765, 0.56123102415468651, 0.59460355750136051, 0.6299605249474366, 0.66741992708501718, 0.70710678118654757, 0.74915353843834076, 0.79370052598409979, 0.8408964152537145, 0.89089871814033927, 0.94387431268169353, 1.0, 1.0594630943592953, 1.122462048309373, 1.189207115002721, 1.2599210498948732, 1.3348398541700344, 1.4142135623730951, 1.4983070768766815, 1.5874010519681994, 1.681792830507429, 1.7817974362806785, 1.8877486253633868, 2.0]
+
+ CELLULES_MARKERS = [ 8, 16, 21, 24 ]
+ CELLULES = [ [ 3, 3, 3, 3 ], [ 3, 3, 6 ], [ 3, 6, 3 ], [ 6, 3, 3 ], [ 4, 4, 4 ], [ 4, 8 ], [ 8, 4 ], [ 6, 6 ], [ 12 ], [ 6, 12, 6 ], [ 8, 8, 8 ], [ 8, 16 ], [ 16, 8 ], [ 12, 12 ], [ 18, 6 ],
+ [ 6, 18 ], [ 24 ], [ 12, 12, 12 ], [ 18, 18 ], [ 24, 12 ], [ 12, 24 ], [ 36 ], [ 12, 24, 12 ], [ 24, 24 ], [ 48 ] ]
diff --git a/common/Generation/GenerationParametersWindow.py b/common/Generation/GenerationParametersWindow.py
new file mode 100755
index 0000000..bde409d
--- /dev/null
+++ b/common/Generation/GenerationParametersWindow.py
@@ -0,0 +1,383 @@
+import pygtk
+pygtk.require('2.0')
+import gtk
+import shelve
+from Generation.Generator import GenerationParameters
+from Generation.GenerationConstants import GenerationConstants
+from Util.ThemeWidgets import *
+import Config
+
+Tooltips = Config.Tooltips()
+
+class GenerationParametersWindow( gtk.VBox ):
+ def __init__( self, generateFunction, handleCloseWindowCallback ):
+ gtk.VBox.__init__( self )
+ self.handleCloseWindowCallback = handleCloseWindowCallback
+ self.tooltips = gtk.Tooltips()
+
+ self.rythmMethod = GenerationConstants.DEFAULT_RYTHM_METHOD
+ self.pitchMethod = GenerationConstants.DEFAULT_PITCH_METHOD
+ self.pattern = GenerationConstants.DEFAULT_PATTERN
+ self.scale = GenerationConstants.DEFAULT_SCALE
+ self.sourceVariation = 1
+ self.generateFunction = generateFunction
+ self.setupWindow()
+ self.show_all()
+
+ def setupWindow( self ):
+ self.GUI = {}
+ self.rythmDensity = GenerationConstants.DEFAULT_DENSITY
+ self.rythmRegularity = GenerationConstants.DEFAULT_RYTHM_REGULARITY
+ self.pitchRegularity = GenerationConstants.DEFAULT_PITCH_REGULARITY
+ self.pitchStep = GenerationConstants.DEFAULT_STEP
+ self.duration = GenerationConstants.DEFAULT_DURATION
+ self.silence = GenerationConstants.DEFAULT_SILENCE
+
+ # Generation Panel Setup
+ generationBox = RoundVBox(fillcolor=Config.INST_BCK_COLOR, bordercolor=Config.PANEL_BCK_COLOR)
+ generationBox.set_border_width(1)
+ generationBox.set_radius(10)
+ XYSlidersBox = gtk.HBox()
+
+ self.col = gtk.gdk.color_parse(Config.PANEL_COLOR)
+
+ XYSlider1Box = gtk.VBox()
+ XYSlider1UpBox = RoundHBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
+ XYSlider1UpBox.set_border_width(3)
+ XYSlider1UpBox.set_radius(10)
+ self.XYSlider1DownBox = RoundHBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
+ self.XYSlider1DownBox.set_border_width(3)
+ self.XYSlider1DownBox.set_radius(10)
+
+ self.slider1Label = gtk.DrawingArea()
+ self.slider1Label.modify_bg(gtk.STATE_NORMAL, self.col)
+ colormap = self.slider1Label.get_colormap()
+ self.bgColor = colormap.alloc_color( Config.PANEL_COLOR, True, True )
+ self.slider1Label.set_size_request(228, 60)
+ self.slider1Label.connect("expose-event", self.draw )
+ XYSliderBox1 = self.formatRoundBox( RoundFixed(), Config.PANEL_COLOR )
+ XYSliderBox1.set_size_request( 250, 250 )
+ self.GUI["XYButton1"] = ImageToggleButton( Config.IMAGE_ROOT+"XYbut.png", Config.IMAGE_ROOT+"XYbutDown.png", backgroundFill=Config.PANEL_COLOR )
+ self.XAdjustment1 = gtk.Adjustment( self.rythmDensity*100, 0, 100, 1, 1, 1 )
+ self.XAdjustment1.connect("value-changed", self.handleXAdjustment1)
+ self.YAdjustment1 = gtk.Adjustment( self.rythmRegularity*100, 0, 100, 1, 1, 1 )
+ self.YAdjustment1.connect("value-changed", self.handleYAdjustment1)
+ self.GUI["xySlider1"] = XYSlider( XYSliderBox1, self.GUI["XYButton1"], self.XAdjustment1, self.YAdjustment1, False, True )
+ XYSlider1UpBox.pack_start( self.GUI["xySlider1"], False, False )
+
+ self.XYSlider1DownBox.pack_start(self.slider1Label, False, False, 5)
+ XYSlider1Box.pack_start(XYSlider1UpBox)
+ XYSlider1Box.pack_start(self.XYSlider1DownBox)
+ XYSlidersBox.pack_start(XYSlider1Box, False, False, 5)
+
+
+ XYSlider2Box = gtk.VBox()
+ XYSlider2UpBox = RoundHBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
+ XYSlider2UpBox.set_border_width(3)
+ XYSlider2UpBox.set_radius(10)
+ self.XYSlider2DownBox = RoundHBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
+ self.XYSlider2DownBox.set_border_width(3)
+ self.XYSlider2DownBox.set_radius(10)
+
+ self.slider2Label = gtk.DrawingArea()
+ self.slider2Label.modify_bg(gtk.STATE_NORMAL, self.col)
+ self.slider2Label.set_size_request(228, 60)
+ self.slider2Label.connect("expose-event", self.draw2 )
+ XYSliderBox2 = self.formatRoundBox( RoundFixed(), Config.PANEL_COLOR )
+ XYSliderBox2.set_size_request( 250, 250 )
+ self.GUI["XYButton2"] = ImageToggleButton( Config.IMAGE_ROOT+"XYbut.png", Config.IMAGE_ROOT+"XYbutDown.png", backgroundFill=Config.PANEL_COLOR )
+ self.XAdjustment2 = gtk.Adjustment( self.pitchRegularity*100, 0, 100, 1, 1, 1 )
+ self.XAdjustment2.connect("value-changed", self.handleXAdjustment2)
+ self.YAdjustment2 = gtk.Adjustment( self.pitchStep*100, 0, 100, 1, 1, 1 )
+ self.YAdjustment2.connect("value-changed", self.handleYAdjustment2)
+ self.GUI["xySlider2"] = XYSlider( XYSliderBox2, self.GUI["XYButton2"], self.XAdjustment2, self.YAdjustment2, False, True )
+ XYSlider2UpBox.pack_start( self.GUI["xySlider2"], False, False )
+
+ self.XYSlider2DownBox.pack_start(self.slider2Label, False, False, 5)
+ XYSlider2Box.pack_start(XYSlider2UpBox)
+ XYSlider2Box.pack_start(self.XYSlider2DownBox)
+ XYSlidersBox.pack_start(XYSlider2Box, False, False, 5)
+
+
+ XYSlider3Box = gtk.VBox()
+ XYSlider3UpBox = RoundHBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
+ XYSlider3UpBox.set_border_width(3)
+ XYSlider3UpBox.set_radius(10)
+ self.XYSlider3DownBox = RoundHBox(fillcolor=Config.PANEL_COLOR, bordercolor=Config.INST_BCK_COLOR)
+ self.XYSlider3DownBox.set_border_width(3)
+ self.XYSlider3DownBox.set_radius(10)
+
+ self.slider3Label = gtk.DrawingArea()
+ self.slider3Label.modify_bg(gtk.STATE_NORMAL, self.col)
+ self.slider3Label.set_size_request(228, 60)
+ self.slider3Label.connect("expose-event", self.draw3 )
+ XYSliderBox3 = self.formatRoundBox( RoundFixed(), Config.PANEL_COLOR )
+ XYSliderBox3.set_size_request( 250, 250 )
+ self.GUI["XYButton3"] = ImageToggleButton( Config.IMAGE_ROOT+"XYbut.png", Config.IMAGE_ROOT+"XYbutDown.png", backgroundFill=Config.PANEL_COLOR )
+ self.XAdjustment3 = gtk.Adjustment( self.duration*100, 0, 100, 1, 1, 1 )
+ self.XAdjustment3.connect("value-changed", self.handleXAdjustment3)
+ self.YAdjustment3 = gtk.Adjustment( self.silence*100, 0, 100, 1, 1, 1 )
+ self.YAdjustment3.connect("value-changed", self.handleYAdjustment3)
+ self.GUI["xySlider3"] = XYSlider( XYSliderBox3, self.GUI["XYButton3"], self.XAdjustment3, self.YAdjustment3, False, True )
+ XYSlider3UpBox.pack_start( self.GUI["xySlider3"], False, False )
+
+ self.XYSlider3DownBox.pack_start(self.slider3Label, False, False, 5)
+ XYSlider3Box.pack_start(XYSlider3UpBox)
+ XYSlider3Box.pack_start(self.XYSlider3DownBox)
+ XYSlidersBox.pack_start(XYSlider3Box, False, False, 5)
+
+ generationBox.pack_start(XYSlidersBox, False, False, 5)
+
+ self.pack_start(generationBox)
+
+ # Meta Algo panel setup
+ metaAlgoBox = RoundVBox(fillcolor=Config.INST_BCK_COLOR, bordercolor=Config.PANEL_BCK_COLOR)
+ metaAlgoBox.set_border_width(1)
+ metaAlgoBox.set_radius(10)
+
+ methodBox = gtk.HBox()
+ self.firstButton = None
+ methodNames = ['drunk', 'droneJump', 'repeat', 'loopSeg']
+ for meth in methodNames:
+ self.GUI[meth] = ImageRadioButton(self.firstButton, Config.IMAGE_ROOT + meth + '.png', Config.IMAGE_ROOT + meth + 'Down.png', Config.IMAGE_ROOT + meth + 'Over.png', backgroundFill=Config.INST_BCK_COLOR )
+ if self.firstButton == None:
+ self.firstButton = self.GUI[meth]
+ self.GUI[meth].connect('clicked' , self.handleMethod , methodNames.index(meth))
+ if methodNames.index(meth) == self.pattern:
+ self.GUI[meth].set_active(True)
+ methodBox.pack_start(self.GUI[meth], False, False)
+ metaAlgoBox.pack_start(methodBox, False, False, 5)
+
+ scaleBox = gtk.HBox()
+ self.firstButton = None
+ scaleNames = ['majorKey', 'minorHarmKey', 'minorKey', 'phrygienKey', 'dorienKey', 'lydienKey', 'myxoKey']
+ for scale in scaleNames:
+ self.GUI[scale] = ImageRadioButton(self.firstButton, Config.IMAGE_ROOT + scale + '.png', Config.IMAGE_ROOT + scale + 'Down.png', Config.IMAGE_ROOT + scale + 'Over.png', backgroundFill=Config.INST_BCK_COLOR )
+ if self.firstButton == None:
+ self.firstButton = self.GUI[scale]
+ self.GUI[scale].connect('clicked' , self.handleScale , scaleNames.index(scale))
+ if scaleNames.index(scale) == self.scale:
+ self.GUI[scale].set_active(True)
+ scaleBox.pack_start(self.GUI[scale], False, False)
+ metaAlgoBox.pack_start(scaleBox, False, False)
+
+ self.pack_start(metaAlgoBox)
+
+ # Transport Panel Setup
+ transportBox = RoundVBox(fillcolor=Config.INST_BCK_COLOR, bordercolor=Config.PANEL_BCK_COLOR)
+ transportBox.set_border_width(1)
+ transportBox.set_radius(10)
+
+ # Create save/load presets
+ transButtonBox = RoundHBox(fillcolor=Config.INST_BCK_COLOR, bordercolor=Config.PANEL_BCK_COLOR)
+ transButtonBox.set_radius(10)
+
+ self.GUI["saveButton"] = ImageButton(Config.TAM_TAM_ROOT + '/Resources/Images/save.png', backgroundFill=Config.INST_BCK_COLOR )
+ self.GUI["saveButton"].connect("clicked", self.handleSave, None)
+ #transButtonBox.pack_start(self.GUI["saveButton"], False, False, 2)
+
+ self.GUI["loadButton"] = ImageButton(Config.TAM_TAM_ROOT + '/Resources/Images/load.png', backgroundFill=Config.INST_BCK_COLOR )
+ self.GUI["loadButton"].connect("clicked", self.handleLoad, None)
+ #transButtonBox.pack_start(self.GUI["loadButton"], False, False, 2)
+
+ # create cancel/check button
+ self.GUI["checkButton"] = ImageButton(Config.IMAGE_ROOT + 'check.png', backgroundFill=Config.INST_BCK_COLOR )
+ self.GUI["checkButton"].connect("clicked", self.generate)
+
+ self.GUI["cancelButton"] = ImageButton(Config.IMAGE_ROOT + 'closeA.png', backgroundFill=Config.INST_BCK_COLOR )
+ self.GUI["cancelButton"].connect("clicked", self.cancel)
+
+ # create play/stop buttons
+ playButton = ImageToggleButton(Config.IMAGE_ROOT + 'playTogOff.png', Config.IMAGE_ROOT + 'playTogOn.png', backgroundFill=Config.INST_BCK_COLOR )
+ selButton = ImageToggleButton(Config.IMAGE_ROOT + 'playAll.png', Config.IMAGE_ROOT + 'playSel.png', backgroundFill=Config.INST_BCK_COLOR )
+ transButtonBox.pack_end(self.GUI["checkButton"], False, False, 10)
+ transButtonBox.pack_end(self.GUI["cancelButton"], False, False)
+ #transButtonBox.pack_end(selButton, False, False)
+ #transButtonBox.pack_end(playButton, False, False)
+ transportBox.pack_start(transButtonBox)
+
+ self.pack_start(transportBox)
+ self.loadPixmaps()
+ # set tooltips
+ for key in self.GUI:
+ if Tooltips.ALGO.has_key(key):
+ self.tooltips.set_tip(self.GUI[key],Tooltips.ALGO[key])
+
+ def loadPixmaps( self ):
+ win = gtk.gdk.get_default_root_window()
+ self.gc = gtk.gdk.GC( win )
+ self.gc.foreground = self.bgColor
+
+ self.arrowPixmap = []
+ for i in range(2):
+ pix = gtk.gdk.pixbuf_new_from_file(Config.IMAGE_ROOT + ['arrowSide.png', 'arrowUp.png'][i])
+ map = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ map.draw_rectangle( self.gc, True, 0, 0, pix.get_width(), pix.get_height() )
+ map.draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.arrowPixmap.append(map)
+
+ self.rythDensPixmap = []
+ self.rythRegPixmap = []
+ self.pitchRegPixmap = []
+ self.pitchStepPixmap = []
+ self.durPixmap = []
+ self.silencePixmap = []
+ pixmaps = [self.rythDensPixmap, self.rythRegPixmap, self.pitchRegPixmap, self.pitchStepPixmap, self.durPixmap, self.silencePixmap]
+ pixmapNames = ['rythDens', 'rythReg', 'pitReg', 'pitStep', 'durLen', 'durDens']
+
+ for inc in range(6):
+ imgName = pixmapNames[inc]
+ pixmap = pixmaps[inc]
+ for i in range(6):
+ pix = gtk.gdk.pixbuf_new_from_file(Config.IMAGE_ROOT + imgName + str(i+1) + '.png')
+ map = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ map.draw_rectangle( self.gc, True, 0, 0, pix.get_width(), pix.get_height() )
+ map.draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ pixmap.append(map)
+
+
+ def draw( self, widget, event ):
+ imgX = 5 - int(self.rythmDensity * 5)
+ imgY = 5 - int(self.rythmRegularity * 5)
+ widget.window.draw_drawable( self.gc, self.arrowPixmap[0], 0, 0, 0, 18, 24, 24 )
+ widget.window.draw_drawable( self.gc, self.rythDensPixmap[imgX], 0, 0, 24, 0, 90, 60 )
+ widget.window.draw_drawable( self.gc, self.arrowPixmap[1], 0, 0, 114, 18, 24, 24 )
+ widget.window.draw_drawable( self.gc, self.rythRegPixmap[imgY], 0, 0, 138, 0, 90, 60 )
+ return True
+
+ def draw2( self, widget, event ):
+ imgX = 5 - int(self.pitchRegularity * 5)
+ imgY = 5 - int(self.pitchStep * 5)
+ widget.window.draw_drawable( self.gc, self.arrowPixmap[0], 0, 0, 0, 18, 24, 24 )
+ widget.window.draw_drawable( self.gc, self.pitchRegPixmap[imgX], 0, 0, 24, 0, 90, 60 )
+ widget.window.draw_drawable( self.gc, self.arrowPixmap[1], 0, 0, 114, 18, 24, 24 )
+ widget.window.draw_drawable( self.gc, self.pitchStepPixmap[imgY], 0, 0, 138, 0, 90, 60 )
+ return True
+
+ def draw3( self, widget, event ):
+ imgX = int(self.duration * 5)
+ imgY = int(self.silence * 5)
+ widget.window.draw_drawable( self.gc, self.arrowPixmap[0], 0, 0, 0, 18, 24, 24 )
+ widget.window.draw_drawable( self.gc, self.durPixmap[imgX], 0, 0, 24, 0, 90, 60 )
+ widget.window.draw_drawable( self.gc, self.arrowPixmap[1], 0, 0, 114, 18, 24, 24 )
+ widget.window.draw_drawable( self.gc, self.silencePixmap[imgY], 0, 0, 138, 0, 90, 60 )
+ return True
+
+
+ def handleXAdjustment1( self, data ):
+ self.rythmDensity = self.XAdjustment1.value * .01
+ self.slider1Label.queue_draw()
+
+ def handleYAdjustment1( self, data ):
+ self.rythmRegularity = self.YAdjustment1.value * .01
+ self.slider1Label.queue_draw()
+
+ def handleXAdjustment2( self, data ):
+ self.pitchRegularity = self.XAdjustment2.value * .01
+ self.slider2Label.queue_draw()
+
+ def handleYAdjustment2( self, data ):
+ self.pitchStep = self.YAdjustment2.value * .01
+ self.slider2Label.queue_draw()
+
+ def handleXAdjustment3( self, data ):
+ self.duration = self.XAdjustment3.value * .01
+ self.slider3Label.queue_draw()
+
+ def handleYAdjustment3( self, data ):
+ self.silence = self.YAdjustment3.value * .01
+ self.slider3Label.queue_draw()
+
+
+ def getGenerationParameters( self ):
+ return GenerationParameters( self.rythmDensity,
+ self.rythmRegularity,
+ self.pitchStep,
+ self.pitchRegularity,
+ self.duration,
+ self.silence,
+ self.rythmMethod,
+ self.pitchMethod,
+ self.pattern,
+ self.scale )
+
+ def cancel( self, widget, data=None ):
+ self.handleCloseWindowCallback()
+
+ def generate(self, widget, data=None):
+ self.generateFunction( self.getGenerationParameters() )
+ self.handleCloseWindowCallback()
+
+ def handleMethod( self, widget, method ):
+ if widget.get_active():
+ self.pattern = method
+
+ def handleScale( self, widget, scale ):
+ if widget.get_active():
+ self.scale = scale
+
+ def formatRoundBox( self, box, fillcolor ):
+ box.set_radius( 10 )
+ box.set_border_width( 1 )
+ box.set_fill_color( fillcolor )
+ box.set_border_color( Config.INST_BCK_COLOR )
+ return box
+
+
+#=========================== PRESETS ================================
+
+ def handleSave(self, widget, data):
+ chooser = gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE,gtk.RESPONSE_OK))
+
+ if chooser.run() == gtk.RESPONSE_OK:
+ try:
+ print 'INFO: save preset file %s' % chooser.get_filename()
+ f = shelve.open( chooser.get_filename(), 'n')
+ self.saveState(f)
+ f.close()
+ except IOError:
+ print 'ERROR: failed to save preset to file %s' % chooser.get_filename()
+
+ chooser.destroy()
+
+ def handleLoad(self, widget, data):
+
+ chooser = gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
+
+ if chooser.run() == gtk.RESPONSE_OK:
+ try:
+ print 'INFO: load preset state from file %s' % chooser.get_filename()
+ f = shelve.open( chooser.get_filename(), 'r')
+ self.loadState(f)
+ f.close()
+ except IOError:
+ print 'ERROR: failed to load preset state from file %s' % chooser.get_filename()
+
+ def loadState( self, state ):
+ pass
+ self.rythmDensity = state['rythmDensity']
+ self.rythmRegularity = state['rythmRegularity']
+ self.pitchRegularity = state['pitchRegularity']
+ self.pitchStep = state['pitchStep']
+ self.duration = state['duration']
+ self.silence = state['silence']
+ self.pattern = state['pattern']
+ self.scale = state['scale']
+
+ self.XAdjustment1.set_value(self.rythmDensity*100)
+ self.YAdjustment1.set_value(self.rythmRegularity*100)
+ self.XAdjustment2.set_value(self.pitchRegularity*100)
+ self.YAdjustment2.set_value(self.pitchStep*100)
+ self.XAdjustment3.set_value(self.duration*100)
+ self.YAdjustment3.set_value(self.silence*100)
+
+ def saveState( self, state ):
+ pass
+ state['rythmDensity'] = self.rythmDensity
+ state['rythmRegularity'] = self.rythmRegularity
+ state['pitchRegularity'] = self.pitchRegularity
+ state['pitchStep'] = self.pitchStep
+ state['duration'] = self.duration
+ state['silence'] = self.silence
+ state['pattern'] = self.pattern
+ state['scale'] = self.scale
diff --git a/common/Generation/GenerationPitch.py b/common/Generation/GenerationPitch.py
new file mode 100644
index 0000000..4012589
--- /dev/null
+++ b/common/Generation/GenerationPitch.py
@@ -0,0 +1,40 @@
+import random
+import Drunk
+
+import common.Config as Config
+from Generation.GenerationConstants import GenerationConstants
+
+class GenerationPitch:
+ def __init__( self ):
+ MIN = 0
+ MAX = 14
+ self.drunkMethod = Drunk.Drunk( MIN, MAX )
+ self.droneMethod = Drunk.DroneAndJump( MIN, MAX )
+ self.repeatMethod = Drunk.Repeter( MIN, MAX )
+ self.loopMethod = Drunk.Loopseg( MIN, MAX )
+ self.methodList = [self.drunkMethod, self.droneMethod, self.repeatMethod, self.loopMethod]
+
+ def drunkPitchSequence(self, length, parameters, table_pitch, trackId):
+ pitchSequence = []
+ append = pitchSequence.append
+ numberOfPitch = int( ( 1 - (parameters.pitchRegularity*.8) ) * 10 + 1 )
+ step = -(int(parameters.step * 10))
+ max = len(table_pitch)-1
+ nextValue = self.methodList[parameters.pattern[trackId]].getNextValue
+ tonique = GenerationConstants.DEFAULT_TONIQUE
+ for i in range(numberOfPitch):
+ append((table_pitch[nextValue(step, max)]) + tonique)
+ restOfNotes = range( length - numberOfPitch )
+ for i in restOfNotes:
+ position = i % numberOfPitch
+ append( pitchSequence[ position ] )
+ return pitchSequence
+
+ def drumPitchSequence(self, length, parameters, drumPitch, table_pitch=None):
+ pitchSequence = []
+ append = pitchSequence.append
+ max = len(drumPitch) - 1
+ rand = random.randint
+ for i in range(length):
+ append(drumPitch[ rand( 0, max ) ] )
+ return pitchSequence
diff --git a/common/Generation/GenerationRythm.py b/common/Generation/GenerationRythm.py
new file mode 100644
index 0000000..718c1ec
--- /dev/null
+++ b/common/Generation/GenerationRythm.py
@@ -0,0 +1,213 @@
+import Utils
+import random
+from math import sqrt
+import common.Config as Config
+from Generation.GenerationConstants import GenerationConstants
+
+class GenerationRythm:
+
+ def celluleRythmSequence(self, parameters, barLength, trackInstrument=None ):
+ rythmSequence = [0, ]
+ self.count = 0
+ lastOnsetTime = 0
+ onsetLen = len(GenerationConstants.TABLE_ONSET_VALUES)
+
+ onsetValue = int( ( 1 - (parameters.density*0.98+0.02) ) * onsetLen )
+ onsetDeviation = int( ( 1 - parameters.rythmRegularity ) * 20 )
+ currentOnsetValue = onsetValue + ( random.randint( 0, onsetDeviation ) - ( onsetDeviation / 2 ) )
+ if currentOnsetValue < 0:
+ currentOnsetValue = 0
+ elif currentOnsetValue >= onsetLen:
+ currentOnsetValue = onsetLen - 1
+ else:
+ currentOnsetValue = currentOnsetValue
+
+ onsetDelta = GenerationConstants.TABLE_ONSET_VALUES[ currentOnsetValue ]
+ listLen = range( int( barLength / Config.TICKS_PER_BEAT * 8 ) )
+ randInt = random.randint
+ for i in listLen:
+ if self.count == 0:
+ currentOnsetValue = onsetValue + ( randInt( 0, onsetDeviation ) - ( onsetDeviation / 2 ) )
+ if currentOnsetValue < 0:
+ currentOnsetValue = 0
+ elif currentOnsetValue >= onsetLen:
+ currentOnsetValue = onsetLen - 1
+ else:
+ currentOnsetValue = currentOnsetValue
+ onsetDelta = GenerationConstants.TABLE_ONSET_VALUES[ currentOnsetValue ]
+
+ if onsetDelta == GenerationConstants.DOUBLE_TICK_DUR:
+ if self.count < (GenerationConstants.DOUBLE_HOW_MANY - 1):
+ self.count += 1
+ else:
+ self.count = 0
+ onsetTime = onsetDelta + lastOnsetTime
+ lastOnsetTime = onsetTime
+ if onsetTime < barLength-2:
+ rythmSequence.append(onsetTime)
+ continue
+ else:
+ break
+ elif onsetDelta == GenerationConstants.HALF_TRIPLET_TICK_DUR:
+ if self.count < (GenerationConstants.HALF_TRIPLET_HOW_MANY - 1):
+ self.count += 1
+ else:
+ self.count = 0
+ onsetTime = onsetDelta + lastOnsetTime
+ lastOnsetTime = onsetTime
+ if onsetTime < barLength-2:
+ rythmSequence.append(onsetTime)
+ continue
+ else:
+ break
+ elif onsetDelta == GenerationConstants.HOLE_TRIPLET_TICK_DUR:
+ if self.count < (GenerationConstants.HOLE_TRIPLET_HOW_MANY - 1):
+ self.count += 1
+ else:
+ self.count = 0
+ onsetTime = onsetDelta + lastOnsetTime
+ lastOnsetTime = onsetTime
+ if onsetTime < barLength-2:
+ rythmSequence.append(onsetTime)
+ continue
+ else:
+ break
+
+ onsetTime = onsetDelta + lastOnsetTime
+ lastOnsetTime = onsetTime
+ if onsetTime < barLength-2:
+ rythmSequence.append(onsetTime)
+ else:
+ break
+ return rythmSequence
+
+ def xnoiseRythmSequence(self, parameters, barLength ):
+ rythmSequence = []
+ onsetTime = None
+ randomParamScaler = parameters.rythmRegularity * 2 + 0.5
+# need radioButton with 0 for random choose and each generator independant
+ whichRandomGenerator = random.randint(0, 4)
+ maximumNumberOfNotes = int( (parameters.density) * GenerationConstants.MAX_NOTES_PER_BAR)
+
+ for i in range(maximumNumberOfNotes):
+ while onsetTime in rythmSequence:
+ if whichRandomGenerator == 0:
+ onsetTime = random.expovariate(GenerationConstants.RANDOM_EXPO_PARAM * randomParamScaler)
+ elif whichRandomGenerator == 1:
+ onsetTime = 1 - random.expovariate(GenerationConstants.RANDOM_EXPO_PARAM * randomParamScaler)
+ elif whichRandomGenerator == 2:
+ onsetTime = random.gauss(GenerationConstants.RANDOM_GAUSS_PARAM1,
+ GenerationConstants.RANDOM_GAUSS_PARAM2 * (3 - randomParamScaler))
+ elif whichRandomGenerator == 3:
+ onsetTime = random.betavariate(GenerationConstants.RANDOM_BETA_PARAM * randomParamScaler,
+ GenerationConstants.RANDOM_BETA_PARAM * randomParamScaler)
+ elif whichRandomGenerator == 4:
+ onsetTime = random.weibullvariate(GenerationConstants.RANDOM_WEIBULL_PARAM1,
+ GenerationConstants.RANDOM_WEIBULL_PARAM2 * randomParamScaler)
+
+ onsetTime = int(onsetTime * (int(( barLength - 1) / GenerationConstants.DOUBLE_TICK_DUR))) * GenerationConstants.DOUBLE_TICK_DUR
+
+ if onsetTime < 0:
+ onsetTime = 0
+ elif onsetTime > ( barLength - GenerationConstants.DOUBLE_TICK_DUR):
+ onsetTime = ( barLength - GenerationConstants.DOUBLE_TICK_DUR)
+ else:
+ onsetTime = onsetTime
+
+ rythmSequence.append(onsetTime)
+
+ rythmSequence.sort()
+ return rythmSequence
+
+ def drumRythmSequence(self, parameters, trackInstrument, barLength ):
+ density = sqrt(parameters.density)
+ rythmSequence = []
+ binSelection = []
+ downBeats = []
+ upBeats = []
+ beats = []
+ countDown = 0
+ onsetTime = None
+ beatsPerPage = int( barLength / Config.TICKS_PER_BEAT )
+ randInt = random.randint
+
+ upBeatsAppend = upBeats.append
+
+ if Config.INSTRUMENTS[ trackInstrument ].instrumentRegister == Config.PUNCH:
+ registerDensity = 0.5
+ downBeatRecurence = 4
+ upBeatOffset = Config.TICKS_PER_BEAT / 2
+ downBeats = [x for x in GenerationConstants.DRUM_PUNCH_ACCENTS[ beatsPerPage ]]
+ for downBeat in downBeats:
+ upBeatsAppend( downBeat + upBeatOffset )
+
+ elif Config.INSTRUMENTS[ trackInstrument ].instrumentRegister == Config.LOW:
+ registerDensity = 1.5
+ downBeatRecurence = 4
+ upBeatOffset = Config.TICKS_PER_BEAT / 2
+ downBeats = [x for x in GenerationConstants.DRUM_LOW_ACCENTS[ beatsPerPage ]]
+ for downBeat in downBeats:
+ upBeatsAppend( downBeat + upBeatOffset )
+
+ elif Config.INSTRUMENTS[ trackInstrument ].instrumentRegister == Config.MID:
+ registerDensity = 1
+ downBeatRecurence = 1
+ upBeatOffset = Config.TICKS_PER_BEAT / 4
+ downBeats = [x for x in GenerationConstants.DRUM_MID_ACCENTS[ beatsPerPage ]]
+ for downBeat in downBeats:
+ upBeatsAppend( downBeat + upBeatOffset )
+
+ elif Config.INSTRUMENTS[ trackInstrument ].instrumentRegister == Config.HIGH:
+ registerDensity = 1.5
+ downBeatRecurence = 1
+ upBeatOffset = Config.TICKS_PER_BEAT / 4
+ downBeats = [x for x in GenerationConstants.DRUM_HIGH_ACCENTS[ beatsPerPage ]]
+ for downBeat in downBeats:
+ upBeatsAppend( downBeat + upBeatOffset )
+
+ list = range( int( density * registerDensity * len( downBeats ) ) )
+ rand = random.random
+ binCount = binSelection.count
+ binAppend = binSelection.append
+ for i in list:
+ if rand() < ( parameters.rythmRegularity * downBeatRecurence ) and binCount( 1 ) < len( downBeats ):
+ binAppend( 1 )
+ else:
+ if binCount( 0 ) < len( downBeats ):
+ binAppend( 0 )
+ else:
+ binAppend( 1 )
+
+ countDown = binCount( 1 )
+
+ seqAppend = rythmSequence.append
+ length = len(downBeats) - 1
+ downPop = downBeats.pop
+ for i in range( countDown ):
+ ran1 = randInt(0, length)
+ ran2 = randInt(0, length)
+ randMin = min(ran1, ran2)
+ onsetTime = downPop(randMin)
+ seqAppend( onsetTime )
+ length -= 1
+
+ length = len(upBeats) - 1
+ upPop = upBeats.pop
+ for i in range( len( binSelection ) - countDown ):
+ ran1 = randInt(0, length)
+ ran2 = randInt(0, length)
+ randMin = min(ran1, ran2)
+ onsetTime = upPop(randMin)
+ seqAppend( onsetTime )
+ length -= 1
+
+ rythmSequence.sort()
+ return rythmSequence
+
+ def makeCellule( self, currentDuration, targetDuration, threshold ):
+ threshold = threshold - 1
+ if currentDuration == targetDuration:
+ if self.count < threshold:
+ self.count += 1
+ else:
+ self.count = 0
diff --git a/common/Generation/Generator.py b/common/Generation/Generator.py
new file mode 100755
index 0000000..b5640a6
--- /dev/null
+++ b/common/Generation/Generator.py
@@ -0,0 +1,167 @@
+import random
+import math
+
+import Utils
+import Drunk
+
+import common.Config as Config
+from Util.CSoundNote import CSoundNote
+from Generation.GenerationConstants import GenerationConstants
+from Generation.GenerationRythm import GenerationRythm
+from Generation.GenerationPitch import GenerationPitch
+
+class GenerationParameters:
+ def __init__( self,
+ density = GenerationConstants.DEFAULT_DENSITY,
+ rythmRegularity = GenerationConstants.DEFAULT_RYTHM_REGULARITY,
+ step = GenerationConstants.DEFAULT_STEP,
+ pitchRegularity = GenerationConstants.DEFAULT_PITCH_REGULARITY,
+ articule = GenerationConstants.DEFAULT_DURATION,
+ silence = GenerationConstants.DEFAULT_SILENCE,
+ rythmMethod = GenerationConstants.DEFAULT_RYTHM_METHOD,
+ pitchMethod = GenerationConstants.DEFAULT_PITCH_METHOD,
+ pattern = GenerationConstants.DEFAULT_PATTERN,
+ scale = GenerationConstants.DEFAULT_SCALE ):
+ self.density = density
+ self.rythmRegularity = rythmRegularity
+ self.step = step
+ self.pitchRegularity = pitchRegularity
+ self.articule = articule
+ self.silence = silence
+ self.rythmMethod = rythmMethod
+ self.pitchMethod = pitchMethod
+ self.pattern = pattern
+ self.scale = scale
+
+def generator1(
+ parameters, # algorithm-specific parameters
+ volume, # [trackId: float(volume) ]
+ instrument, # [pageId][trackId: instrument]
+ tempo, # integer bpm
+ nbeats, # map [ pageId : beats ]
+ trackIds, # list of trackIds to generate
+ pageIds, # list of pageIds to generate
+ trackDictionary, # map [ trackId : [ pageId : events ] ]
+ nPagesCycle = 4 # META ALGO number of pages in a section
+ ):
+
+ makeRythm = GenerationRythm()
+ makePitch = GenerationPitch()
+
+ def makeGainSequence( onsetList ):
+ gainSequence = []
+ append = gainSequence.append
+ rand = random.uniform
+ max = GenerationConstants.GAIN_MAX_BOUNDARY
+ midMax = GenerationConstants.GAIN_MID_MAX_BOUNDARY
+ midMin = GenerationConstants.GAIN_MID_MIN_BOUNDARY
+ min = GenerationConstants.GAIN_MIN_BOUNDARY
+ for onset in onsetList:
+ if onset == 0:
+ append(rand(midMax, max))
+ elif ( onset % Config.TICKS_PER_BEAT) == 0:
+ append(rand(midMin, midMax))
+ else:
+ append(rand(min, midMin))
+ return gainSequence
+
+ def makeDurationSequence( onsetList, parameters, table_duration, barLength, currentInstrument ):
+ durationSequence = []
+ if Config.INSTRUMENTS[currentInstrument].soundClass == 'drum':
+ duration = GenerationConstants.DOUBLE_TICK_DUR / 2
+ durationSequence = [duration] * len(onsetList)
+ return durationSequence
+
+ append = durationSequence.append
+ proba = Utils.prob2
+ if len( onsetList ) > 1:
+ for i in range(len(onsetList) - 1):
+ append((onsetList[i+1] - onsetList[i]) * proba( table_duration ))
+ append(( barLength - onsetList[-1]) * proba( table_duration ))
+ elif len( onsetList ) == 1:
+ append( ( barLength - onsetList[0] ) * proba( table_duration ))
+ return durationSequence
+
+ def pageGenerate(parameters, trackId, pageId, trackOfNotes, drumPitch = None):
+
+ trackNotes = trackOfNotes
+
+ if drumPitch:
+ currentInstrument = Config.INSTRUMENTS[instrument[pageId][trackId]].kit[drumPitch[0]].name
+ rythmSequence = makeRythm.drumRythmSequence(parameters, currentInstrument, barLength)
+ pitchSequence = makePitch.drumPitchSequence(len(rythmSequence), parameters, drumPitch, table_pitch )
+ else:
+ currentInstrument = instrument[pageId][trackId]
+ rythmSequence = makeRythm.celluleRythmSequence(parameters, barLength, currentInstrument)
+ pitchSequence = makePitch.drunkPitchSequence(len(rythmSequence),parameters, table_pitch, trackId)
+
+ gainSequence = makeGainSequence(rythmSequence)
+ durationSequence = makeDurationSequence(rythmSequence, parameters, table_duration, barLength, currentInstrument)
+
+ numOfNotes = range(len(rythmSequence))
+ rand = random.random
+ append = trackNotes.append
+ pan = GenerationConstants.DEFAULT_PAN
+ instrument_id = Config.INSTRUMENTS[instrument[pageId][trackId]].instrumentId
+ for i in numOfNotes:
+ if drumPitch:
+ if ( rand() * fillDrum ) > ( parameters.silence * .5 ):
+ if fillDrum != 1:
+ if rythmSequence[i] not in trackOnsets or pitchSequence[i] not in trackPitchs:
+ append( CSoundNote( rythmSequence[i], pitchSequence[i], gainSequence[i], pan, durationSequence[i], trackId, instrument_id, 0.002, 0.098, 0.1, 0, 1000, False, 'edit' ) )
+ else:
+ append( CSoundNote( rythmSequence[i], pitchSequence[i], gainSequence[i], pan, durationSequence[i], trackId, instrument_id, 0.002, 0.098, 0.1, 0, 1000, False, 'edit' ) )
+ else:
+ if rand() > parameters.silence:
+ append( CSoundNote( rythmSequence[i], pitchSequence[i], gainSequence[i], pan, durationSequence[i], trackId, instrument_id, 0.002, 0.1, 0.1, 0, 1000, False, 'edit' ) )
+
+ trackDictionary[ trackId ][ pageId ] = trackNotes
+
+##################################################################################
+ # begin generate()
+
+ table_duration = Utils.scale(parameters.articule, GenerationConstants.ARTICULATION_SCALE_MIN_MAPPING, GenerationConstants.ARTICULATION_SCALE_MAX_MAPPING, GenerationConstants.ARTICULATION_SCALE_STEPS)
+ table_pitch = GenerationConstants.SCALES[parameters.scale]
+
+ for trackId in trackIds:
+ if trackId == 4: # drum index
+ if parameters.rythmRegularity > 0.75:
+ streamOfPitch = GenerationConstants.DRUM_COMPLEXITY1
+ elif parameters.rythmRegularity > 0.5:
+ streamOfPitch = GenerationConstants.DRUM_COMPLEXITY2
+ elif parameters.rythmRegularity > 0.25:
+ streamOfPitch = GenerationConstants.DRUM_COMPLEXITY3
+ else:
+ streamOfPitch = GenerationConstants.DRUM_COMPLEXITY4
+ selectedPageCount = 0
+ lastPageId = 0
+ for pageId in pageIds:
+ barLength = Config.TICKS_PER_BEAT * nbeats[ pageId ]
+ trackOfNotes = []
+ pageCycle = selectedPageCount % nPagesCycle
+
+ if instrument[pageId][trackId][0:4] == 'drum':
+ if pageCycle not in [0,nPagesCycle-1] and nbeats[pageId] == nbeats[lastPageId]:
+ trackDictionary[trackId][pageId] = []
+ for n in trackDictionary[trackId][lastPageId]:
+ trackDictionary[trackId][pageId].append(n.clone())
+ elif pageCycle == (nPagesCycle-1) and nbeats[pageId] == nbeats[lastPageId]:
+ for n in trackDictionary[trackId][lastPageId]:
+ trackOfNotes.append(n.clone())
+ trackOnsets = [n.onset for n in trackOfNotes]
+ trackPitchs = [n.pitch for n in trackOfNotes]
+ fillDrum = .5
+ rythmRegTemp = parameters.rythmRegularity
+ parameters.rythmRegularity = 0.5
+ for drumPitch in GenerationConstants.DRUM_COMPLEXITY4:
+ pageGenerate( parameters, trackId, pageId, trackOfNotes, drumPitch )
+ parameters.rythmRegularity = rythmRegTemp
+ else:
+ fillDrum = 1
+ for drumPitch in streamOfPitch:
+ pageGenerate( parameters, trackId, pageId, trackOfNotes, drumPitch )
+
+ else:
+ pageGenerate( parameters, trackId, pageId, trackOfNotes, drumPitch = None )
+ selectedPageCount += 1
+ lastPageId = pageId
diff --git a/common/Generation/Utils.py b/common/Generation/Utils.py
new file mode 100755
index 0000000..e5ea295
--- /dev/null
+++ b/common/Generation/Utils.py
@@ -0,0 +1,74 @@
+import random
+import time
+import math
+
+#----------------------------------------------------------------------
+# TODO: replace magic numbers with constants
+# http://en.wikipedia.org/wiki/Magic_number_(programming)
+#----------------------------------------------------------------------
+
+def prob(x):
+ sum1 = 0
+ sum2 = 0
+
+ for i in x:
+ sum1 = sum1 + i
+
+ val = sum1 * random.randint(0, 32767) / 32768
+
+ for i in range(len(x)):
+ sum2 = sum2 + x[i]
+ if x[i]:
+ if sum2 >= val:
+ return i
+ break
+
+def prob2(x):
+ sum1 = 0
+ sum2 = 0
+
+ for i in x:
+ sum1 = sum1 + i[1]
+
+ val = sum1 * random.randint(0, 32767) / 32768
+
+ for i in x:
+ sum2 = sum2 + i[1]
+ if i[1]:
+ if sum2 >= val:
+ return i[0]
+ break
+
+def scale(val, mini=0., maxi=1., length=100):
+ slope = []
+
+ up = 1.-val
+ if up <= 0.5:
+ low_val = (pow(1.-(up*2.),4.)*(-50.5)+0.5)
+ else:
+ low_val = up
+
+ if val <= 0.5:
+ high_val = (pow(1.-(val * 2.),4.)*(-50.5)+0.5)
+ else:
+ high_val = val
+
+ step = (maxi - mini) * (1. / length)
+
+ calc = (1. / length) * (high_val - low_val)
+ append = slope.append
+ for i in range(length + 1):
+ temp = i * calc + low_val
+ if temp < 0:
+ temp = 0
+ elif temp > 1:
+ temp = 1
+ else:
+ temp = temp
+
+ append(((step * i) + mini, int(temp * 100)))
+
+ return slope
+
+def midtotrans(x):
+ return pow(1.059463, x - 36)
diff --git a/common/Generation/VariationPitch.py b/common/Generation/VariationPitch.py
new file mode 100644
index 0000000..5a2b151
--- /dev/null
+++ b/common/Generation/VariationPitch.py
@@ -0,0 +1,82 @@
+import random
+
+class PitchReverse:
+ def __init__( self ):
+ self.pitchList = []
+
+ def reorderPitch( self, notesList ):
+ self.extractOneValue(notesList)
+ self.pitchList.reverse()
+ for i in range(len(notesList)):
+ notesList[i].pitch = self.pitchList[i]
+
+ return notesList
+
+ def extractOneValue( self, notesList ):
+ self.pitchList = []
+ for note in notesList:
+ self.pitchList.append(note.pitch)
+
+class PitchSort( PitchReverse ):
+ def __init__( self ):
+ PitchReverse.__init__( self )
+
+ def reorderPitch( self, notesList ):
+ PitchReverse.extractOneValue(self, notesList)
+ self.pitchList.sort()
+ for i in range(len(notesList)):
+ notesList[i].pitch = self.pitchList[i]
+
+ return notesList
+
+class PitchShuffle( PitchReverse ):
+ def __init__( self ):
+ PitchReverse.__init__ ( self )
+
+ def reorderPitch( self, notesList ):
+ PitchReverse.extractOneValue(self, notesList)
+ self.pitchList = random.sample(self.pitchList, len(self.pitchList))
+ for i in range(len(notesList)):
+ notesList[i].pitch = self.pitchList[i]
+
+ return notesList
+
+class PitchMarkov:
+ def __init__( self ):
+ self.originalList = []
+
+ def getNewList( self, notesList, order=1 ):
+ self.playedNotes = []
+ self.extractOneValue( notesList, order )
+ self.playedNotes = self.originalList[:order]
+
+ for i in range(len(self.originalList) - order):
+ self.playedNotes.append(self.pickupNewValue(order))
+
+ for i in range(len(notesList)):
+ notesList[i].pitch = self.playedNotes[i]
+
+ return notesList
+
+ def extractOneValue( self, notesList, order ):
+ self.originalList = []
+ for note in notesList:
+ self.originalList.append(note.pitch)
+ for i in range(order):
+ self.originalList.append(self.originalList[i])
+
+ def pickupNewValue( self, order ):
+ condition = False
+ self.probTable = []
+ for ilist in range(len(self.originalList) - order):
+ for iord in range(order):
+ if self.playedNotes[len(self.playedNotes) - (iord + 1)] != self.originalList[(order - 1) + ilist - iord]:
+ condition = False
+ break
+ else:
+ condition = True
+
+ if condition == True:
+ self.probTable.append(self.originalList[ilist + order])
+
+ return self.probTable[random.randint(0, (len(self.probTable) - 1))]
diff --git a/common/Generation/VariationRythm.py b/common/Generation/VariationRythm.py
new file mode 100644
index 0000000..5fb6111
--- /dev/null
+++ b/common/Generation/VariationRythm.py
@@ -0,0 +1,74 @@
+import random
+
+import common.Config as Config
+
+# remplacer position dans notesList par l'attribut de CSoundNote
+class RythmShuffle:
+
+ def getNewList( self, notesList, nbeats ):
+ self.barLength = Config.TICKS_PER_BEAT * nbeats
+ self.onsetDelta = 0
+ self.newOnsetList = []
+ self.oldDuration = []
+ self.newDuration = []
+ self.extractOnsetValue(notesList)
+
+ self.newOnsetList = random.sample(range(len(self.originalList)), len(self.originalList))
+ self.getOldDuration(notesList)
+ self.getNewDuration(notesList)
+
+ for i in range(len(notesList)):
+ notesList[i].onset = self.onsetDelta
+ notesList[i].duration = self.oldDuration[i] * self.newDuration[i]
+ self.onsetDelta = self.onsetDelta + self.originalList[self.newOnsetList[i]]
+
+ return notesList
+
+ def extractOnsetValue( self, notesList ):
+ self.originalList = []
+ for note in notesList:
+ self.originalList.append(note.onset)
+
+ for i in range(len(self.originalList) -1):
+ self.originalList[i] = self.originalList[i+1] - self.originalList[i]
+
+ self.originalList[-1] = self.barLength - (self.originalList[-1] % self.barLength)
+
+ def getOldDuration( self, notesList ):
+ for i in range(len(notesList)):
+ if (i+1) == len(notesList):
+ self.oldDuration.append(notesList[i].duration / (self.barLength - (notesList[i].onset % self.barLength)))
+ else:
+ self.oldDuration.append(notesList[i].duration / (notesList[i+1].onset - notesList[i].onset))
+
+ def getNewDuration( self, notesList ):
+ for i in self.newOnsetList:
+ if (i+1) == len(notesList):
+ self.newDuration.append(self.barLength - (notesList[i].onset % self.barLength))
+ else:
+ self.newDuration.append(notesList[i+1].onset - notesList[i].onset)
+
+class RythmReverse( RythmShuffle ):
+
+ def getNewList( self, notesList, nbeats ):
+ self.barLength = Config.TICKS_PER_BEAT * nbeats
+ self.onsetDelta = 0
+ self.newOnsetList = []
+ self.oldDuration = []
+ self.newDuration = []
+ RythmShuffle.extractOnsetValue( self, notesList )
+
+ for i in range( len( self.originalList ) ):
+ self.newOnsetList.append( i )
+
+ self.newOnsetList.reverse()
+
+ RythmShuffle.getOldDuration( self, notesList )
+ RythmShuffle.getNewDuration( self, notesList )
+
+ for i in range(len(notesList)):
+ notesList[i].onset = self.onsetDelta
+ notesList[i].duration = self.oldDuration[i] * self.newDuration[i]
+ self.onsetDelta = self.onsetDelta + self.originalList[self.newOnsetList[i]]
+
+ return notesList
diff --git a/common/Generation/__init__.py b/common/Generation/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/common/Generation/__init__.py
diff --git a/common/Generation/bList.py b/common/Generation/bList.py
new file mode 100644
index 0000000..26aed12
--- /dev/null
+++ b/common/Generation/bList.py
@@ -0,0 +1,97 @@
+import common.Config as Config
+from Generation.GenerationConstants import GenerationConstants
+
+def gen():
+ punch_list = [[], ]
+ low_list = [[], ]
+ mid_list = [[], ]
+ high_list = [[], ]
+
+ f = open('/home/olpc/tamtam/Generation/drumTablesList', 'w')
+ g = open('/home/olpc/tamtam/Generation/drumStraightTables', 'w')
+
+ # gen punch list
+ beatsList = [[], ]
+ for beatsPerPage in [1,2,3,4,5,6,7,8,9,10,11,12]:
+ accents = []
+ for j in GenerationConstants.PUNCH_ACCENTS[beatsPerPage]:
+ accents.append(j * Config.TICKS_PER_BEAT)
+ beatsList.append(accents)
+ beats = []
+ downBeats = []
+ for beat in range( beatsPerPage ):
+ beats.append( beat * Config.TICKS_PER_BEAT )
+ for i in range( len( beats ) ):
+ downBeats.append( ( beats[ GenerationConstants.PUNCH_ACCENTS[ beatsPerPage ][ i ] ], int( pow( float( len( beats ) - i) / len( beats ), 1.5 ) * 100.) ) )
+ punch_list.append(downBeats)
+
+ string = ' DRUM_PUNCH_PROB = ' + str(punch_list) + '\n'
+ f.write(string)
+ string = ' DRUM_PUNCH_ACCENT = ' + str(beatsList) + '\n'
+ g.write(string)
+
+ # gen low list
+ beatsList = [[], ]
+ for beatsPerPage in [1,2,3,4,5,6,7,8,9,10,11,12]:
+ accents = []
+ for j in GenerationConstants.LOW_ACCENTS[beatsPerPage]:
+ accents.append(j * Config.TICKS_PER_BEAT)
+ beatsList.append(accents)
+ beats = []
+ downBeats = []
+ for beat in range( beatsPerPage ):
+ beats.append( beat * Config.TICKS_PER_BEAT )
+ for i in range( len( beats ) ):
+ downBeats.append( ( beats[ GenerationConstants.LOW_ACCENTS[ beatsPerPage ][ i ] ], int( pow( float( len( beats ) - i) / len( beats ), 1.5 ) * 100.) ) )
+ low_list.append(downBeats)
+
+ string = ' DRUM_LOW_PROB = ' + str(low_list) + '\n'
+ f.write(string)
+ string = ' DRUM_LOW_ACCENT = ' + str(beatsList) + '\n'
+ g.write(string)
+
+ # gen mid list
+ beatsList = [[], ]
+ for beatsPerPage in [1,2,3,4,5,6,7,8,9,10,11,12]:
+ accents = []
+ for j in GenerationConstants.MID_ACCENTS[beatsPerPage]:
+ accents.append(j * Config.TICKS_PER_BEAT / 2)
+ beatsList.append(accents)
+ beats = []
+ downBeats = []
+ for beat in range( beatsPerPage ):
+ beats.append( beat * Config.TICKS_PER_BEAT )
+ beats.append( beat * Config.TICKS_PER_BEAT + ( Config.TICKS_PER_BEAT / 2 ) )
+ for i in range( len( beats ) ):
+ downBeats.append( ( beats[ GenerationConstants.MID_ACCENTS[ beatsPerPage ][ i ] ], int( pow( float( len( beats ) - i) / len( beats ), 1.5 ) * 100.) ) )
+ mid_list.append(downBeats)
+
+ string = ' DRUM_MID_PROB = ' + str(mid_list) + '\n'
+ f.write(string)
+ string = ' DRUM_MID_ACCENT = ' + str(beatsList) + '\n'
+ g.write(string)
+
+ # gen high list
+ beatsList = [[], ]
+ for beatsPerPage in [1,2,3,4,5,6,7,8,9,10,11,12]:
+ accents = []
+ for j in GenerationConstants.HIGH_ACCENTS[beatsPerPage]:
+ accents.append(j * Config.TICKS_PER_BEAT / 2)
+ beatsList.append(accents)
+ beats = []
+ downBeats = []
+ for beat in range( beatsPerPage ):
+ beats.append( beat * Config.TICKS_PER_BEAT )
+ beats.append( beat * Config.TICKS_PER_BEAT + ( Config.TICKS_PER_BEAT / 2 ) )
+ for i in range( len( beats ) ):
+ downBeats.append( ( beats[ GenerationConstants.HIGH_ACCENTS[ beatsPerPage ][ i ] ], int( pow( float( len( beats ) - i) / len( beats ), 1.5 ) * 100.) ) )
+ high_list.append(downBeats)
+
+ string = ' DRUM_HIGH_PROB = ' + str(high_list) + '\n'
+ f.write(string)
+ string = ' DRUM_HIGH_ACCENT = ' + str(beatsList) + '\n'
+ g.write(string)
+
+ f.close()
+ g.close()
+
diff --git a/common/Resources/Desktops/desktop0 b/common/Resources/Desktops/desktop0
new file mode 100644
index 0000000..3da73d9
--- /dev/null
+++ b/common/Resources/Desktops/desktop0
@@ -0,0 +1,206 @@
+page_add 10 11 0 [82, 82, 82, 82, 133]
+note_add 9 10 0 0 34 0.942260596881 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 13 10 0 3 38 0.72175977127 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 26 10 0 3 42 0.694338417824 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 1 10 0 6 26 0.725991648348 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 27 10 0 9 46 0.673789246514 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 10 0 21 40 0.711089872007 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 28 10 0 21 44 0.724189552495 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 10 0 24 34 0.78660445793 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 10 0 33 38 0.689247104327 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 29 10 0 36 44 0.892482541278 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 30 10 0 39 46 0.743841693835 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 31 10 0 45 42 0.675915254637 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 10 0 48 28 0.867874500271 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 10 0 48 32 0.843933612421 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 10 0 48 36 0.882490480554 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 10 0 51 46 0.7260388951 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 10 0 54 26 0.723548457528 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 10 0 54 40 0.688941454565 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 10 0 57 38 0.692369221065 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 10 0 60 30 0.851574151203 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 10 0 63 42 0.725848400909 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 10 0 72 24 0.844375616982 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 10 0 75 36 0.721617793685 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 10 0 75 44 0.733357608142 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 10 0 84 24 0.816385837458 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 10 0 84 42 0.797679015697 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 10 0 87 40 0.736436950535 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 10 0 93 40 0.678395248218 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 10 0 93 46 0.711345361166 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 10 0 96 24 0.852190617798 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 10 0 99 38 0.730783663308 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 10 0 114 26 0.746689002705 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 10 0 117 36 0.696057408747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 10 0 117 44 0.704912091309 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 10 0 120 26 0.89517776125 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 10 0 120 38 0.775461496957 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 25 10 0 123 36 0.671213642754 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 10 0 123 48 0.657357627725 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 9 3 0 [82, 82, 82, 82, 133]
+note_add 1 9 0 0 24 0.939922537979 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 9 0 0 32 0.919417513279 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 9 0 0 46 0.94323408296 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 9 0 3 40 0.698900010891 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 9 0 6 46 0.698856456031 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 9 9 0 9 46 0.73534413844 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 9 0 12 28 0.777449966123 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 9 0 15 36 0.745537315527 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 9 0 18 40 0.731967099614 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 9 0 18 46 0.659748039959 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 9 0 24 48 0.887567039913 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 9 0 27 48 0.67596583908 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 8 9 0 [82, 82, 82, 82, 133]
+note_add 31 8 0 0 24 0.925548542596 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 41 8 0 0 40 0.99515399493 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 51 8 0 3 42 0.656600534211 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 42 8 0 12 40 0.781608499687 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 52 8 0 18 42 0.746078356731 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 8 0 24 26 0.842788079016 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 8 0 24 30 0.858448377744 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 43 8 0 27 38 0.655557996923 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 8 0 36 24 0.84416548026 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 53 8 0 42 48 0.708755031747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 54 8 0 45 46 0.694252886906 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 8 0 48 28 0.790745114826 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 44 8 0 51 38 0.693079205578 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 55 8 0 51 48 0.723114366376 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 56 8 0 57 42 0.74000144627 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 45 8 0 60 36 0.844357847996 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 46 8 0 63 36 0.670774638825 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 57 8 0 69 42 0.666807403745 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 8 0 72 24 0.802855117652 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 39 8 0 72 32 0.850137481504 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 58 8 0 75 42 0.714082247268 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 8 0 84 28 0.854088386031 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 47 8 0 84 38 0.816924020176 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 48 8 0 87 38 0.698932384487 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 59 8 0 87 42 0.674609289728 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 8 0 96 26 0.884421425859 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 40 8 0 96 32 0.816095303092 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 49 8 0 96 40 0.85609056018 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 50 8 0 99 36 0.739998407875 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 60 8 0 99 48 0.735836941454 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 5 3 0 [82, 82, 82, 82, 133]
+note_add 13 5 0 0 28 0.948923051548 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 5 0 0 32 0.983674976389 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 5 0 3 38 0.676515455171 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 5 0 3 44 0.748902416777 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 5 0 9 42 0.721823750258 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 5 0 18 26 0.727501183971 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 5 0 18 42 0.692538780737 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 5 0 21 42 0.704638060569 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 5 0 27 38 0.699231033599 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 5 0 27 42 0.710291506584 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 5 0 33 38 0.740104587325 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 5 0 33 42 0.712509981931 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 11 9 0 [82, 82, 82, 82, 133]
+note_add 1 11 0 0 28 0.940708810641 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 11 0 0 30 0.917125893398 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 11 0 3 38 0.659757355829 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 21 11 0 3 46 0.691197364433 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 11 0 15 36 0.728363093232 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 22 11 0 15 48 0.651730437628 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 13 11 0 21 36 0.748099491714 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 23 11 0 21 42 0.691142328317 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 11 0 24 26 0.799430971651 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 14 11 0 24 36 0.789827858454 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 15 11 0 27 40 0.717847096017 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 24 11 0 27 46 0.68775950814 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 3 11 0 36 28 0.847659428446 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 16 11 0 39 38 0.724596484561 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 17 11 0 42 38 0.672521332617 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 25 11 0 45 42 0.707153905275 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 11 0 48 26 0.768231729212 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 11 0 48 30 0.797498430547 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 18 11 0 51 40 0.662933204402 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 26 11 0 51 46 0.652875237261 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 11 0 60 28 0.870729034797 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 19 11 0 63 38 0.699990604686 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 27 11 0 63 46 0.744299692171 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 28 11 0 69 42 0.674719518782 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 11 0 72 28 0.793569160964 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 20 11 0 75 36 0.743411205808 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 11 0 84 30 0.76896495703 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 29 11 0 87 46 0.739799809332 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 11 0 96 28 0.854769659604 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 30 11 0 96 48 0.88403154664 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 12 2 0 [88, 76, 56, 82, 135]
+note_add 1 12 0 0 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 12 0 3 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 12 0 6 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 12 0 9 41 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 12 0 12 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 12 0 15 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 12 0 18 38 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 12 0 21 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 13 5 0 [88, 76, 56, 82, 135]
+note_add 1 13 0 0 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 13 0 1 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 13 0 2 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 13 0 3 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 13 0 4 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 39 13 0 7 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 40 13 0 8 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 41 13 0 9 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 42 13 0 10 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 43 13 0 11 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 13 0 12 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 13 0 13 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 13 0 14 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 9 13 0 15 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 10 13 0 16 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 34 13 0 19 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 35 13 0 20 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 36 13 0 21 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 37 13 0 22 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 38 13 0 23 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 11 13 0 24 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 12 13 0 25 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 13 13 0 26 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 14 13 0 27 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 29 13 0 31 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 30 13 0 32 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 31 13 0 33 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 32 13 0 34 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 33 13 0 35 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 15 13 0 36 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 16 13 0 37 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 17 13 0 38 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 18 13 0 39 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 24 13 0 43 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 25 13 0 44 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 26 13 0 45 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 27 13 0 46 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 28 13 0 47 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 19 13 0 55 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 20 13 0 56 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 21 13 0 57 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 22 13 0 58 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 23 13 0 59 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 14 3 0 [82, 82, 82, 82, 133]
+note_add 3 14 0 0 30 0.900689216372 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 14 0 0 38 0.92403208165 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 1 14 0 6 24 0.710809973008 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 14 0 6 44 0.680687612344 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 14 0 9 48 0.689412655788 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 14 0 15 44 0.664335685932 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 14 0 21 44 0.699249583758 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 14 0 24 26 0.826542425289 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 14 0 27 38 0.737997319594 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 14 0 27 42 0.671027963479 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 14 0 33 40 0.727866267806 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 14 0 33 48 0.674593053365 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 15 7 0 [88, 77, 67, 85, 137]
+note_add 1 15 0 0 29 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 15 0 24 44 0.75 0.5 7.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 15 0 36 44 0.75 0.5 6.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 15 0 48 32 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+block_add Drum False 236 203 False {'name': 'drum5kit', 'regularity': 0.17265378043653012, 'page': 5, 'volume': 0.5, 'beats': 3, 'seed': 0.61058227696419964, 'reverb': 0.0, 'id': 137}
+block_add Instrument False 437 137 False {'volume': 0.5, 'reverb': 0, 'name': 'duck', 'pan': 0.5, 'id': 30}
+block_add Loop False 567 137 True {'name': 'loop1', 'id': 15}
+block_add Instrument True 431 302 False {'volume': 0.5, 'reverb': 0, 'name': 'rhodes', 'pan': 0.5, 'id': 85}
+block_add Instrument False 443 445 False {'volume': 0.5, 'reverb': 0, 'name': 'ow', 'pan': 0.5, 'id': 63}
+block_add Loop False 550 445 True {'name': 'loop2', 'id': 13}
+block_add Loop False 638 445 True {'name': 'loop3', 'id': 12}
+block_add Drum False 233 354 False {'name': 'drum2kit', 'regularity': 0.32130953701001352, 'id': 134, 'volume': 0.5, 'beats': 9, 'reverb': 0.0, 'page': 8}
diff --git a/common/Resources/Desktops/desktop1 b/common/Resources/Desktops/desktop1
new file mode 100644
index 0000000..3da73d9
--- /dev/null
+++ b/common/Resources/Desktops/desktop1
@@ -0,0 +1,206 @@
+page_add 10 11 0 [82, 82, 82, 82, 133]
+note_add 9 10 0 0 34 0.942260596881 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 13 10 0 3 38 0.72175977127 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 26 10 0 3 42 0.694338417824 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 1 10 0 6 26 0.725991648348 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 27 10 0 9 46 0.673789246514 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 10 0 21 40 0.711089872007 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 28 10 0 21 44 0.724189552495 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 10 0 24 34 0.78660445793 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 10 0 33 38 0.689247104327 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 29 10 0 36 44 0.892482541278 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 30 10 0 39 46 0.743841693835 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 31 10 0 45 42 0.675915254637 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 10 0 48 28 0.867874500271 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 10 0 48 32 0.843933612421 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 10 0 48 36 0.882490480554 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 10 0 51 46 0.7260388951 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 10 0 54 26 0.723548457528 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 10 0 54 40 0.688941454565 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 10 0 57 38 0.692369221065 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 10 0 60 30 0.851574151203 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 10 0 63 42 0.725848400909 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 10 0 72 24 0.844375616982 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 10 0 75 36 0.721617793685 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 10 0 75 44 0.733357608142 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 10 0 84 24 0.816385837458 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 10 0 84 42 0.797679015697 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 10 0 87 40 0.736436950535 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 10 0 93 40 0.678395248218 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 10 0 93 46 0.711345361166 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 10 0 96 24 0.852190617798 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 10 0 99 38 0.730783663308 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 10 0 114 26 0.746689002705 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 10 0 117 36 0.696057408747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 10 0 117 44 0.704912091309 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 10 0 120 26 0.89517776125 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 10 0 120 38 0.775461496957 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 25 10 0 123 36 0.671213642754 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 10 0 123 48 0.657357627725 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 9 3 0 [82, 82, 82, 82, 133]
+note_add 1 9 0 0 24 0.939922537979 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 9 0 0 32 0.919417513279 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 9 0 0 46 0.94323408296 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 9 0 3 40 0.698900010891 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 9 0 6 46 0.698856456031 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 9 9 0 9 46 0.73534413844 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 9 0 12 28 0.777449966123 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 9 0 15 36 0.745537315527 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 9 0 18 40 0.731967099614 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 9 0 18 46 0.659748039959 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 9 0 24 48 0.887567039913 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 9 0 27 48 0.67596583908 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 8 9 0 [82, 82, 82, 82, 133]
+note_add 31 8 0 0 24 0.925548542596 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 41 8 0 0 40 0.99515399493 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 51 8 0 3 42 0.656600534211 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 42 8 0 12 40 0.781608499687 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 52 8 0 18 42 0.746078356731 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 8 0 24 26 0.842788079016 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 8 0 24 30 0.858448377744 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 43 8 0 27 38 0.655557996923 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 8 0 36 24 0.84416548026 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 53 8 0 42 48 0.708755031747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 54 8 0 45 46 0.694252886906 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 8 0 48 28 0.790745114826 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 44 8 0 51 38 0.693079205578 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 55 8 0 51 48 0.723114366376 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 56 8 0 57 42 0.74000144627 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 45 8 0 60 36 0.844357847996 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 46 8 0 63 36 0.670774638825 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 57 8 0 69 42 0.666807403745 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 8 0 72 24 0.802855117652 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 39 8 0 72 32 0.850137481504 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 58 8 0 75 42 0.714082247268 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 8 0 84 28 0.854088386031 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 47 8 0 84 38 0.816924020176 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 48 8 0 87 38 0.698932384487 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 59 8 0 87 42 0.674609289728 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 8 0 96 26 0.884421425859 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 40 8 0 96 32 0.816095303092 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 49 8 0 96 40 0.85609056018 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 50 8 0 99 36 0.739998407875 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 60 8 0 99 48 0.735836941454 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 5 3 0 [82, 82, 82, 82, 133]
+note_add 13 5 0 0 28 0.948923051548 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 5 0 0 32 0.983674976389 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 5 0 3 38 0.676515455171 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 5 0 3 44 0.748902416777 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 5 0 9 42 0.721823750258 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 5 0 18 26 0.727501183971 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 5 0 18 42 0.692538780737 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 5 0 21 42 0.704638060569 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 5 0 27 38 0.699231033599 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 5 0 27 42 0.710291506584 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 5 0 33 38 0.740104587325 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 5 0 33 42 0.712509981931 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 11 9 0 [82, 82, 82, 82, 133]
+note_add 1 11 0 0 28 0.940708810641 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 11 0 0 30 0.917125893398 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 11 0 3 38 0.659757355829 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 21 11 0 3 46 0.691197364433 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 11 0 15 36 0.728363093232 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 22 11 0 15 48 0.651730437628 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 13 11 0 21 36 0.748099491714 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 23 11 0 21 42 0.691142328317 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 11 0 24 26 0.799430971651 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 14 11 0 24 36 0.789827858454 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 15 11 0 27 40 0.717847096017 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 24 11 0 27 46 0.68775950814 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 3 11 0 36 28 0.847659428446 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 16 11 0 39 38 0.724596484561 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 17 11 0 42 38 0.672521332617 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 25 11 0 45 42 0.707153905275 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 11 0 48 26 0.768231729212 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 11 0 48 30 0.797498430547 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 18 11 0 51 40 0.662933204402 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 26 11 0 51 46 0.652875237261 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 11 0 60 28 0.870729034797 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 19 11 0 63 38 0.699990604686 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 27 11 0 63 46 0.744299692171 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 28 11 0 69 42 0.674719518782 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 11 0 72 28 0.793569160964 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 20 11 0 75 36 0.743411205808 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 11 0 84 30 0.76896495703 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 29 11 0 87 46 0.739799809332 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 11 0 96 28 0.854769659604 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 30 11 0 96 48 0.88403154664 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 12 2 0 [88, 76, 56, 82, 135]
+note_add 1 12 0 0 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 12 0 3 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 12 0 6 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 12 0 9 41 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 12 0 12 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 12 0 15 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 12 0 18 38 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 12 0 21 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 13 5 0 [88, 76, 56, 82, 135]
+note_add 1 13 0 0 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 13 0 1 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 13 0 2 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 13 0 3 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 13 0 4 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 39 13 0 7 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 40 13 0 8 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 41 13 0 9 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 42 13 0 10 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 43 13 0 11 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 13 0 12 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 13 0 13 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 13 0 14 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 9 13 0 15 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 10 13 0 16 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 34 13 0 19 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 35 13 0 20 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 36 13 0 21 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 37 13 0 22 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 38 13 0 23 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 11 13 0 24 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 12 13 0 25 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 13 13 0 26 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 14 13 0 27 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 29 13 0 31 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 30 13 0 32 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 31 13 0 33 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 32 13 0 34 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 33 13 0 35 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 15 13 0 36 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 16 13 0 37 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 17 13 0 38 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 18 13 0 39 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 24 13 0 43 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 25 13 0 44 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 26 13 0 45 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 27 13 0 46 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 28 13 0 47 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 19 13 0 55 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 20 13 0 56 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 21 13 0 57 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 22 13 0 58 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 23 13 0 59 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 14 3 0 [82, 82, 82, 82, 133]
+note_add 3 14 0 0 30 0.900689216372 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 14 0 0 38 0.92403208165 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 1 14 0 6 24 0.710809973008 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 14 0 6 44 0.680687612344 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 14 0 9 48 0.689412655788 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 14 0 15 44 0.664335685932 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 14 0 21 44 0.699249583758 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 14 0 24 26 0.826542425289 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 14 0 27 38 0.737997319594 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 14 0 27 42 0.671027963479 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 14 0 33 40 0.727866267806 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 14 0 33 48 0.674593053365 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 15 7 0 [88, 77, 67, 85, 137]
+note_add 1 15 0 0 29 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 15 0 24 44 0.75 0.5 7.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 15 0 36 44 0.75 0.5 6.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 15 0 48 32 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+block_add Drum False 236 203 False {'name': 'drum5kit', 'regularity': 0.17265378043653012, 'page': 5, 'volume': 0.5, 'beats': 3, 'seed': 0.61058227696419964, 'reverb': 0.0, 'id': 137}
+block_add Instrument False 437 137 False {'volume': 0.5, 'reverb': 0, 'name': 'duck', 'pan': 0.5, 'id': 30}
+block_add Loop False 567 137 True {'name': 'loop1', 'id': 15}
+block_add Instrument True 431 302 False {'volume': 0.5, 'reverb': 0, 'name': 'rhodes', 'pan': 0.5, 'id': 85}
+block_add Instrument False 443 445 False {'volume': 0.5, 'reverb': 0, 'name': 'ow', 'pan': 0.5, 'id': 63}
+block_add Loop False 550 445 True {'name': 'loop2', 'id': 13}
+block_add Loop False 638 445 True {'name': 'loop3', 'id': 12}
+block_add Drum False 233 354 False {'name': 'drum2kit', 'regularity': 0.32130953701001352, 'id': 134, 'volume': 0.5, 'beats': 9, 'reverb': 0.0, 'page': 8}
diff --git a/common/Resources/Desktops/desktop2 b/common/Resources/Desktops/desktop2
new file mode 100644
index 0000000..3da73d9
--- /dev/null
+++ b/common/Resources/Desktops/desktop2
@@ -0,0 +1,206 @@
+page_add 10 11 0 [82, 82, 82, 82, 133]
+note_add 9 10 0 0 34 0.942260596881 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 13 10 0 3 38 0.72175977127 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 26 10 0 3 42 0.694338417824 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 1 10 0 6 26 0.725991648348 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 27 10 0 9 46 0.673789246514 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 10 0 21 40 0.711089872007 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 28 10 0 21 44 0.724189552495 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 10 0 24 34 0.78660445793 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 10 0 33 38 0.689247104327 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 29 10 0 36 44 0.892482541278 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 30 10 0 39 46 0.743841693835 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 31 10 0 45 42 0.675915254637 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 10 0 48 28 0.867874500271 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 10 0 48 32 0.843933612421 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 10 0 48 36 0.882490480554 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 10 0 51 46 0.7260388951 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 10 0 54 26 0.723548457528 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 10 0 54 40 0.688941454565 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 10 0 57 38 0.692369221065 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 10 0 60 30 0.851574151203 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 10 0 63 42 0.725848400909 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 10 0 72 24 0.844375616982 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 10 0 75 36 0.721617793685 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 10 0 75 44 0.733357608142 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 10 0 84 24 0.816385837458 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 10 0 84 42 0.797679015697 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 10 0 87 40 0.736436950535 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 10 0 93 40 0.678395248218 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 10 0 93 46 0.711345361166 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 10 0 96 24 0.852190617798 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 10 0 99 38 0.730783663308 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 10 0 114 26 0.746689002705 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 10 0 117 36 0.696057408747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 10 0 117 44 0.704912091309 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 10 0 120 26 0.89517776125 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 10 0 120 38 0.775461496957 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 25 10 0 123 36 0.671213642754 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 10 0 123 48 0.657357627725 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 9 3 0 [82, 82, 82, 82, 133]
+note_add 1 9 0 0 24 0.939922537979 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 9 0 0 32 0.919417513279 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 9 0 0 46 0.94323408296 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 9 0 3 40 0.698900010891 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 9 0 6 46 0.698856456031 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 9 9 0 9 46 0.73534413844 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 9 0 12 28 0.777449966123 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 9 0 15 36 0.745537315527 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 9 0 18 40 0.731967099614 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 9 0 18 46 0.659748039959 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 9 0 24 48 0.887567039913 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 9 0 27 48 0.67596583908 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 8 9 0 [82, 82, 82, 82, 133]
+note_add 31 8 0 0 24 0.925548542596 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 41 8 0 0 40 0.99515399493 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 51 8 0 3 42 0.656600534211 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 42 8 0 12 40 0.781608499687 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 52 8 0 18 42 0.746078356731 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 8 0 24 26 0.842788079016 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 8 0 24 30 0.858448377744 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 43 8 0 27 38 0.655557996923 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 8 0 36 24 0.84416548026 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 53 8 0 42 48 0.708755031747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 54 8 0 45 46 0.694252886906 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 8 0 48 28 0.790745114826 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 44 8 0 51 38 0.693079205578 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 55 8 0 51 48 0.723114366376 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 56 8 0 57 42 0.74000144627 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 45 8 0 60 36 0.844357847996 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 46 8 0 63 36 0.670774638825 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 57 8 0 69 42 0.666807403745 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 8 0 72 24 0.802855117652 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 39 8 0 72 32 0.850137481504 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 58 8 0 75 42 0.714082247268 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 8 0 84 28 0.854088386031 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 47 8 0 84 38 0.816924020176 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 48 8 0 87 38 0.698932384487 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 59 8 0 87 42 0.674609289728 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 8 0 96 26 0.884421425859 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 40 8 0 96 32 0.816095303092 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 49 8 0 96 40 0.85609056018 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 50 8 0 99 36 0.739998407875 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 60 8 0 99 48 0.735836941454 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 5 3 0 [82, 82, 82, 82, 133]
+note_add 13 5 0 0 28 0.948923051548 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 5 0 0 32 0.983674976389 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 5 0 3 38 0.676515455171 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 5 0 3 44 0.748902416777 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 5 0 9 42 0.721823750258 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 5 0 18 26 0.727501183971 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 5 0 18 42 0.692538780737 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 5 0 21 42 0.704638060569 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 5 0 27 38 0.699231033599 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 5 0 27 42 0.710291506584 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 5 0 33 38 0.740104587325 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 5 0 33 42 0.712509981931 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 11 9 0 [82, 82, 82, 82, 133]
+note_add 1 11 0 0 28 0.940708810641 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 11 0 0 30 0.917125893398 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 11 0 3 38 0.659757355829 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 21 11 0 3 46 0.691197364433 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 11 0 15 36 0.728363093232 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 22 11 0 15 48 0.651730437628 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 13 11 0 21 36 0.748099491714 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 23 11 0 21 42 0.691142328317 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 11 0 24 26 0.799430971651 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 14 11 0 24 36 0.789827858454 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 15 11 0 27 40 0.717847096017 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 24 11 0 27 46 0.68775950814 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 3 11 0 36 28 0.847659428446 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 16 11 0 39 38 0.724596484561 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 17 11 0 42 38 0.672521332617 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 25 11 0 45 42 0.707153905275 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 11 0 48 26 0.768231729212 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 11 0 48 30 0.797498430547 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 18 11 0 51 40 0.662933204402 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 26 11 0 51 46 0.652875237261 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 11 0 60 28 0.870729034797 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 19 11 0 63 38 0.699990604686 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 27 11 0 63 46 0.744299692171 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 28 11 0 69 42 0.674719518782 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 11 0 72 28 0.793569160964 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 20 11 0 75 36 0.743411205808 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 11 0 84 30 0.76896495703 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 29 11 0 87 46 0.739799809332 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 11 0 96 28 0.854769659604 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 30 11 0 96 48 0.88403154664 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 12 2 0 [88, 76, 56, 82, 135]
+note_add 1 12 0 0 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 12 0 3 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 12 0 6 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 12 0 9 41 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 12 0 12 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 12 0 15 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 12 0 18 38 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 12 0 21 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 13 5 0 [88, 76, 56, 82, 135]
+note_add 1 13 0 0 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 13 0 1 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 13 0 2 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 13 0 3 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 13 0 4 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 39 13 0 7 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 40 13 0 8 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 41 13 0 9 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 42 13 0 10 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 43 13 0 11 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 13 0 12 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 13 0 13 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 13 0 14 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 9 13 0 15 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 10 13 0 16 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 34 13 0 19 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 35 13 0 20 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 36 13 0 21 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 37 13 0 22 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 38 13 0 23 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 11 13 0 24 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 12 13 0 25 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 13 13 0 26 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 14 13 0 27 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 29 13 0 31 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 30 13 0 32 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 31 13 0 33 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 32 13 0 34 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 33 13 0 35 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 15 13 0 36 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 16 13 0 37 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 17 13 0 38 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 18 13 0 39 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 24 13 0 43 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 25 13 0 44 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 26 13 0 45 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 27 13 0 46 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 28 13 0 47 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 19 13 0 55 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 20 13 0 56 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 21 13 0 57 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 22 13 0 58 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 23 13 0 59 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 14 3 0 [82, 82, 82, 82, 133]
+note_add 3 14 0 0 30 0.900689216372 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 14 0 0 38 0.92403208165 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 1 14 0 6 24 0.710809973008 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 14 0 6 44 0.680687612344 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 14 0 9 48 0.689412655788 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 14 0 15 44 0.664335685932 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 14 0 21 44 0.699249583758 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 14 0 24 26 0.826542425289 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 14 0 27 38 0.737997319594 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 14 0 27 42 0.671027963479 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 14 0 33 40 0.727866267806 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 14 0 33 48 0.674593053365 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 15 7 0 [88, 77, 67, 85, 137]
+note_add 1 15 0 0 29 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 15 0 24 44 0.75 0.5 7.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 15 0 36 44 0.75 0.5 6.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 15 0 48 32 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+block_add Drum False 236 203 False {'name': 'drum5kit', 'regularity': 0.17265378043653012, 'page': 5, 'volume': 0.5, 'beats': 3, 'seed': 0.61058227696419964, 'reverb': 0.0, 'id': 137}
+block_add Instrument False 437 137 False {'volume': 0.5, 'reverb': 0, 'name': 'duck', 'pan': 0.5, 'id': 30}
+block_add Loop False 567 137 True {'name': 'loop1', 'id': 15}
+block_add Instrument True 431 302 False {'volume': 0.5, 'reverb': 0, 'name': 'rhodes', 'pan': 0.5, 'id': 85}
+block_add Instrument False 443 445 False {'volume': 0.5, 'reverb': 0, 'name': 'ow', 'pan': 0.5, 'id': 63}
+block_add Loop False 550 445 True {'name': 'loop2', 'id': 13}
+block_add Loop False 638 445 True {'name': 'loop3', 'id': 12}
+block_add Drum False 233 354 False {'name': 'drum2kit', 'regularity': 0.32130953701001352, 'id': 134, 'volume': 0.5, 'beats': 9, 'reverb': 0.0, 'page': 8}
diff --git a/common/Resources/Desktops/desktop3 b/common/Resources/Desktops/desktop3
new file mode 100644
index 0000000..3da73d9
--- /dev/null
+++ b/common/Resources/Desktops/desktop3
@@ -0,0 +1,206 @@
+page_add 10 11 0 [82, 82, 82, 82, 133]
+note_add 9 10 0 0 34 0.942260596881 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 13 10 0 3 38 0.72175977127 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 26 10 0 3 42 0.694338417824 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 1 10 0 6 26 0.725991648348 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 27 10 0 9 46 0.673789246514 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 10 0 21 40 0.711089872007 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 28 10 0 21 44 0.724189552495 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 10 0 24 34 0.78660445793 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 10 0 33 38 0.689247104327 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 29 10 0 36 44 0.892482541278 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 30 10 0 39 46 0.743841693835 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 31 10 0 45 42 0.675915254637 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 10 0 48 28 0.867874500271 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 10 0 48 32 0.843933612421 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 10 0 48 36 0.882490480554 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 10 0 51 46 0.7260388951 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 10 0 54 26 0.723548457528 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 10 0 54 40 0.688941454565 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 10 0 57 38 0.692369221065 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 10 0 60 30 0.851574151203 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 10 0 63 42 0.725848400909 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 10 0 72 24 0.844375616982 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 10 0 75 36 0.721617793685 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 10 0 75 44 0.733357608142 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 10 0 84 24 0.816385837458 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 10 0 84 42 0.797679015697 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 10 0 87 40 0.736436950535 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 10 0 93 40 0.678395248218 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 10 0 93 46 0.711345361166 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 10 0 96 24 0.852190617798 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 10 0 99 38 0.730783663308 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 10 0 114 26 0.746689002705 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 10 0 117 36 0.696057408747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 10 0 117 44 0.704912091309 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 10 0 120 26 0.89517776125 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 10 0 120 38 0.775461496957 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 25 10 0 123 36 0.671213642754 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 10 0 123 48 0.657357627725 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 9 3 0 [82, 82, 82, 82, 133]
+note_add 1 9 0 0 24 0.939922537979 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 9 0 0 32 0.919417513279 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 9 0 0 46 0.94323408296 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 9 0 3 40 0.698900010891 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 9 0 6 46 0.698856456031 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 9 9 0 9 46 0.73534413844 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 9 0 12 28 0.777449966123 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 9 0 15 36 0.745537315527 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 9 0 18 40 0.731967099614 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 9 0 18 46 0.659748039959 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 9 0 24 48 0.887567039913 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 9 0 27 48 0.67596583908 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 8 9 0 [82, 82, 82, 82, 133]
+note_add 31 8 0 0 24 0.925548542596 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 41 8 0 0 40 0.99515399493 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 51 8 0 3 42 0.656600534211 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 42 8 0 12 40 0.781608499687 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 52 8 0 18 42 0.746078356731 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 8 0 24 26 0.842788079016 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 8 0 24 30 0.858448377744 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 43 8 0 27 38 0.655557996923 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 8 0 36 24 0.84416548026 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 53 8 0 42 48 0.708755031747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 54 8 0 45 46 0.694252886906 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 8 0 48 28 0.790745114826 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 44 8 0 51 38 0.693079205578 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 55 8 0 51 48 0.723114366376 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 56 8 0 57 42 0.74000144627 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 45 8 0 60 36 0.844357847996 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 46 8 0 63 36 0.670774638825 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 57 8 0 69 42 0.666807403745 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 8 0 72 24 0.802855117652 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 39 8 0 72 32 0.850137481504 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 58 8 0 75 42 0.714082247268 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 8 0 84 28 0.854088386031 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 47 8 0 84 38 0.816924020176 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 48 8 0 87 38 0.698932384487 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 59 8 0 87 42 0.674609289728 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 8 0 96 26 0.884421425859 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 40 8 0 96 32 0.816095303092 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 49 8 0 96 40 0.85609056018 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 50 8 0 99 36 0.739998407875 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 60 8 0 99 48 0.735836941454 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 5 3 0 [82, 82, 82, 82, 133]
+note_add 13 5 0 0 28 0.948923051548 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 5 0 0 32 0.983674976389 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 5 0 3 38 0.676515455171 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 5 0 3 44 0.748902416777 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 5 0 9 42 0.721823750258 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 5 0 18 26 0.727501183971 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 5 0 18 42 0.692538780737 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 5 0 21 42 0.704638060569 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 5 0 27 38 0.699231033599 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 5 0 27 42 0.710291506584 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 5 0 33 38 0.740104587325 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 5 0 33 42 0.712509981931 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 11 9 0 [82, 82, 82, 82, 133]
+note_add 1 11 0 0 28 0.940708810641 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 11 0 0 30 0.917125893398 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 11 0 3 38 0.659757355829 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 21 11 0 3 46 0.691197364433 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 11 0 15 36 0.728363093232 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 22 11 0 15 48 0.651730437628 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 13 11 0 21 36 0.748099491714 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 23 11 0 21 42 0.691142328317 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 11 0 24 26 0.799430971651 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 14 11 0 24 36 0.789827858454 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 15 11 0 27 40 0.717847096017 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 24 11 0 27 46 0.68775950814 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 3 11 0 36 28 0.847659428446 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 16 11 0 39 38 0.724596484561 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 17 11 0 42 38 0.672521332617 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 25 11 0 45 42 0.707153905275 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 11 0 48 26 0.768231729212 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 11 0 48 30 0.797498430547 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 18 11 0 51 40 0.662933204402 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 26 11 0 51 46 0.652875237261 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 11 0 60 28 0.870729034797 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 19 11 0 63 38 0.699990604686 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 27 11 0 63 46 0.744299692171 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 28 11 0 69 42 0.674719518782 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 11 0 72 28 0.793569160964 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 20 11 0 75 36 0.743411205808 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 11 0 84 30 0.76896495703 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 29 11 0 87 46 0.739799809332 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 11 0 96 28 0.854769659604 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 30 11 0 96 48 0.88403154664 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 12 2 0 [88, 76, 56, 82, 135]
+note_add 1 12 0 0 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 12 0 3 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 12 0 6 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 12 0 9 41 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 12 0 12 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 12 0 15 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 12 0 18 38 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 12 0 21 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 13 5 0 [88, 76, 56, 82, 135]
+note_add 1 13 0 0 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 13 0 1 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 13 0 2 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 13 0 3 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 13 0 4 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 39 13 0 7 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 40 13 0 8 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 41 13 0 9 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 42 13 0 10 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 43 13 0 11 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 13 0 12 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 13 0 13 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 13 0 14 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 9 13 0 15 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 10 13 0 16 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 34 13 0 19 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 35 13 0 20 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 36 13 0 21 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 37 13 0 22 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 38 13 0 23 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 11 13 0 24 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 12 13 0 25 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 13 13 0 26 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 14 13 0 27 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 29 13 0 31 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 30 13 0 32 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 31 13 0 33 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 32 13 0 34 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 33 13 0 35 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 15 13 0 36 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 16 13 0 37 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 17 13 0 38 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 18 13 0 39 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 24 13 0 43 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 25 13 0 44 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 26 13 0 45 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 27 13 0 46 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 28 13 0 47 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 19 13 0 55 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 20 13 0 56 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 21 13 0 57 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 22 13 0 58 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 23 13 0 59 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 14 3 0 [82, 82, 82, 82, 133]
+note_add 3 14 0 0 30 0.900689216372 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 14 0 0 38 0.92403208165 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 1 14 0 6 24 0.710809973008 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 14 0 6 44 0.680687612344 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 14 0 9 48 0.689412655788 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 14 0 15 44 0.664335685932 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 14 0 21 44 0.699249583758 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 14 0 24 26 0.826542425289 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 14 0 27 38 0.737997319594 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 14 0 27 42 0.671027963479 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 14 0 33 40 0.727866267806 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 14 0 33 48 0.674593053365 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 15 7 0 [88, 77, 67, 85, 137]
+note_add 1 15 0 0 29 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 15 0 24 44 0.75 0.5 7.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 15 0 36 44 0.75 0.5 6.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 15 0 48 32 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+block_add Drum False 236 203 False {'name': 'drum5kit', 'regularity': 0.17265378043653012, 'page': 5, 'volume': 0.5, 'beats': 3, 'seed': 0.61058227696419964, 'reverb': 0.0, 'id': 137}
+block_add Instrument False 437 137 False {'volume': 0.5, 'reverb': 0, 'name': 'duck', 'pan': 0.5, 'id': 30}
+block_add Loop False 567 137 True {'name': 'loop1', 'id': 15}
+block_add Instrument True 431 302 False {'volume': 0.5, 'reverb': 0, 'name': 'rhodes', 'pan': 0.5, 'id': 85}
+block_add Instrument False 443 445 False {'volume': 0.5, 'reverb': 0, 'name': 'ow', 'pan': 0.5, 'id': 63}
+block_add Loop False 550 445 True {'name': 'loop2', 'id': 13}
+block_add Loop False 638 445 True {'name': 'loop3', 'id': 12}
+block_add Drum False 233 354 False {'name': 'drum2kit', 'regularity': 0.32130953701001352, 'id': 134, 'volume': 0.5, 'beats': 9, 'reverb': 0.0, 'page': 8}
diff --git a/common/Resources/Desktops/desktop4 b/common/Resources/Desktops/desktop4
new file mode 100644
index 0000000..3da73d9
--- /dev/null
+++ b/common/Resources/Desktops/desktop4
@@ -0,0 +1,206 @@
+page_add 10 11 0 [82, 82, 82, 82, 133]
+note_add 9 10 0 0 34 0.942260596881 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 13 10 0 3 38 0.72175977127 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 26 10 0 3 42 0.694338417824 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 1 10 0 6 26 0.725991648348 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 27 10 0 9 46 0.673789246514 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 10 0 21 40 0.711089872007 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 28 10 0 21 44 0.724189552495 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 10 0 24 34 0.78660445793 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 10 0 33 38 0.689247104327 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 29 10 0 36 44 0.892482541278 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 30 10 0 39 46 0.743841693835 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 31 10 0 45 42 0.675915254637 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 10 0 48 28 0.867874500271 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 10 0 48 32 0.843933612421 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 10 0 48 36 0.882490480554 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 10 0 51 46 0.7260388951 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 10 0 54 26 0.723548457528 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 10 0 54 40 0.688941454565 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 10 0 57 38 0.692369221065 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 10 0 60 30 0.851574151203 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 10 0 63 42 0.725848400909 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 10 0 72 24 0.844375616982 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 10 0 75 36 0.721617793685 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 10 0 75 44 0.733357608142 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 10 0 84 24 0.816385837458 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 10 0 84 42 0.797679015697 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 10 0 87 40 0.736436950535 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 10 0 93 40 0.678395248218 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 10 0 93 46 0.711345361166 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 10 0 96 24 0.852190617798 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 10 0 99 38 0.730783663308 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 10 0 114 26 0.746689002705 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 10 0 117 36 0.696057408747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 10 0 117 44 0.704912091309 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 10 0 120 26 0.89517776125 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 10 0 120 38 0.775461496957 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 25 10 0 123 36 0.671213642754 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 10 0 123 48 0.657357627725 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 9 3 0 [82, 82, 82, 82, 133]
+note_add 1 9 0 0 24 0.939922537979 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 9 0 0 32 0.919417513279 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 9 0 0 46 0.94323408296 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 9 0 3 40 0.698900010891 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 9 0 6 46 0.698856456031 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 9 9 0 9 46 0.73534413844 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 9 0 12 28 0.777449966123 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 9 0 15 36 0.745537315527 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 9 0 18 40 0.731967099614 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 9 0 18 46 0.659748039959 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 9 0 24 48 0.887567039913 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 9 0 27 48 0.67596583908 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 8 9 0 [82, 82, 82, 82, 133]
+note_add 31 8 0 0 24 0.925548542596 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 41 8 0 0 40 0.99515399493 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 51 8 0 3 42 0.656600534211 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 42 8 0 12 40 0.781608499687 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 52 8 0 18 42 0.746078356731 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 8 0 24 26 0.842788079016 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 8 0 24 30 0.858448377744 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 43 8 0 27 38 0.655557996923 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 8 0 36 24 0.84416548026 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 53 8 0 42 48 0.708755031747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 54 8 0 45 46 0.694252886906 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 8 0 48 28 0.790745114826 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 44 8 0 51 38 0.693079205578 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 55 8 0 51 48 0.723114366376 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 56 8 0 57 42 0.74000144627 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 45 8 0 60 36 0.844357847996 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 46 8 0 63 36 0.670774638825 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 57 8 0 69 42 0.666807403745 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 8 0 72 24 0.802855117652 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 39 8 0 72 32 0.850137481504 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 58 8 0 75 42 0.714082247268 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 8 0 84 28 0.854088386031 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 47 8 0 84 38 0.816924020176 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 48 8 0 87 38 0.698932384487 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 59 8 0 87 42 0.674609289728 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 8 0 96 26 0.884421425859 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 40 8 0 96 32 0.816095303092 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 49 8 0 96 40 0.85609056018 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 50 8 0 99 36 0.739998407875 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 60 8 0 99 48 0.735836941454 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 5 3 0 [82, 82, 82, 82, 133]
+note_add 13 5 0 0 28 0.948923051548 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 5 0 0 32 0.983674976389 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 5 0 3 38 0.676515455171 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 5 0 3 44 0.748902416777 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 5 0 9 42 0.721823750258 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 5 0 18 26 0.727501183971 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 5 0 18 42 0.692538780737 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 5 0 21 42 0.704638060569 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 5 0 27 38 0.699231033599 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 5 0 27 42 0.710291506584 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 5 0 33 38 0.740104587325 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 5 0 33 42 0.712509981931 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 11 9 0 [82, 82, 82, 82, 133]
+note_add 1 11 0 0 28 0.940708810641 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 11 0 0 30 0.917125893398 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 11 0 3 38 0.659757355829 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 21 11 0 3 46 0.691197364433 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 11 0 15 36 0.728363093232 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 22 11 0 15 48 0.651730437628 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 13 11 0 21 36 0.748099491714 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 23 11 0 21 42 0.691142328317 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 11 0 24 26 0.799430971651 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 14 11 0 24 36 0.789827858454 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 15 11 0 27 40 0.717847096017 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 24 11 0 27 46 0.68775950814 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 3 11 0 36 28 0.847659428446 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 16 11 0 39 38 0.724596484561 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 17 11 0 42 38 0.672521332617 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 25 11 0 45 42 0.707153905275 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 11 0 48 26 0.768231729212 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 11 0 48 30 0.797498430547 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 18 11 0 51 40 0.662933204402 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 26 11 0 51 46 0.652875237261 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 11 0 60 28 0.870729034797 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 19 11 0 63 38 0.699990604686 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 27 11 0 63 46 0.744299692171 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 28 11 0 69 42 0.674719518782 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 11 0 72 28 0.793569160964 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 20 11 0 75 36 0.743411205808 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 11 0 84 30 0.76896495703 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 29 11 0 87 46 0.739799809332 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 11 0 96 28 0.854769659604 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 30 11 0 96 48 0.88403154664 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 12 2 0 [88, 76, 56, 82, 135]
+note_add 1 12 0 0 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 12 0 3 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 12 0 6 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 12 0 9 41 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 12 0 12 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 12 0 15 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 12 0 18 38 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 12 0 21 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 13 5 0 [88, 76, 56, 82, 135]
+note_add 1 13 0 0 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 13 0 1 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 13 0 2 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 13 0 3 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 13 0 4 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 39 13 0 7 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 40 13 0 8 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 41 13 0 9 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 42 13 0 10 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 43 13 0 11 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 13 0 12 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 13 0 13 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 13 0 14 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 9 13 0 15 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 10 13 0 16 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 34 13 0 19 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 35 13 0 20 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 36 13 0 21 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 37 13 0 22 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 38 13 0 23 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 11 13 0 24 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 12 13 0 25 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 13 13 0 26 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 14 13 0 27 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 29 13 0 31 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 30 13 0 32 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 31 13 0 33 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 32 13 0 34 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 33 13 0 35 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 15 13 0 36 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 16 13 0 37 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 17 13 0 38 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 18 13 0 39 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 24 13 0 43 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 25 13 0 44 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 26 13 0 45 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 27 13 0 46 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 28 13 0 47 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 19 13 0 55 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 20 13 0 56 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 21 13 0 57 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 22 13 0 58 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 23 13 0 59 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 14 3 0 [82, 82, 82, 82, 133]
+note_add 3 14 0 0 30 0.900689216372 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 14 0 0 38 0.92403208165 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 1 14 0 6 24 0.710809973008 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 14 0 6 44 0.680687612344 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 14 0 9 48 0.689412655788 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 14 0 15 44 0.664335685932 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 14 0 21 44 0.699249583758 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 14 0 24 26 0.826542425289 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 14 0 27 38 0.737997319594 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 14 0 27 42 0.671027963479 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 14 0 33 40 0.727866267806 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 14 0 33 48 0.674593053365 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 15 7 0 [88, 77, 67, 85, 137]
+note_add 1 15 0 0 29 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 15 0 24 44 0.75 0.5 7.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 15 0 36 44 0.75 0.5 6.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 15 0 48 32 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+block_add Drum False 236 203 False {'name': 'drum5kit', 'regularity': 0.17265378043653012, 'page': 5, 'volume': 0.5, 'beats': 3, 'seed': 0.61058227696419964, 'reverb': 0.0, 'id': 137}
+block_add Instrument False 437 137 False {'volume': 0.5, 'reverb': 0, 'name': 'duck', 'pan': 0.5, 'id': 30}
+block_add Loop False 567 137 True {'name': 'loop1', 'id': 15}
+block_add Instrument True 431 302 False {'volume': 0.5, 'reverb': 0, 'name': 'rhodes', 'pan': 0.5, 'id': 85}
+block_add Instrument False 443 445 False {'volume': 0.5, 'reverb': 0, 'name': 'ow', 'pan': 0.5, 'id': 63}
+block_add Loop False 550 445 True {'name': 'loop2', 'id': 13}
+block_add Loop False 638 445 True {'name': 'loop3', 'id': 12}
+block_add Drum False 233 354 False {'name': 'drum2kit', 'regularity': 0.32130953701001352, 'id': 134, 'volume': 0.5, 'beats': 9, 'reverb': 0.0, 'page': 8}
diff --git a/common/Resources/Desktops/desktop5 b/common/Resources/Desktops/desktop5
new file mode 100644
index 0000000..3da73d9
--- /dev/null
+++ b/common/Resources/Desktops/desktop5
@@ -0,0 +1,206 @@
+page_add 10 11 0 [82, 82, 82, 82, 133]
+note_add 9 10 0 0 34 0.942260596881 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 13 10 0 3 38 0.72175977127 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 26 10 0 3 42 0.694338417824 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 1 10 0 6 26 0.725991648348 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 27 10 0 9 46 0.673789246514 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 10 0 21 40 0.711089872007 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 28 10 0 21 44 0.724189552495 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 10 0 24 34 0.78660445793 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 10 0 33 38 0.689247104327 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 29 10 0 36 44 0.892482541278 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 30 10 0 39 46 0.743841693835 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 31 10 0 45 42 0.675915254637 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 10 0 48 28 0.867874500271 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 10 0 48 32 0.843933612421 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 10 0 48 36 0.882490480554 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 10 0 51 46 0.7260388951 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 10 0 54 26 0.723548457528 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 10 0 54 40 0.688941454565 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 10 0 57 38 0.692369221065 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 10 0 60 30 0.851574151203 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 10 0 63 42 0.725848400909 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 10 0 72 24 0.844375616982 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 10 0 75 36 0.721617793685 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 10 0 75 44 0.733357608142 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 10 0 84 24 0.816385837458 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 10 0 84 42 0.797679015697 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 10 0 87 40 0.736436950535 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 10 0 93 40 0.678395248218 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 10 0 93 46 0.711345361166 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 10 0 96 24 0.852190617798 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 10 0 99 38 0.730783663308 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 10 0 114 26 0.746689002705 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 10 0 117 36 0.696057408747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 10 0 117 44 0.704912091309 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 10 0 120 26 0.89517776125 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 10 0 120 38 0.775461496957 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 25 10 0 123 36 0.671213642754 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 10 0 123 48 0.657357627725 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 9 3 0 [82, 82, 82, 82, 133]
+note_add 1 9 0 0 24 0.939922537979 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 9 0 0 32 0.919417513279 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 9 0 0 46 0.94323408296 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 9 0 3 40 0.698900010891 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 9 0 6 46 0.698856456031 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 9 9 0 9 46 0.73534413844 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 9 0 12 28 0.777449966123 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 9 0 15 36 0.745537315527 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 9 0 18 40 0.731967099614 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 9 0 18 46 0.659748039959 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 9 0 24 48 0.887567039913 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 9 0 27 48 0.67596583908 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 8 9 0 [82, 82, 82, 82, 133]
+note_add 31 8 0 0 24 0.925548542596 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 41 8 0 0 40 0.99515399493 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 51 8 0 3 42 0.656600534211 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 42 8 0 12 40 0.781608499687 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 52 8 0 18 42 0.746078356731 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 8 0 24 26 0.842788079016 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 8 0 24 30 0.858448377744 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 43 8 0 27 38 0.655557996923 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 8 0 36 24 0.84416548026 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 53 8 0 42 48 0.708755031747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 54 8 0 45 46 0.694252886906 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 8 0 48 28 0.790745114826 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 44 8 0 51 38 0.693079205578 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 55 8 0 51 48 0.723114366376 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 56 8 0 57 42 0.74000144627 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 45 8 0 60 36 0.844357847996 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 46 8 0 63 36 0.670774638825 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 57 8 0 69 42 0.666807403745 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 8 0 72 24 0.802855117652 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 39 8 0 72 32 0.850137481504 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 58 8 0 75 42 0.714082247268 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 8 0 84 28 0.854088386031 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 47 8 0 84 38 0.816924020176 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 48 8 0 87 38 0.698932384487 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 59 8 0 87 42 0.674609289728 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 8 0 96 26 0.884421425859 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 40 8 0 96 32 0.816095303092 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 49 8 0 96 40 0.85609056018 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 50 8 0 99 36 0.739998407875 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 60 8 0 99 48 0.735836941454 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 5 3 0 [82, 82, 82, 82, 133]
+note_add 13 5 0 0 28 0.948923051548 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 5 0 0 32 0.983674976389 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 5 0 3 38 0.676515455171 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 5 0 3 44 0.748902416777 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 5 0 9 42 0.721823750258 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 5 0 18 26 0.727501183971 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 5 0 18 42 0.692538780737 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 5 0 21 42 0.704638060569 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 5 0 27 38 0.699231033599 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 5 0 27 42 0.710291506584 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 5 0 33 38 0.740104587325 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 5 0 33 42 0.712509981931 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 11 9 0 [82, 82, 82, 82, 133]
+note_add 1 11 0 0 28 0.940708810641 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 11 0 0 30 0.917125893398 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 11 0 3 38 0.659757355829 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 21 11 0 3 46 0.691197364433 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 11 0 15 36 0.728363093232 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 22 11 0 15 48 0.651730437628 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 13 11 0 21 36 0.748099491714 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 23 11 0 21 42 0.691142328317 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 11 0 24 26 0.799430971651 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 14 11 0 24 36 0.789827858454 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 15 11 0 27 40 0.717847096017 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 24 11 0 27 46 0.68775950814 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 3 11 0 36 28 0.847659428446 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 16 11 0 39 38 0.724596484561 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 17 11 0 42 38 0.672521332617 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 25 11 0 45 42 0.707153905275 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 11 0 48 26 0.768231729212 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 11 0 48 30 0.797498430547 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 18 11 0 51 40 0.662933204402 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 26 11 0 51 46 0.652875237261 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 11 0 60 28 0.870729034797 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 19 11 0 63 38 0.699990604686 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 27 11 0 63 46 0.744299692171 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 28 11 0 69 42 0.674719518782 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 11 0 72 28 0.793569160964 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 20 11 0 75 36 0.743411205808 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 11 0 84 30 0.76896495703 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 29 11 0 87 46 0.739799809332 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 11 0 96 28 0.854769659604 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 30 11 0 96 48 0.88403154664 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 12 2 0 [88, 76, 56, 82, 135]
+note_add 1 12 0 0 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 12 0 3 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 12 0 6 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 12 0 9 41 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 12 0 12 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 12 0 15 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 12 0 18 38 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 12 0 21 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 13 5 0 [88, 76, 56, 82, 135]
+note_add 1 13 0 0 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 13 0 1 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 13 0 2 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 13 0 3 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 13 0 4 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 39 13 0 7 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 40 13 0 8 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 41 13 0 9 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 42 13 0 10 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 43 13 0 11 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 13 0 12 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 13 0 13 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 13 0 14 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 9 13 0 15 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 10 13 0 16 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 34 13 0 19 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 35 13 0 20 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 36 13 0 21 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 37 13 0 22 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 38 13 0 23 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 11 13 0 24 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 12 13 0 25 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 13 13 0 26 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 14 13 0 27 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 29 13 0 31 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 30 13 0 32 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 31 13 0 33 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 32 13 0 34 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 33 13 0 35 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 15 13 0 36 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 16 13 0 37 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 17 13 0 38 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 18 13 0 39 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 24 13 0 43 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 25 13 0 44 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 26 13 0 45 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 27 13 0 46 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 28 13 0 47 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 19 13 0 55 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 20 13 0 56 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 21 13 0 57 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 22 13 0 58 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 23 13 0 59 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 14 3 0 [82, 82, 82, 82, 133]
+note_add 3 14 0 0 30 0.900689216372 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 14 0 0 38 0.92403208165 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 1 14 0 6 24 0.710809973008 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 14 0 6 44 0.680687612344 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 14 0 9 48 0.689412655788 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 14 0 15 44 0.664335685932 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 14 0 21 44 0.699249583758 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 14 0 24 26 0.826542425289 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 14 0 27 38 0.737997319594 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 14 0 27 42 0.671027963479 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 14 0 33 40 0.727866267806 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 14 0 33 48 0.674593053365 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 15 7 0 [88, 77, 67, 85, 137]
+note_add 1 15 0 0 29 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 15 0 24 44 0.75 0.5 7.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 15 0 36 44 0.75 0.5 6.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 15 0 48 32 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+block_add Drum False 236 203 False {'name': 'drum5kit', 'regularity': 0.17265378043653012, 'page': 5, 'volume': 0.5, 'beats': 3, 'seed': 0.61058227696419964, 'reverb': 0.0, 'id': 137}
+block_add Instrument False 437 137 False {'volume': 0.5, 'reverb': 0, 'name': 'duck', 'pan': 0.5, 'id': 30}
+block_add Loop False 567 137 True {'name': 'loop1', 'id': 15}
+block_add Instrument True 431 302 False {'volume': 0.5, 'reverb': 0, 'name': 'rhodes', 'pan': 0.5, 'id': 85}
+block_add Instrument False 443 445 False {'volume': 0.5, 'reverb': 0, 'name': 'ow', 'pan': 0.5, 'id': 63}
+block_add Loop False 550 445 True {'name': 'loop2', 'id': 13}
+block_add Loop False 638 445 True {'name': 'loop3', 'id': 12}
+block_add Drum False 233 354 False {'name': 'drum2kit', 'regularity': 0.32130953701001352, 'id': 134, 'volume': 0.5, 'beats': 9, 'reverb': 0.0, 'page': 8}
diff --git a/common/Resources/Desktops/desktop6 b/common/Resources/Desktops/desktop6
new file mode 100644
index 0000000..3da73d9
--- /dev/null
+++ b/common/Resources/Desktops/desktop6
@@ -0,0 +1,206 @@
+page_add 10 11 0 [82, 82, 82, 82, 133]
+note_add 9 10 0 0 34 0.942260596881 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 13 10 0 3 38 0.72175977127 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 26 10 0 3 42 0.694338417824 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 1 10 0 6 26 0.725991648348 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 27 10 0 9 46 0.673789246514 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 10 0 21 40 0.711089872007 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 28 10 0 21 44 0.724189552495 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 10 0 24 34 0.78660445793 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 10 0 33 38 0.689247104327 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 29 10 0 36 44 0.892482541278 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 30 10 0 39 46 0.743841693835 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 31 10 0 45 42 0.675915254637 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 10 0 48 28 0.867874500271 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 10 0 48 32 0.843933612421 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 10 0 48 36 0.882490480554 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 10 0 51 46 0.7260388951 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 10 0 54 26 0.723548457528 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 10 0 54 40 0.688941454565 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 10 0 57 38 0.692369221065 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 10 0 60 30 0.851574151203 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 10 0 63 42 0.725848400909 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 10 0 72 24 0.844375616982 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 10 0 75 36 0.721617793685 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 10 0 75 44 0.733357608142 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 10 0 84 24 0.816385837458 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 10 0 84 42 0.797679015697 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 10 0 87 40 0.736436950535 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 10 0 93 40 0.678395248218 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 10 0 93 46 0.711345361166 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 10 0 96 24 0.852190617798 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 10 0 99 38 0.730783663308 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 10 0 114 26 0.746689002705 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 10 0 117 36 0.696057408747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 10 0 117 44 0.704912091309 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 10 0 120 26 0.89517776125 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 10 0 120 38 0.775461496957 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 25 10 0 123 36 0.671213642754 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 10 0 123 48 0.657357627725 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 9 3 0 [82, 82, 82, 82, 133]
+note_add 1 9 0 0 24 0.939922537979 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 9 0 0 32 0.919417513279 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 9 0 0 46 0.94323408296 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 9 0 3 40 0.698900010891 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 9 0 6 46 0.698856456031 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 9 9 0 9 46 0.73534413844 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 9 0 12 28 0.777449966123 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 9 0 15 36 0.745537315527 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 9 0 18 40 0.731967099614 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 9 0 18 46 0.659748039959 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 9 0 24 48 0.887567039913 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 9 0 27 48 0.67596583908 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 8 9 0 [82, 82, 82, 82, 133]
+note_add 31 8 0 0 24 0.925548542596 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 41 8 0 0 40 0.99515399493 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 51 8 0 3 42 0.656600534211 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 42 8 0 12 40 0.781608499687 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 52 8 0 18 42 0.746078356731 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 8 0 24 26 0.842788079016 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 8 0 24 30 0.858448377744 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 43 8 0 27 38 0.655557996923 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 8 0 36 24 0.84416548026 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 53 8 0 42 48 0.708755031747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 54 8 0 45 46 0.694252886906 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 8 0 48 28 0.790745114826 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 44 8 0 51 38 0.693079205578 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 55 8 0 51 48 0.723114366376 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 56 8 0 57 42 0.74000144627 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 45 8 0 60 36 0.844357847996 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 46 8 0 63 36 0.670774638825 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 57 8 0 69 42 0.666807403745 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 8 0 72 24 0.802855117652 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 39 8 0 72 32 0.850137481504 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 58 8 0 75 42 0.714082247268 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 8 0 84 28 0.854088386031 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 47 8 0 84 38 0.816924020176 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 48 8 0 87 38 0.698932384487 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 59 8 0 87 42 0.674609289728 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 8 0 96 26 0.884421425859 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 40 8 0 96 32 0.816095303092 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 49 8 0 96 40 0.85609056018 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 50 8 0 99 36 0.739998407875 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 60 8 0 99 48 0.735836941454 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 5 3 0 [82, 82, 82, 82, 133]
+note_add 13 5 0 0 28 0.948923051548 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 5 0 0 32 0.983674976389 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 5 0 3 38 0.676515455171 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 5 0 3 44 0.748902416777 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 5 0 9 42 0.721823750258 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 5 0 18 26 0.727501183971 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 5 0 18 42 0.692538780737 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 5 0 21 42 0.704638060569 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 5 0 27 38 0.699231033599 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 5 0 27 42 0.710291506584 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 5 0 33 38 0.740104587325 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 5 0 33 42 0.712509981931 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 11 9 0 [82, 82, 82, 82, 133]
+note_add 1 11 0 0 28 0.940708810641 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 11 0 0 30 0.917125893398 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 11 0 3 38 0.659757355829 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 21 11 0 3 46 0.691197364433 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 11 0 15 36 0.728363093232 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 22 11 0 15 48 0.651730437628 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 13 11 0 21 36 0.748099491714 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 23 11 0 21 42 0.691142328317 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 11 0 24 26 0.799430971651 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 14 11 0 24 36 0.789827858454 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 15 11 0 27 40 0.717847096017 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 24 11 0 27 46 0.68775950814 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 3 11 0 36 28 0.847659428446 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 16 11 0 39 38 0.724596484561 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 17 11 0 42 38 0.672521332617 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 25 11 0 45 42 0.707153905275 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 11 0 48 26 0.768231729212 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 11 0 48 30 0.797498430547 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 18 11 0 51 40 0.662933204402 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 26 11 0 51 46 0.652875237261 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 11 0 60 28 0.870729034797 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 19 11 0 63 38 0.699990604686 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 27 11 0 63 46 0.744299692171 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 28 11 0 69 42 0.674719518782 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 11 0 72 28 0.793569160964 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 20 11 0 75 36 0.743411205808 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 11 0 84 30 0.76896495703 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 29 11 0 87 46 0.739799809332 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 11 0 96 28 0.854769659604 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 30 11 0 96 48 0.88403154664 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 12 2 0 [88, 76, 56, 82, 135]
+note_add 1 12 0 0 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 12 0 3 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 12 0 6 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 12 0 9 41 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 12 0 12 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 12 0 15 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 12 0 18 38 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 12 0 21 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 13 5 0 [88, 76, 56, 82, 135]
+note_add 1 13 0 0 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 13 0 1 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 13 0 2 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 13 0 3 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 13 0 4 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 39 13 0 7 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 40 13 0 8 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 41 13 0 9 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 42 13 0 10 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 43 13 0 11 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 13 0 12 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 13 0 13 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 13 0 14 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 9 13 0 15 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 10 13 0 16 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 34 13 0 19 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 35 13 0 20 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 36 13 0 21 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 37 13 0 22 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 38 13 0 23 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 11 13 0 24 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 12 13 0 25 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 13 13 0 26 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 14 13 0 27 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 29 13 0 31 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 30 13 0 32 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 31 13 0 33 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 32 13 0 34 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 33 13 0 35 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 15 13 0 36 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 16 13 0 37 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 17 13 0 38 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 18 13 0 39 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 24 13 0 43 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 25 13 0 44 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 26 13 0 45 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 27 13 0 46 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 28 13 0 47 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 19 13 0 55 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 20 13 0 56 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 21 13 0 57 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 22 13 0 58 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 23 13 0 59 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 14 3 0 [82, 82, 82, 82, 133]
+note_add 3 14 0 0 30 0.900689216372 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 14 0 0 38 0.92403208165 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 1 14 0 6 24 0.710809973008 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 14 0 6 44 0.680687612344 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 14 0 9 48 0.689412655788 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 14 0 15 44 0.664335685932 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 14 0 21 44 0.699249583758 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 14 0 24 26 0.826542425289 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 14 0 27 38 0.737997319594 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 14 0 27 42 0.671027963479 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 14 0 33 40 0.727866267806 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 14 0 33 48 0.674593053365 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 15 7 0 [88, 77, 67, 85, 137]
+note_add 1 15 0 0 29 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 15 0 24 44 0.75 0.5 7.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 15 0 36 44 0.75 0.5 6.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 15 0 48 32 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+block_add Drum False 236 203 False {'name': 'drum5kit', 'regularity': 0.17265378043653012, 'page': 5, 'volume': 0.5, 'beats': 3, 'seed': 0.61058227696419964, 'reverb': 0.0, 'id': 137}
+block_add Instrument False 437 137 False {'volume': 0.5, 'reverb': 0, 'name': 'duck', 'pan': 0.5, 'id': 30}
+block_add Loop False 567 137 True {'name': 'loop1', 'id': 15}
+block_add Instrument True 431 302 False {'volume': 0.5, 'reverb': 0, 'name': 'rhodes', 'pan': 0.5, 'id': 85}
+block_add Instrument False 443 445 False {'volume': 0.5, 'reverb': 0, 'name': 'ow', 'pan': 0.5, 'id': 63}
+block_add Loop False 550 445 True {'name': 'loop2', 'id': 13}
+block_add Loop False 638 445 True {'name': 'loop3', 'id': 12}
+block_add Drum False 233 354 False {'name': 'drum2kit', 'regularity': 0.32130953701001352, 'id': 134, 'volume': 0.5, 'beats': 9, 'reverb': 0.0, 'page': 8}
diff --git a/common/Resources/Desktops/desktop7 b/common/Resources/Desktops/desktop7
new file mode 100644
index 0000000..3da73d9
--- /dev/null
+++ b/common/Resources/Desktops/desktop7
@@ -0,0 +1,206 @@
+page_add 10 11 0 [82, 82, 82, 82, 133]
+note_add 9 10 0 0 34 0.942260596881 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 13 10 0 3 38 0.72175977127 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 26 10 0 3 42 0.694338417824 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 1 10 0 6 26 0.725991648348 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 27 10 0 9 46 0.673789246514 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 10 0 21 40 0.711089872007 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 28 10 0 21 44 0.724189552495 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 10 0 24 34 0.78660445793 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 10 0 33 38 0.689247104327 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 29 10 0 36 44 0.892482541278 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 30 10 0 39 46 0.743841693835 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 31 10 0 45 42 0.675915254637 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 10 0 48 28 0.867874500271 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 10 0 48 32 0.843933612421 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 10 0 48 36 0.882490480554 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 10 0 51 46 0.7260388951 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 10 0 54 26 0.723548457528 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 10 0 54 40 0.688941454565 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 10 0 57 38 0.692369221065 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 10 0 60 30 0.851574151203 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 10 0 63 42 0.725848400909 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 10 0 72 24 0.844375616982 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 10 0 75 36 0.721617793685 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 10 0 75 44 0.733357608142 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 10 0 84 24 0.816385837458 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 10 0 84 42 0.797679015697 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 10 0 87 40 0.736436950535 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 10 0 93 40 0.678395248218 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 10 0 93 46 0.711345361166 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 10 0 96 24 0.852190617798 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 10 0 99 38 0.730783663308 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 10 0 114 26 0.746689002705 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 10 0 117 36 0.696057408747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 10 0 117 44 0.704912091309 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 10 0 120 26 0.89517776125 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 10 0 120 38 0.775461496957 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 25 10 0 123 36 0.671213642754 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 10 0 123 48 0.657357627725 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 9 3 0 [82, 82, 82, 82, 133]
+note_add 1 9 0 0 24 0.939922537979 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 9 0 0 32 0.919417513279 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 9 0 0 46 0.94323408296 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 9 0 3 40 0.698900010891 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 9 0 6 46 0.698856456031 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 9 9 0 9 46 0.73534413844 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 9 0 12 28 0.777449966123 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 9 0 15 36 0.745537315527 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 9 0 18 40 0.731967099614 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 9 0 18 46 0.659748039959 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 9 0 24 48 0.887567039913 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 9 0 27 48 0.67596583908 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 8 9 0 [82, 82, 82, 82, 133]
+note_add 31 8 0 0 24 0.925548542596 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 41 8 0 0 40 0.99515399493 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 51 8 0 3 42 0.656600534211 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 42 8 0 12 40 0.781608499687 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 52 8 0 18 42 0.746078356731 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 8 0 24 26 0.842788079016 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 8 0 24 30 0.858448377744 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 43 8 0 27 38 0.655557996923 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 8 0 36 24 0.84416548026 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 53 8 0 42 48 0.708755031747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 54 8 0 45 46 0.694252886906 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 8 0 48 28 0.790745114826 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 44 8 0 51 38 0.693079205578 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 55 8 0 51 48 0.723114366376 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 56 8 0 57 42 0.74000144627 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 45 8 0 60 36 0.844357847996 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 46 8 0 63 36 0.670774638825 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 57 8 0 69 42 0.666807403745 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 8 0 72 24 0.802855117652 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 39 8 0 72 32 0.850137481504 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 58 8 0 75 42 0.714082247268 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 8 0 84 28 0.854088386031 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 47 8 0 84 38 0.816924020176 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 48 8 0 87 38 0.698932384487 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 59 8 0 87 42 0.674609289728 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 8 0 96 26 0.884421425859 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 40 8 0 96 32 0.816095303092 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 49 8 0 96 40 0.85609056018 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 50 8 0 99 36 0.739998407875 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 60 8 0 99 48 0.735836941454 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 5 3 0 [82, 82, 82, 82, 133]
+note_add 13 5 0 0 28 0.948923051548 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 5 0 0 32 0.983674976389 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 5 0 3 38 0.676515455171 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 5 0 3 44 0.748902416777 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 5 0 9 42 0.721823750258 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 5 0 18 26 0.727501183971 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 5 0 18 42 0.692538780737 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 5 0 21 42 0.704638060569 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 5 0 27 38 0.699231033599 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 5 0 27 42 0.710291506584 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 5 0 33 38 0.740104587325 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 5 0 33 42 0.712509981931 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 11 9 0 [82, 82, 82, 82, 133]
+note_add 1 11 0 0 28 0.940708810641 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 11 0 0 30 0.917125893398 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 11 0 3 38 0.659757355829 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 21 11 0 3 46 0.691197364433 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 11 0 15 36 0.728363093232 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 22 11 0 15 48 0.651730437628 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 13 11 0 21 36 0.748099491714 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 23 11 0 21 42 0.691142328317 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 11 0 24 26 0.799430971651 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 14 11 0 24 36 0.789827858454 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 15 11 0 27 40 0.717847096017 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 24 11 0 27 46 0.68775950814 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 3 11 0 36 28 0.847659428446 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 16 11 0 39 38 0.724596484561 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 17 11 0 42 38 0.672521332617 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 25 11 0 45 42 0.707153905275 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 11 0 48 26 0.768231729212 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 11 0 48 30 0.797498430547 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 18 11 0 51 40 0.662933204402 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 26 11 0 51 46 0.652875237261 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 11 0 60 28 0.870729034797 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 19 11 0 63 38 0.699990604686 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 27 11 0 63 46 0.744299692171 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 28 11 0 69 42 0.674719518782 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 11 0 72 28 0.793569160964 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 20 11 0 75 36 0.743411205808 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 11 0 84 30 0.76896495703 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 29 11 0 87 46 0.739799809332 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 11 0 96 28 0.854769659604 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 30 11 0 96 48 0.88403154664 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 12 2 0 [88, 76, 56, 82, 135]
+note_add 1 12 0 0 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 12 0 3 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 12 0 6 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 12 0 9 41 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 12 0 12 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 12 0 15 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 12 0 18 38 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 12 0 21 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 13 5 0 [88, 76, 56, 82, 135]
+note_add 1 13 0 0 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 13 0 1 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 13 0 2 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 13 0 3 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 13 0 4 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 39 13 0 7 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 40 13 0 8 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 41 13 0 9 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 42 13 0 10 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 43 13 0 11 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 13 0 12 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 13 0 13 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 13 0 14 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 9 13 0 15 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 10 13 0 16 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 34 13 0 19 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 35 13 0 20 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 36 13 0 21 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 37 13 0 22 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 38 13 0 23 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 11 13 0 24 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 12 13 0 25 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 13 13 0 26 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 14 13 0 27 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 29 13 0 31 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 30 13 0 32 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 31 13 0 33 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 32 13 0 34 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 33 13 0 35 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 15 13 0 36 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 16 13 0 37 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 17 13 0 38 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 18 13 0 39 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 24 13 0 43 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 25 13 0 44 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 26 13 0 45 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 27 13 0 46 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 28 13 0 47 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 19 13 0 55 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 20 13 0 56 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 21 13 0 57 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 22 13 0 58 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 23 13 0 59 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 14 3 0 [82, 82, 82, 82, 133]
+note_add 3 14 0 0 30 0.900689216372 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 14 0 0 38 0.92403208165 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 1 14 0 6 24 0.710809973008 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 14 0 6 44 0.680687612344 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 14 0 9 48 0.689412655788 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 14 0 15 44 0.664335685932 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 14 0 21 44 0.699249583758 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 14 0 24 26 0.826542425289 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 14 0 27 38 0.737997319594 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 14 0 27 42 0.671027963479 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 14 0 33 40 0.727866267806 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 14 0 33 48 0.674593053365 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 15 7 0 [88, 77, 67, 85, 137]
+note_add 1 15 0 0 29 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 15 0 24 44 0.75 0.5 7.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 15 0 36 44 0.75 0.5 6.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 15 0 48 32 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+block_add Drum False 236 203 False {'name': 'drum5kit', 'regularity': 0.17265378043653012, 'page': 5, 'volume': 0.5, 'beats': 3, 'seed': 0.61058227696419964, 'reverb': 0.0, 'id': 137}
+block_add Instrument False 437 137 False {'volume': 0.5, 'reverb': 0, 'name': 'duck', 'pan': 0.5, 'id': 30}
+block_add Loop False 567 137 True {'name': 'loop1', 'id': 15}
+block_add Instrument True 431 302 False {'volume': 0.5, 'reverb': 0, 'name': 'rhodes', 'pan': 0.5, 'id': 85}
+block_add Instrument False 443 445 False {'volume': 0.5, 'reverb': 0, 'name': 'ow', 'pan': 0.5, 'id': 63}
+block_add Loop False 550 445 True {'name': 'loop2', 'id': 13}
+block_add Loop False 638 445 True {'name': 'loop3', 'id': 12}
+block_add Drum False 233 354 False {'name': 'drum2kit', 'regularity': 0.32130953701001352, 'id': 134, 'volume': 0.5, 'beats': 9, 'reverb': 0.0, 'page': 8}
diff --git a/common/Resources/Desktops/desktop8 b/common/Resources/Desktops/desktop8
new file mode 100644
index 0000000..3da73d9
--- /dev/null
+++ b/common/Resources/Desktops/desktop8
@@ -0,0 +1,206 @@
+page_add 10 11 0 [82, 82, 82, 82, 133]
+note_add 9 10 0 0 34 0.942260596881 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 13 10 0 3 38 0.72175977127 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 26 10 0 3 42 0.694338417824 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 1 10 0 6 26 0.725991648348 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 27 10 0 9 46 0.673789246514 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 10 0 21 40 0.711089872007 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 28 10 0 21 44 0.724189552495 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 10 0 24 34 0.78660445793 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 10 0 33 38 0.689247104327 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 29 10 0 36 44 0.892482541278 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 30 10 0 39 46 0.743841693835 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 31 10 0 45 42 0.675915254637 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 10 0 48 28 0.867874500271 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 10 0 48 32 0.843933612421 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 10 0 48 36 0.882490480554 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 10 0 51 46 0.7260388951 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 10 0 54 26 0.723548457528 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 10 0 54 40 0.688941454565 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 10 0 57 38 0.692369221065 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 10 0 60 30 0.851574151203 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 10 0 63 42 0.725848400909 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 10 0 72 24 0.844375616982 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 10 0 75 36 0.721617793685 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 10 0 75 44 0.733357608142 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 10 0 84 24 0.816385837458 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 10 0 84 42 0.797679015697 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 10 0 87 40 0.736436950535 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 10 0 93 40 0.678395248218 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 10 0 93 46 0.711345361166 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 10 0 96 24 0.852190617798 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 10 0 99 38 0.730783663308 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 10 0 114 26 0.746689002705 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 10 0 117 36 0.696057408747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 10 0 117 44 0.704912091309 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 10 0 120 26 0.89517776125 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 10 0 120 38 0.775461496957 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 25 10 0 123 36 0.671213642754 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 10 0 123 48 0.657357627725 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 9 3 0 [82, 82, 82, 82, 133]
+note_add 1 9 0 0 24 0.939922537979 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 9 0 0 32 0.919417513279 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 9 0 0 46 0.94323408296 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 9 0 3 40 0.698900010891 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 9 0 6 46 0.698856456031 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 9 9 0 9 46 0.73534413844 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 9 0 12 28 0.777449966123 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 9 0 15 36 0.745537315527 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 9 0 18 40 0.731967099614 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 9 0 18 46 0.659748039959 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 9 0 24 48 0.887567039913 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 9 0 27 48 0.67596583908 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 8 9 0 [82, 82, 82, 82, 133]
+note_add 31 8 0 0 24 0.925548542596 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 41 8 0 0 40 0.99515399493 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 51 8 0 3 42 0.656600534211 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 42 8 0 12 40 0.781608499687 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 52 8 0 18 42 0.746078356731 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 8 0 24 26 0.842788079016 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 8 0 24 30 0.858448377744 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 43 8 0 27 38 0.655557996923 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 8 0 36 24 0.84416548026 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 53 8 0 42 48 0.708755031747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 54 8 0 45 46 0.694252886906 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 8 0 48 28 0.790745114826 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 44 8 0 51 38 0.693079205578 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 55 8 0 51 48 0.723114366376 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 56 8 0 57 42 0.74000144627 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 45 8 0 60 36 0.844357847996 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 46 8 0 63 36 0.670774638825 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 57 8 0 69 42 0.666807403745 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 8 0 72 24 0.802855117652 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 39 8 0 72 32 0.850137481504 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 58 8 0 75 42 0.714082247268 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 8 0 84 28 0.854088386031 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 47 8 0 84 38 0.816924020176 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 48 8 0 87 38 0.698932384487 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 59 8 0 87 42 0.674609289728 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 8 0 96 26 0.884421425859 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 40 8 0 96 32 0.816095303092 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 49 8 0 96 40 0.85609056018 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 50 8 0 99 36 0.739998407875 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 60 8 0 99 48 0.735836941454 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 5 3 0 [82, 82, 82, 82, 133]
+note_add 13 5 0 0 28 0.948923051548 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 5 0 0 32 0.983674976389 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 5 0 3 38 0.676515455171 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 5 0 3 44 0.748902416777 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 5 0 9 42 0.721823750258 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 5 0 18 26 0.727501183971 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 5 0 18 42 0.692538780737 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 5 0 21 42 0.704638060569 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 5 0 27 38 0.699231033599 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 5 0 27 42 0.710291506584 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 5 0 33 38 0.740104587325 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 5 0 33 42 0.712509981931 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 11 9 0 [82, 82, 82, 82, 133]
+note_add 1 11 0 0 28 0.940708810641 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 11 0 0 30 0.917125893398 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 11 0 3 38 0.659757355829 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 21 11 0 3 46 0.691197364433 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 11 0 15 36 0.728363093232 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 22 11 0 15 48 0.651730437628 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 13 11 0 21 36 0.748099491714 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 23 11 0 21 42 0.691142328317 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 11 0 24 26 0.799430971651 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 14 11 0 24 36 0.789827858454 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 15 11 0 27 40 0.717847096017 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 24 11 0 27 46 0.68775950814 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 3 11 0 36 28 0.847659428446 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 16 11 0 39 38 0.724596484561 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 17 11 0 42 38 0.672521332617 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 25 11 0 45 42 0.707153905275 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 11 0 48 26 0.768231729212 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 11 0 48 30 0.797498430547 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 18 11 0 51 40 0.662933204402 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 26 11 0 51 46 0.652875237261 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 11 0 60 28 0.870729034797 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 19 11 0 63 38 0.699990604686 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 27 11 0 63 46 0.744299692171 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 28 11 0 69 42 0.674719518782 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 11 0 72 28 0.793569160964 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 20 11 0 75 36 0.743411205808 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 11 0 84 30 0.76896495703 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 29 11 0 87 46 0.739799809332 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 11 0 96 28 0.854769659604 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 30 11 0 96 48 0.88403154664 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 12 2 0 [88, 76, 56, 82, 135]
+note_add 1 12 0 0 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 12 0 3 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 12 0 6 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 12 0 9 41 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 12 0 12 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 12 0 15 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 12 0 18 38 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 12 0 21 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 13 5 0 [88, 76, 56, 82, 135]
+note_add 1 13 0 0 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 13 0 1 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 13 0 2 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 13 0 3 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 13 0 4 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 39 13 0 7 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 40 13 0 8 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 41 13 0 9 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 42 13 0 10 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 43 13 0 11 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 13 0 12 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 13 0 13 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 13 0 14 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 9 13 0 15 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 10 13 0 16 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 34 13 0 19 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 35 13 0 20 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 36 13 0 21 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 37 13 0 22 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 38 13 0 23 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 11 13 0 24 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 12 13 0 25 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 13 13 0 26 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 14 13 0 27 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 29 13 0 31 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 30 13 0 32 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 31 13 0 33 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 32 13 0 34 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 33 13 0 35 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 15 13 0 36 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 16 13 0 37 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 17 13 0 38 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 18 13 0 39 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 24 13 0 43 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 25 13 0 44 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 26 13 0 45 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 27 13 0 46 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 28 13 0 47 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 19 13 0 55 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 20 13 0 56 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 21 13 0 57 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 22 13 0 58 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 23 13 0 59 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 14 3 0 [82, 82, 82, 82, 133]
+note_add 3 14 0 0 30 0.900689216372 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 14 0 0 38 0.92403208165 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 1 14 0 6 24 0.710809973008 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 14 0 6 44 0.680687612344 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 14 0 9 48 0.689412655788 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 14 0 15 44 0.664335685932 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 14 0 21 44 0.699249583758 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 14 0 24 26 0.826542425289 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 14 0 27 38 0.737997319594 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 14 0 27 42 0.671027963479 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 14 0 33 40 0.727866267806 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 14 0 33 48 0.674593053365 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 15 7 0 [88, 77, 67, 85, 137]
+note_add 1 15 0 0 29 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 15 0 24 44 0.75 0.5 7.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 15 0 36 44 0.75 0.5 6.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 15 0 48 32 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+block_add Drum False 236 203 False {'name': 'drum5kit', 'regularity': 0.17265378043653012, 'page': 5, 'volume': 0.5, 'beats': 3, 'seed': 0.61058227696419964, 'reverb': 0.0, 'id': 137}
+block_add Instrument False 437 137 False {'volume': 0.5, 'reverb': 0, 'name': 'duck', 'pan': 0.5, 'id': 30}
+block_add Loop False 567 137 True {'name': 'loop1', 'id': 15}
+block_add Instrument True 431 302 False {'volume': 0.5, 'reverb': 0, 'name': 'rhodes', 'pan': 0.5, 'id': 85}
+block_add Instrument False 443 445 False {'volume': 0.5, 'reverb': 0, 'name': 'ow', 'pan': 0.5, 'id': 63}
+block_add Loop False 550 445 True {'name': 'loop2', 'id': 13}
+block_add Loop False 638 445 True {'name': 'loop3', 'id': 12}
+block_add Drum False 233 354 False {'name': 'drum2kit', 'regularity': 0.32130953701001352, 'id': 134, 'volume': 0.5, 'beats': 9, 'reverb': 0.0, 'page': 8}
diff --git a/common/Resources/Desktops/desktop9 b/common/Resources/Desktops/desktop9
new file mode 100644
index 0000000..3da73d9
--- /dev/null
+++ b/common/Resources/Desktops/desktop9
@@ -0,0 +1,206 @@
+page_add 10 11 0 [82, 82, 82, 82, 133]
+note_add 9 10 0 0 34 0.942260596881 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 13 10 0 3 38 0.72175977127 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 26 10 0 3 42 0.694338417824 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 1 10 0 6 26 0.725991648348 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 27 10 0 9 46 0.673789246514 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 10 0 21 40 0.711089872007 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 28 10 0 21 44 0.724189552495 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 10 0 24 34 0.78660445793 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 10 0 33 38 0.689247104327 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 29 10 0 36 44 0.892482541278 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 30 10 0 39 46 0.743841693835 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 31 10 0 45 42 0.675915254637 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 10 0 48 28 0.867874500271 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 10 0 48 32 0.843933612421 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 10 0 48 36 0.882490480554 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 10 0 51 46 0.7260388951 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 10 0 54 26 0.723548457528 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 10 0 54 40 0.688941454565 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 10 0 57 38 0.692369221065 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 10 0 60 30 0.851574151203 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 10 0 63 42 0.725848400909 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 10 0 72 24 0.844375616982 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 10 0 75 36 0.721617793685 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 10 0 75 44 0.733357608142 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 10 0 84 24 0.816385837458 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 10 0 84 42 0.797679015697 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 10 0 87 40 0.736436950535 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 10 0 93 40 0.678395248218 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 10 0 93 46 0.711345361166 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 10 0 96 24 0.852190617798 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 10 0 99 38 0.730783663308 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 10 0 114 26 0.746689002705 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 10 0 117 36 0.696057408747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 10 0 117 44 0.704912091309 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 10 0 120 26 0.89517776125 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 10 0 120 38 0.775461496957 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 25 10 0 123 36 0.671213642754 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 10 0 123 48 0.657357627725 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 9 3 0 [82, 82, 82, 82, 133]
+note_add 1 9 0 0 24 0.939922537979 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 3 9 0 0 32 0.919417513279 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 7 9 0 0 46 0.94323408296 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 4 9 0 3 40 0.698900010891 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 8 9 0 6 46 0.698856456031 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 9 9 0 9 46 0.73534413844 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 2 9 0 12 28 0.777449966123 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 5 9 0 15 36 0.745537315527 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 6 9 0 18 40 0.731967099614 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 10 9 0 18 46 0.659748039959 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 11 9 0 24 48 0.887567039913 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 12 9 0 27 48 0.67596583908 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 8 9 0 [82, 82, 82, 82, 133]
+note_add 31 8 0 0 24 0.925548542596 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 41 8 0 0 40 0.99515399493 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 51 8 0 3 42 0.656600534211 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 42 8 0 12 40 0.781608499687 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 52 8 0 18 42 0.746078356731 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 32 8 0 24 26 0.842788079016 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 38 8 0 24 30 0.858448377744 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 43 8 0 27 38 0.655557996923 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 33 8 0 36 24 0.84416548026 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 53 8 0 42 48 0.708755031747 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 54 8 0 45 46 0.694252886906 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 34 8 0 48 28 0.790745114826 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 44 8 0 51 38 0.693079205578 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 55 8 0 51 48 0.723114366376 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 56 8 0 57 42 0.74000144627 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 45 8 0 60 36 0.844357847996 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 46 8 0 63 36 0.670774638825 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 57 8 0 69 42 0.666807403745 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 35 8 0 72 24 0.802855117652 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 39 8 0 72 32 0.850137481504 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 58 8 0 75 42 0.714082247268 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 36 8 0 84 28 0.854088386031 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 47 8 0 84 38 0.816924020176 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 48 8 0 87 38 0.698932384487 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 59 8 0 87 42 0.674609289728 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 37 8 0 96 26 0.884421425859 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 40 8 0 96 32 0.816095303092 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 49 8 0 96 40 0.85609056018 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 50 8 0 99 36 0.739998407875 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+note_add 60 8 0 99 48 0.735836941454 0.5 1 5 134 0.005 0.095 0.0 0 1000 0 mini
+page_add 5 3 0 [82, 82, 82, 82, 133]
+note_add 13 5 0 0 28 0.948923051548 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 15 5 0 0 32 0.983674976389 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 16 5 0 3 38 0.676515455171 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 19 5 0 3 44 0.748902416777 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 20 5 0 9 42 0.721823750258 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 14 5 0 18 26 0.727501183971 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 21 5 0 18 42 0.692538780737 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 22 5 0 21 42 0.704638060569 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 17 5 0 27 38 0.699231033599 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 23 5 0 27 42 0.710291506584 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 18 5 0 33 38 0.740104587325 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+note_add 24 5 0 33 42 0.712509981931 0.5 1 5 137 0.005 0.095 0.0 0 1000 0 mini
+page_add 11 9 0 [82, 82, 82, 82, 133]
+note_add 1 11 0 0 28 0.940708810641 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 11 0 0 30 0.917125893398 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 11 0 3 38 0.659757355829 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 21 11 0 3 46 0.691197364433 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 11 0 15 36 0.728363093232 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 22 11 0 15 48 0.651730437628 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 13 11 0 21 36 0.748099491714 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 23 11 0 21 42 0.691142328317 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 11 0 24 26 0.799430971651 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 14 11 0 24 36 0.789827858454 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 15 11 0 27 40 0.717847096017 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 24 11 0 27 46 0.68775950814 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 3 11 0 36 28 0.847659428446 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 16 11 0 39 38 0.724596484561 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 17 11 0 42 38 0.672521332617 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 25 11 0 45 42 0.707153905275 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 11 0 48 26 0.768231729212 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 11 0 48 30 0.797498430547 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 18 11 0 51 40 0.662933204402 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 26 11 0 51 46 0.652875237261 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 11 0 60 28 0.870729034797 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 19 11 0 63 38 0.699990604686 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 27 11 0 63 46 0.744299692171 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 28 11 0 69 42 0.674719518782 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 11 0 72 28 0.793569160964 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 20 11 0 75 36 0.743411205808 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 11 0 84 30 0.76896495703 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 29 11 0 87 46 0.739799809332 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 11 0 96 28 0.854769659604 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 30 11 0 96 48 0.88403154664 0.5 1.0 5 134 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 12 2 0 [88, 76, 56, 82, 135]
+note_add 1 12 0 0 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 12 0 3 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 12 0 6 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 12 0 9 41 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 12 0 12 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 12 0 15 24 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 12 0 18 38 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 12 0 21 45 0.75 0.5 3.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 13 5 0 [88, 76, 56, 82, 135]
+note_add 1 13 0 0 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 13 0 1 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 13 0 2 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 5 13 0 3 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 6 13 0 4 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 39 13 0 7 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 40 13 0 8 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 41 13 0 9 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 42 13 0 10 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 43 13 0 11 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 13 0 12 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 7 13 0 13 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 8 13 0 14 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 9 13 0 15 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 10 13 0 16 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 34 13 0 19 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 35 13 0 20 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 36 13 0 21 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 37 13 0 22 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 38 13 0 23 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 11 13 0 24 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 12 13 0 25 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 13 13 0 26 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 14 13 0 27 48 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 29 13 0 31 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 30 13 0 32 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 31 13 0 33 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 32 13 0 34 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 33 13 0 35 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 15 13 0 36 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 16 13 0 37 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 17 13 0 38 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 18 13 0 39 24 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 24 13 0 43 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 25 13 0 44 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 26 13 0 45 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 27 13 0 46 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 28 13 0 47 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 19 13 0 55 35 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 20 13 0 56 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 21 13 0 57 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 22 13 0 58 36 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 23 13 0 59 34 0.75 0.5 1.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+page_add 14 3 0 [82, 82, 82, 82, 133]
+note_add 3 14 0 0 30 0.900689216372 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 4 14 0 0 38 0.92403208165 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 1 14 0 6 24 0.710809973008 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 7 14 0 6 44 0.680687612344 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 8 14 0 9 48 0.689412655788 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 9 14 0 15 44 0.664335685932 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 10 14 0 21 44 0.699249583758 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 2 14 0 24 26 0.826542425289 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 5 14 0 27 38 0.737997319594 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 11 14 0 27 42 0.671027963479 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 6 14 0 33 40 0.727866267806 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+note_add 12 14 0 33 48 0.674593053365 0.5 1.0 5 137 0.005 0.095 0.0 0.0 1000.0 1 mini
+page_add 15 7 0 [88, 77, 67, 85, 137]
+note_add 1 15 0 0 29 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 2 15 0 24 44 0.75 0.5 7.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 3 15 0 36 44 0.75 0.5 6.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+note_add 4 15 0 48 32 0.75 0.5 24.0 0 88 0.005 0.098 0.1 0.0 1000.0 1 edit
+block_add Drum False 236 203 False {'name': 'drum5kit', 'regularity': 0.17265378043653012, 'page': 5, 'volume': 0.5, 'beats': 3, 'seed': 0.61058227696419964, 'reverb': 0.0, 'id': 137}
+block_add Instrument False 437 137 False {'volume': 0.5, 'reverb': 0, 'name': 'duck', 'pan': 0.5, 'id': 30}
+block_add Loop False 567 137 True {'name': 'loop1', 'id': 15}
+block_add Instrument True 431 302 False {'volume': 0.5, 'reverb': 0, 'name': 'rhodes', 'pan': 0.5, 'id': 85}
+block_add Instrument False 443 445 False {'volume': 0.5, 'reverb': 0, 'name': 'ow', 'pan': 0.5, 'id': 63}
+block_add Loop False 550 445 True {'name': 'loop2', 'id': 13}
+block_add Loop False 638 445 True {'name': 'loop3', 'id': 12}
+block_add Drum False 233 354 False {'name': 'drum2kit', 'regularity': 0.32130953701001352, 'id': 134, 'volume': 0.5, 'beats': 9, 'reverb': 0.0, 'page': 8}
diff --git a/common/Resources/Images/TamTam.png b/common/Resources/Images/TamTam.png
new file mode 100644
index 0000000..1e1f6de
--- /dev/null
+++ b/common/Resources/Images/TamTam.png
Binary files differ
diff --git a/common/Resources/Images/acguit.png b/common/Resources/Images/acguit.png
new file mode 100644
index 0000000..ed0e1ff
--- /dev/null
+++ b/common/Resources/Images/acguit.png
Binary files differ
diff --git a/common/Resources/Images/acguitsel.png b/common/Resources/Images/acguitsel.png
new file mode 100644
index 0000000..cc692ef
--- /dev/null
+++ b/common/Resources/Images/acguitsel.png
Binary files differ
diff --git a/common/Resources/Images/alarm.png b/common/Resources/Images/alarm.png
new file mode 100755
index 0000000..817f23c
--- /dev/null
+++ b/common/Resources/Images/alarm.png
Binary files differ
diff --git a/common/Resources/Images/alarmsel.png b/common/Resources/Images/alarmsel.png
new file mode 100755
index 0000000..cbf2f79
--- /dev/null
+++ b/common/Resources/Images/alarmsel.png
Binary files differ
diff --git a/common/Resources/Images/all.png b/common/Resources/Images/all.png
new file mode 100644
index 0000000..ee3534b
--- /dev/null
+++ b/common/Resources/Images/all.png
Binary files differ
diff --git a/common/Resources/Images/allsel.png b/common/Resources/Images/allsel.png
new file mode 100644
index 0000000..98ff02b
--- /dev/null
+++ b/common/Resources/Images/allsel.png
Binary files differ
diff --git a/common/Resources/Images/animals.png b/common/Resources/Images/animals.png
new file mode 100644
index 0000000..95c802f
--- /dev/null
+++ b/common/Resources/Images/animals.png
Binary files differ
diff --git a/common/Resources/Images/animalssel.png b/common/Resources/Images/animalssel.png
new file mode 100644
index 0000000..f2369fb
--- /dev/null
+++ b/common/Resources/Images/animalssel.png
Binary files differ
diff --git a/common/Resources/Images/arrowEditDown.png b/common/Resources/Images/arrowEditDown.png
new file mode 100755
index 0000000..99888f7
--- /dev/null
+++ b/common/Resources/Images/arrowEditDown.png
Binary files differ
diff --git a/common/Resources/Images/arrowEditDownDown.png b/common/Resources/Images/arrowEditDownDown.png
new file mode 100755
index 0000000..20f783f
--- /dev/null
+++ b/common/Resources/Images/arrowEditDownDown.png
Binary files differ
diff --git a/common/Resources/Images/arrowEditDownOver.png b/common/Resources/Images/arrowEditDownOver.png
new file mode 100755
index 0000000..3fb3d28
--- /dev/null
+++ b/common/Resources/Images/arrowEditDownOver.png
Binary files differ
diff --git a/common/Resources/Images/arrowEditLeft.png b/common/Resources/Images/arrowEditLeft.png
new file mode 100644
index 0000000..2850e64
--- /dev/null
+++ b/common/Resources/Images/arrowEditLeft.png
Binary files differ
diff --git a/common/Resources/Images/arrowEditLeftDown.png b/common/Resources/Images/arrowEditLeftDown.png
new file mode 100755
index 0000000..49ccb5f
--- /dev/null
+++ b/common/Resources/Images/arrowEditLeftDown.png
Binary files differ
diff --git a/common/Resources/Images/arrowEditLeftOver.png b/common/Resources/Images/arrowEditLeftOver.png
new file mode 100755
index 0000000..8dcf71d
--- /dev/null
+++ b/common/Resources/Images/arrowEditLeftOver.png
Binary files differ
diff --git a/common/Resources/Images/arrowEditRight.png b/common/Resources/Images/arrowEditRight.png
new file mode 100644
index 0000000..4046205
--- /dev/null
+++ b/common/Resources/Images/arrowEditRight.png
Binary files differ
diff --git a/common/Resources/Images/arrowEditRightDown.png b/common/Resources/Images/arrowEditRightDown.png
new file mode 100755
index 0000000..b38037d
--- /dev/null
+++ b/common/Resources/Images/arrowEditRightDown.png
Binary files differ
diff --git a/common/Resources/Images/arrowEditRightOver.png b/common/Resources/Images/arrowEditRightOver.png
new file mode 100755
index 0000000..3f4502a
--- /dev/null
+++ b/common/Resources/Images/arrowEditRightOver.png
Binary files differ
diff --git a/common/Resources/Images/arrowEditUp.png b/common/Resources/Images/arrowEditUp.png
new file mode 100755
index 0000000..8ad3a2f
--- /dev/null
+++ b/common/Resources/Images/arrowEditUp.png
Binary files differ
diff --git a/common/Resources/Images/arrowEditUpDown.png b/common/Resources/Images/arrowEditUpDown.png
new file mode 100755
index 0000000..5ca1742
--- /dev/null
+++ b/common/Resources/Images/arrowEditUpDown.png
Binary files differ
diff --git a/common/Resources/Images/arrowEditUpOver.png b/common/Resources/Images/arrowEditUpOver.png
new file mode 100755
index 0000000..5b76e31
--- /dev/null
+++ b/common/Resources/Images/arrowEditUpOver.png
Binary files differ
diff --git a/common/Resources/Images/basse.png b/common/Resources/Images/basse.png
new file mode 100644
index 0000000..93d9a13
--- /dev/null
+++ b/common/Resources/Images/basse.png
Binary files differ
diff --git a/common/Resources/Images/bassesel.png b/common/Resources/Images/bassesel.png
new file mode 100644
index 0000000..ea8b65c
--- /dev/null
+++ b/common/Resources/Images/bassesel.png
Binary files differ
diff --git a/common/Resources/Images/beat1.png b/common/Resources/Images/beat1.png
new file mode 100644
index 0000000..104be63
--- /dev/null
+++ b/common/Resources/Images/beat1.png
Binary files differ
diff --git a/common/Resources/Images/beat10.png b/common/Resources/Images/beat10.png
new file mode 100644
index 0000000..f584b30
--- /dev/null
+++ b/common/Resources/Images/beat10.png
Binary files differ
diff --git a/common/Resources/Images/beat11.png b/common/Resources/Images/beat11.png
new file mode 100644
index 0000000..3b977ad
--- /dev/null
+++ b/common/Resources/Images/beat11.png
Binary files differ
diff --git a/common/Resources/Images/beat2.png b/common/Resources/Images/beat2.png
new file mode 100644
index 0000000..b3b19d3
--- /dev/null
+++ b/common/Resources/Images/beat2.png
Binary files differ
diff --git a/common/Resources/Images/beat3.png b/common/Resources/Images/beat3.png
new file mode 100644
index 0000000..4e5c73a
--- /dev/null
+++ b/common/Resources/Images/beat3.png
Binary files differ
diff --git a/common/Resources/Images/beat4.png b/common/Resources/Images/beat4.png
new file mode 100644
index 0000000..e3c3aea
--- /dev/null
+++ b/common/Resources/Images/beat4.png
Binary files differ
diff --git a/common/Resources/Images/beat5.png b/common/Resources/Images/beat5.png
new file mode 100644
index 0000000..54846dd
--- /dev/null
+++ b/common/Resources/Images/beat5.png
Binary files differ
diff --git a/common/Resources/Images/beat6.png b/common/Resources/Images/beat6.png
new file mode 100644
index 0000000..9f9664f
--- /dev/null
+++ b/common/Resources/Images/beat6.png
Binary files differ
diff --git a/common/Resources/Images/beat7.png b/common/Resources/Images/beat7.png
new file mode 100644
index 0000000..cec399d
--- /dev/null
+++ b/common/Resources/Images/beat7.png
Binary files differ
diff --git a/common/Resources/Images/beat8.png b/common/Resources/Images/beat8.png
new file mode 100644
index 0000000..7f4d7e5
--- /dev/null
+++ b/common/Resources/Images/beat8.png
Binary files differ
diff --git a/common/Resources/Images/beat9.png b/common/Resources/Images/beat9.png
new file mode 100644
index 0000000..1b18084
--- /dev/null
+++ b/common/Resources/Images/beat9.png
Binary files differ
diff --git a/common/Resources/Images/bird.png b/common/Resources/Images/bird.png
new file mode 100644
index 0000000..a0c0fb1
--- /dev/null
+++ b/common/Resources/Images/bird.png
Binary files differ
diff --git a/common/Resources/Images/birdsel.png b/common/Resources/Images/birdsel.png
new file mode 100644
index 0000000..60f75b8
--- /dev/null
+++ b/common/Resources/Images/birdsel.png
Binary files differ
diff --git a/common/Resources/Images/bottle.png b/common/Resources/Images/bottle.png
new file mode 100644
index 0000000..634fcca
--- /dev/null
+++ b/common/Resources/Images/bottle.png
Binary files differ
diff --git a/common/Resources/Images/bottlesel.png b/common/Resources/Images/bottlesel.png
new file mode 100644
index 0000000..f93d01b
--- /dev/null
+++ b/common/Resources/Images/bottlesel.png
Binary files differ
diff --git a/common/Resources/Images/bubbles.png b/common/Resources/Images/bubbles.png
new file mode 100755
index 0000000..ba52212
--- /dev/null
+++ b/common/Resources/Images/bubbles.png
Binary files differ
diff --git a/common/Resources/Images/bubblessel.png b/common/Resources/Images/bubblessel.png
new file mode 100755
index 0000000..6aea349
--- /dev/null
+++ b/common/Resources/Images/bubblessel.png
Binary files differ
diff --git a/common/Resources/Images/byke.png b/common/Resources/Images/byke.png
new file mode 100755
index 0000000..5b4796c
--- /dev/null
+++ b/common/Resources/Images/byke.png
Binary files differ
diff --git a/common/Resources/Images/bykesel.png b/common/Resources/Images/bykesel.png
new file mode 100755
index 0000000..a6b0943
--- /dev/null
+++ b/common/Resources/Images/bykesel.png
Binary files differ
diff --git a/common/Resources/Images/camera.png b/common/Resources/Images/camera.png
new file mode 100755
index 0000000..b5c460d
--- /dev/null
+++ b/common/Resources/Images/camera.png
Binary files differ
diff --git a/common/Resources/Images/camerasel.png b/common/Resources/Images/camerasel.png
new file mode 100755
index 0000000..feb84bc
--- /dev/null
+++ b/common/Resources/Images/camerasel.png
Binary files differ
diff --git a/common/Resources/Images/car.png b/common/Resources/Images/car.png
new file mode 100755
index 0000000..1f8ad8d
--- /dev/null
+++ b/common/Resources/Images/car.png
Binary files differ
diff --git a/common/Resources/Images/carsel.png b/common/Resources/Images/carsel.png
new file mode 100755
index 0000000..76287a7
--- /dev/null
+++ b/common/Resources/Images/carsel.png
Binary files differ
diff --git a/common/Resources/Images/cat.png b/common/Resources/Images/cat.png
new file mode 100644
index 0000000..28151c3
--- /dev/null
+++ b/common/Resources/Images/cat.png
Binary files differ
diff --git a/common/Resources/Images/catsel.png b/common/Resources/Images/catsel.png
new file mode 100644
index 0000000..2ca1472
--- /dev/null
+++ b/common/Resources/Images/catsel.png
Binary files differ
diff --git a/common/Resources/Images/cello.png b/common/Resources/Images/cello.png
new file mode 100755
index 0000000..750a0bc
--- /dev/null
+++ b/common/Resources/Images/cello.png
Binary files differ
diff --git a/common/Resources/Images/cellosel.png b/common/Resources/Images/cellosel.png
new file mode 100755
index 0000000..dc3ac53
--- /dev/null
+++ b/common/Resources/Images/cellosel.png
Binary files differ
diff --git a/common/Resources/Images/check.png b/common/Resources/Images/check.png
new file mode 100644
index 0000000..187546b
--- /dev/null
+++ b/common/Resources/Images/check.png
Binary files differ
diff --git a/common/Resources/Images/checkOff.svg b/common/Resources/Images/checkOff.svg
new file mode 100644
index 0000000..9357b87
--- /dev/null
+++ b/common/Resources/Images/checkOff.svg
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="22px" height="22px" viewBox="0 0 22 22" enable-background="new 0 0 22 22" xml:space="preserve">
+<rect x="1" y="1" fill="#FFFFFF" stroke="#000000" stroke-width="2" width="20" height="20"/>
+</svg>
diff --git a/common/Resources/Images/checkOn.svg b/common/Resources/Images/checkOn.svg
new file mode 100644
index 0000000..5b91ddf
--- /dev/null
+++ b/common/Resources/Images/checkOn.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14576) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="22px" height="22px" viewBox="0 0 22 22" enable-background="new 0 0 22 22" xml:space="preserve">
+<rect x="1" y="1" fill="#FFFFFF" stroke="#000000" stroke-width="2" width="20" height="20"/>
+<g>
+ <path d="M17.021,6.637c0.312,0,0.624,0.048,0.96,0.143c0.144,0.048,0.264,0.12,0.264,0.191c0,0.071-0.048,0.119-0.192,0.143
+ c-0.288,0.024-0.695,0.215-0.912,0.358c-1.68,1.002-6.192,4.701-9.264,7.947c-0.288,0.286-0.625,0.215-0.576,0.047
+ c0.168-0.501,0.312-2.911,0.096-4.009c-0.048-0.286-0.216-0.597-0.672-0.549c-0.144,0.024-0.288,0.024-0.288-0.072
+ c0-0.071,0.12-0.143,0.264-0.191c0.312-0.119,0.744-0.167,0.96-0.167c0.528,0,1.056,0.143,1.176,0.668
+ c0.192,0.788-0.024,2.171-1.008,4.033c2.472-3.604,4.896-6.3,6.528-7.469C15.028,7.234,16.156,6.637,17.021,6.637z"/>
+</g>
+</svg>
diff --git a/common/Resources/Images/chimes.png b/common/Resources/Images/chimes.png
new file mode 100755
index 0000000..5c0873a
--- /dev/null
+++ b/common/Resources/Images/chimes.png
Binary files differ
diff --git a/common/Resources/Images/chimessel.png b/common/Resources/Images/chimessel.png
new file mode 100755
index 0000000..a700720
--- /dev/null
+++ b/common/Resources/Images/chimessel.png
Binary files differ
diff --git a/common/Resources/Images/clang.png b/common/Resources/Images/clang.png
new file mode 100644
index 0000000..f6586fb
--- /dev/null
+++ b/common/Resources/Images/clang.png
Binary files differ
diff --git a/common/Resources/Images/clangsel.png b/common/Resources/Images/clangsel.png
new file mode 100644
index 0000000..9f5a289
--- /dev/null
+++ b/common/Resources/Images/clangsel.png
Binary files differ
diff --git a/common/Resources/Images/clarinette.png b/common/Resources/Images/clarinette.png
new file mode 100644
index 0000000..a3729df
--- /dev/null
+++ b/common/Resources/Images/clarinette.png
Binary files differ
diff --git a/common/Resources/Images/clarinettesel.png b/common/Resources/Images/clarinettesel.png
new file mode 100644
index 0000000..119ec6d
--- /dev/null
+++ b/common/Resources/Images/clarinettesel.png
Binary files differ
diff --git a/common/Resources/Images/cling.png b/common/Resources/Images/cling.png
new file mode 100644
index 0000000..ff35a7e
--- /dev/null
+++ b/common/Resources/Images/cling.png
Binary files differ
diff --git a/common/Resources/Images/clingsel.png b/common/Resources/Images/clingsel.png
new file mode 100644
index 0000000..0b69cd2
--- /dev/null
+++ b/common/Resources/Images/clingsel.png
Binary files differ
diff --git a/common/Resources/Images/complex1.png b/common/Resources/Images/complex1.png
new file mode 100644
index 0000000..5e9fd06
--- /dev/null
+++ b/common/Resources/Images/complex1.png
Binary files differ
diff --git a/common/Resources/Images/complex2.png b/common/Resources/Images/complex2.png
new file mode 100644
index 0000000..3a52d54
--- /dev/null
+++ b/common/Resources/Images/complex2.png
Binary files differ
diff --git a/common/Resources/Images/complex3.png b/common/Resources/Images/complex3.png
new file mode 100644
index 0000000..94d2c7e
--- /dev/null
+++ b/common/Resources/Images/complex3.png
Binary files differ
diff --git a/common/Resources/Images/complex4.png b/common/Resources/Images/complex4.png
new file mode 100644
index 0000000..65ccce0
--- /dev/null
+++ b/common/Resources/Images/complex4.png
Binary files differ
diff --git a/common/Resources/Images/complex5.png b/common/Resources/Images/complex5.png
new file mode 100644
index 0000000..598b14d
--- /dev/null
+++ b/common/Resources/Images/complex5.png
Binary files differ
diff --git a/common/Resources/Images/complex6.png b/common/Resources/Images/complex6.png
new file mode 100644
index 0000000..d8a030a
--- /dev/null
+++ b/common/Resources/Images/complex6.png
Binary files differ
diff --git a/common/Resources/Images/complex7.png b/common/Resources/Images/complex7.png
new file mode 100644
index 0000000..f3d50fb
--- /dev/null
+++ b/common/Resources/Images/complex7.png
Binary files differ
diff --git a/common/Resources/Images/complex8.png b/common/Resources/Images/complex8.png
new file mode 100644
index 0000000..5e9a0a4
--- /dev/null
+++ b/common/Resources/Images/complex8.png
Binary files differ
diff --git a/common/Resources/Images/concret.png b/common/Resources/Images/concret.png
new file mode 100644
index 0000000..038dbb4
--- /dev/null
+++ b/common/Resources/Images/concret.png
Binary files differ
diff --git a/common/Resources/Images/concretsel.png b/common/Resources/Images/concretsel.png
new file mode 100644
index 0000000..b78687c
--- /dev/null
+++ b/common/Resources/Images/concretsel.png
Binary files differ
diff --git a/common/Resources/Images/crash.png b/common/Resources/Images/crash.png
new file mode 100755
index 0000000..23db01f
--- /dev/null
+++ b/common/Resources/Images/crash.png
Binary files differ
diff --git a/common/Resources/Images/crashsel.png b/common/Resources/Images/crashsel.png
new file mode 100755
index 0000000..38dba22
--- /dev/null
+++ b/common/Resources/Images/crashsel.png
Binary files differ
diff --git a/common/Resources/Images/dice.png b/common/Resources/Images/dice.png
new file mode 100644
index 0000000..47441b7
--- /dev/null
+++ b/common/Resources/Images/dice.png
Binary files differ
diff --git a/common/Resources/Images/diceProp.png b/common/Resources/Images/diceProp.png
new file mode 100644
index 0000000..887a6fb
--- /dev/null
+++ b/common/Resources/Images/diceProp.png
Binary files differ
diff --git a/common/Resources/Images/dicePropSel.png b/common/Resources/Images/dicePropSel.png
new file mode 100644
index 0000000..13c5779
--- /dev/null
+++ b/common/Resources/Images/dicePropSel.png
Binary files differ
diff --git a/common/Resources/Images/diceblur.png b/common/Resources/Images/diceblur.png
new file mode 100644
index 0000000..f275422
--- /dev/null
+++ b/common/Resources/Images/diceblur.png
Binary files differ
diff --git a/common/Resources/Images/diceinst.png b/common/Resources/Images/diceinst.png
new file mode 100644
index 0000000..9fda10f
--- /dev/null
+++ b/common/Resources/Images/diceinst.png
Binary files differ
diff --git a/common/Resources/Images/diceinstsel.png b/common/Resources/Images/diceinstsel.png
new file mode 100644
index 0000000..782b100
--- /dev/null
+++ b/common/Resources/Images/diceinstsel.png
Binary files differ
diff --git a/common/Resources/Images/didjeridu.png b/common/Resources/Images/didjeridu.png
new file mode 100644
index 0000000..a14b863
--- /dev/null
+++ b/common/Resources/Images/didjeridu.png
Binary files differ
diff --git a/common/Resources/Images/didjeridusel.png b/common/Resources/Images/didjeridusel.png
new file mode 100644
index 0000000..a836b71
--- /dev/null
+++ b/common/Resources/Images/didjeridusel.png
Binary files differ
diff --git a/common/Resources/Images/dog.png b/common/Resources/Images/dog.png
new file mode 100644
index 0000000..942e5aa
--- /dev/null
+++ b/common/Resources/Images/dog.png
Binary files differ
diff --git a/common/Resources/Images/dogsel.png b/common/Resources/Images/dogsel.png
new file mode 100644
index 0000000..f5458a3
--- /dev/null
+++ b/common/Resources/Images/dogsel.png
Binary files differ
diff --git a/common/Resources/Images/door.png b/common/Resources/Images/door.png
new file mode 100644
index 0000000..15c95b2
--- /dev/null
+++ b/common/Resources/Images/door.png
Binary files differ
diff --git a/common/Resources/Images/doorsel.png b/common/Resources/Images/doorsel.png
new file mode 100644
index 0000000..a95f616
--- /dev/null
+++ b/common/Resources/Images/doorsel.png
Binary files differ
diff --git a/common/Resources/Images/dru0.png b/common/Resources/Images/dru0.png
new file mode 100755
index 0000000..eb8227c
--- /dev/null
+++ b/common/Resources/Images/dru0.png
Binary files differ
diff --git a/common/Resources/Images/dru1.png b/common/Resources/Images/dru1.png
new file mode 100755
index 0000000..e5c8698
--- /dev/null
+++ b/common/Resources/Images/dru1.png
Binary files differ
diff --git a/common/Resources/Images/dru2.png b/common/Resources/Images/dru2.png
new file mode 100755
index 0000000..7f5dba0
--- /dev/null
+++ b/common/Resources/Images/dru2.png
Binary files differ
diff --git a/common/Resources/Images/dru3.png b/common/Resources/Images/dru3.png
new file mode 100755
index 0000000..dcfd922
--- /dev/null
+++ b/common/Resources/Images/dru3.png
Binary files differ
diff --git a/common/Resources/Images/dru4.png b/common/Resources/Images/dru4.png
new file mode 100755
index 0000000..7718e36
--- /dev/null
+++ b/common/Resources/Images/dru4.png
Binary files differ
diff --git a/common/Resources/Images/drum1kit.png b/common/Resources/Images/drum1kit.png
new file mode 100644
index 0000000..e98ec33
--- /dev/null
+++ b/common/Resources/Images/drum1kit.png
Binary files differ
diff --git a/common/Resources/Images/drum1kitsel.png b/common/Resources/Images/drum1kitsel.png
new file mode 100644
index 0000000..aa9a1e0
--- /dev/null
+++ b/common/Resources/Images/drum1kitsel.png
Binary files differ
diff --git a/common/Resources/Images/drum1kitselgen.png b/common/Resources/Images/drum1kitselgen.png
new file mode 100644
index 0000000..f78a18e
--- /dev/null
+++ b/common/Resources/Images/drum1kitselgen.png
Binary files differ
diff --git a/common/Resources/Images/drum2kit.png b/common/Resources/Images/drum2kit.png
new file mode 100644
index 0000000..76d12d7
--- /dev/null
+++ b/common/Resources/Images/drum2kit.png
Binary files differ
diff --git a/common/Resources/Images/drum2kitsel.png b/common/Resources/Images/drum2kitsel.png
new file mode 100644
index 0000000..1101b8a
--- /dev/null
+++ b/common/Resources/Images/drum2kitsel.png
Binary files differ
diff --git a/common/Resources/Images/drum2kitselgen.png b/common/Resources/Images/drum2kitselgen.png
new file mode 100644
index 0000000..6027918
--- /dev/null
+++ b/common/Resources/Images/drum2kitselgen.png
Binary files differ
diff --git a/common/Resources/Images/drum3kit.png b/common/Resources/Images/drum3kit.png
new file mode 100644
index 0000000..38975a2
--- /dev/null
+++ b/common/Resources/Images/drum3kit.png
Binary files differ
diff --git a/common/Resources/Images/drum3kitsel.png b/common/Resources/Images/drum3kitsel.png
new file mode 100644
index 0000000..7200e89
--- /dev/null
+++ b/common/Resources/Images/drum3kitsel.png
Binary files differ
diff --git a/common/Resources/Images/drum3kitselgen.png b/common/Resources/Images/drum3kitselgen.png
new file mode 100644
index 0000000..ecfb61b
--- /dev/null
+++ b/common/Resources/Images/drum3kitselgen.png
Binary files differ
diff --git a/common/Resources/Images/drum4kit.png b/common/Resources/Images/drum4kit.png
new file mode 100644
index 0000000..a928080
--- /dev/null
+++ b/common/Resources/Images/drum4kit.png
Binary files differ
diff --git a/common/Resources/Images/drum4kitsel.png b/common/Resources/Images/drum4kitsel.png
new file mode 100644
index 0000000..8d012df
--- /dev/null
+++ b/common/Resources/Images/drum4kitsel.png
Binary files differ
diff --git a/common/Resources/Images/drum4kitselgen.png b/common/Resources/Images/drum4kitselgen.png
new file mode 100644
index 0000000..02a62c6
--- /dev/null
+++ b/common/Resources/Images/drum4kitselgen.png
Binary files differ
diff --git a/common/Resources/Images/drum5kit.png b/common/Resources/Images/drum5kit.png
new file mode 100644
index 0000000..6213770
--- /dev/null
+++ b/common/Resources/Images/drum5kit.png
Binary files differ
diff --git a/common/Resources/Images/drum5kitsel.png b/common/Resources/Images/drum5kitsel.png
new file mode 100644
index 0000000..eec29b5
--- /dev/null
+++ b/common/Resources/Images/drum5kitsel.png
Binary files differ
diff --git a/common/Resources/Images/drum5kitselgen.png b/common/Resources/Images/drum5kitselgen.png
new file mode 100644
index 0000000..2208d55
--- /dev/null
+++ b/common/Resources/Images/drum5kitselgen.png
Binary files differ
diff --git a/common/Resources/Images/duck.png b/common/Resources/Images/duck.png
new file mode 100644
index 0000000..9c75bd8
--- /dev/null
+++ b/common/Resources/Images/duck.png
Binary files differ
diff --git a/common/Resources/Images/duck2.png b/common/Resources/Images/duck2.png
new file mode 100644
index 0000000..4ef2f28
--- /dev/null
+++ b/common/Resources/Images/duck2.png
Binary files differ
diff --git a/common/Resources/Images/duck2sel.png b/common/Resources/Images/duck2sel.png
new file mode 100644
index 0000000..b3f5c5f
--- /dev/null
+++ b/common/Resources/Images/duck2sel.png
Binary files differ
diff --git a/common/Resources/Images/ducksel.png b/common/Resources/Images/ducksel.png
new file mode 100644
index 0000000..0bc3243
--- /dev/null
+++ b/common/Resources/Images/ducksel.png
Binary files differ
diff --git a/common/Resources/Images/editTam.png b/common/Resources/Images/editTam.png
new file mode 100644
index 0000000..b27e33e
--- /dev/null
+++ b/common/Resources/Images/editTam.png
Binary files differ
diff --git a/common/Resources/Images/editTamDown.png b/common/Resources/Images/editTamDown.png
new file mode 100644
index 0000000..b7ad8b3
--- /dev/null
+++ b/common/Resources/Images/editTamDown.png
Binary files differ
diff --git a/common/Resources/Images/editTamOver.png b/common/Resources/Images/editTamOver.png
new file mode 100644
index 0000000..233624d
--- /dev/null
+++ b/common/Resources/Images/editTamOver.png
Binary files differ
diff --git a/common/Resources/Images/electronic.png b/common/Resources/Images/electronic.png
new file mode 100644
index 0000000..37a7e6f
--- /dev/null
+++ b/common/Resources/Images/electronic.png
Binary files differ
diff --git a/common/Resources/Images/electronicsel.png b/common/Resources/Images/electronicsel.png
new file mode 100644
index 0000000..bd6fceb
--- /dev/null
+++ b/common/Resources/Images/electronicsel.png
Binary files differ
diff --git a/common/Resources/Images/flute.png b/common/Resources/Images/flute.png
new file mode 100644
index 0000000..43e128b
--- /dev/null
+++ b/common/Resources/Images/flute.png
Binary files differ
diff --git a/common/Resources/Images/flutesel.png b/common/Resources/Images/flutesel.png
new file mode 100644
index 0000000..9b72cf7
--- /dev/null
+++ b/common/Resources/Images/flutesel.png
Binary files differ
diff --git a/common/Resources/Images/gam.png b/common/Resources/Images/gam.png
new file mode 100644
index 0000000..02f8719
--- /dev/null
+++ b/common/Resources/Images/gam.png
Binary files differ
diff --git a/common/Resources/Images/gamsel.png b/common/Resources/Images/gamsel.png
new file mode 100644
index 0000000..ac6594f
--- /dev/null
+++ b/common/Resources/Images/gamsel.png
Binary files differ
diff --git a/common/Resources/Images/generic.png b/common/Resources/Images/generic.png
new file mode 100755
index 0000000..c42119b
--- /dev/null
+++ b/common/Resources/Images/generic.png
Binary files differ
diff --git a/common/Resources/Images/genericsel.png b/common/Resources/Images/genericsel.png
new file mode 100755
index 0000000..2cbdb81
--- /dev/null
+++ b/common/Resources/Images/genericsel.png
Binary files differ
diff --git a/common/Resources/Images/guit.png b/common/Resources/Images/guit.png
new file mode 100644
index 0000000..0c2f667
--- /dev/null
+++ b/common/Resources/Images/guit.png
Binary files differ
diff --git a/common/Resources/Images/guit2.png b/common/Resources/Images/guit2.png
new file mode 100755
index 0000000..183d754
--- /dev/null
+++ b/common/Resources/Images/guit2.png
Binary files differ
diff --git a/common/Resources/Images/guit2sel.png b/common/Resources/Images/guit2sel.png
new file mode 100755
index 0000000..60641bd
--- /dev/null
+++ b/common/Resources/Images/guit2sel.png
Binary files differ
diff --git a/common/Resources/Images/guitsel.png b/common/Resources/Images/guitsel.png
new file mode 100644
index 0000000..890fcb7
--- /dev/null
+++ b/common/Resources/Images/guitsel.png
Binary files differ
diff --git a/common/Resources/Images/harmonica.png b/common/Resources/Images/harmonica.png
new file mode 100644
index 0000000..d8dd849
--- /dev/null
+++ b/common/Resources/Images/harmonica.png
Binary files differ
diff --git a/common/Resources/Images/harmonicasel.png b/common/Resources/Images/harmonicasel.png
new file mode 100644
index 0000000..0814bd9
--- /dev/null
+++ b/common/Resources/Images/harmonicasel.png
Binary files differ
diff --git a/common/Resources/Images/harmonium.png b/common/Resources/Images/harmonium.png
new file mode 100644
index 0000000..3d4a605
--- /dev/null
+++ b/common/Resources/Images/harmonium.png
Binary files differ
diff --git a/common/Resources/Images/harmoniumsel.png b/common/Resources/Images/harmoniumsel.png
new file mode 100644
index 0000000..80eb2c8
--- /dev/null
+++ b/common/Resources/Images/harmoniumsel.png
Binary files differ
diff --git a/common/Resources/Images/helpShow1.jpg b/common/Resources/Images/helpShow1.jpg
new file mode 100755
index 0000000..885db27
--- /dev/null
+++ b/common/Resources/Images/helpShow1.jpg
Binary files differ
diff --git a/common/Resources/Images/helpShow2.jpg b/common/Resources/Images/helpShow2.jpg
new file mode 100755
index 0000000..009e58e
--- /dev/null
+++ b/common/Resources/Images/helpShow2.jpg
Binary files differ
diff --git a/common/Resources/Images/helpShow3.jpg b/common/Resources/Images/helpShow3.jpg
new file mode 100755
index 0000000..b3858aa
--- /dev/null
+++ b/common/Resources/Images/helpShow3.jpg
Binary files differ
diff --git a/common/Resources/Images/helpShow4.jpg b/common/Resources/Images/helpShow4.jpg
new file mode 100755
index 0000000..f5ef420
--- /dev/null
+++ b/common/Resources/Images/helpShow4.jpg
Binary files differ
diff --git a/common/Resources/Images/helpShow5.jpg b/common/Resources/Images/helpShow5.jpg
new file mode 100755
index 0000000..f7d47d6
--- /dev/null
+++ b/common/Resources/Images/helpShow5.jpg
Binary files differ
diff --git a/common/Resources/Images/helpShow6.jpg b/common/Resources/Images/helpShow6.jpg
new file mode 100755
index 0000000..8b548e3
--- /dev/null
+++ b/common/Resources/Images/helpShow6.jpg
Binary files differ
diff --git a/common/Resources/Images/helpShow7.jpg b/common/Resources/Images/helpShow7.jpg
new file mode 100755
index 0000000..58f6f1a
--- /dev/null
+++ b/common/Resources/Images/helpShow7.jpg
Binary files differ
diff --git a/common/Resources/Images/helpShow8.jpg b/common/Resources/Images/helpShow8.jpg
new file mode 100755
index 0000000..c135fa8
--- /dev/null
+++ b/common/Resources/Images/helpShow8.jpg
Binary files differ
diff --git a/common/Resources/Images/helpShow9.jpg b/common/Resources/Images/helpShow9.jpg
new file mode 100755
index 0000000..6a1e01a
--- /dev/null
+++ b/common/Resources/Images/helpShow9.jpg
Binary files differ
diff --git a/common/Resources/Images/helpTam.png b/common/Resources/Images/helpTam.png
new file mode 100644
index 0000000..b7ad8b3
--- /dev/null
+++ b/common/Resources/Images/helpTam.png
Binary files differ
diff --git a/common/Resources/Images/helpTamDown.png b/common/Resources/Images/helpTamDown.png
new file mode 100644
index 0000000..b27e33e
--- /dev/null
+++ b/common/Resources/Images/helpTamDown.png
Binary files differ
diff --git a/common/Resources/Images/helpTamOver.png b/common/Resources/Images/helpTamOver.png
new file mode 100644
index 0000000..233624d
--- /dev/null
+++ b/common/Resources/Images/helpTamOver.png
Binary files differ
diff --git a/common/Resources/Images/hit.png b/common/Resources/Images/hit.png
new file mode 100644
index 0000000..d81489e
--- /dev/null
+++ b/common/Resources/Images/hit.png
Binary files differ
diff --git a/common/Resources/Images/hitSelected.png b/common/Resources/Images/hitSelected.png
new file mode 100644
index 0000000..20473b8
--- /dev/null
+++ b/common/Resources/Images/hitSelected.png
Binary files differ
diff --git a/common/Resources/Images/horse.png b/common/Resources/Images/horse.png
new file mode 100644
index 0000000..2c4c528
--- /dev/null
+++ b/common/Resources/Images/horse.png
Binary files differ
diff --git a/common/Resources/Images/horsesel.png b/common/Resources/Images/horsesel.png
new file mode 100644
index 0000000..c599ebe
--- /dev/null
+++ b/common/Resources/Images/horsesel.png
Binary files differ
diff --git a/common/Resources/Images/instr0.png b/common/Resources/Images/instr0.png
new file mode 100755
index 0000000..8e11498
--- /dev/null
+++ b/common/Resources/Images/instr0.png
Binary files differ
diff --git a/common/Resources/Images/instr1.png b/common/Resources/Images/instr1.png
new file mode 100755
index 0000000..548870d
--- /dev/null
+++ b/common/Resources/Images/instr1.png
Binary files differ
diff --git a/common/Resources/Images/instr2.png b/common/Resources/Images/instr2.png
new file mode 100755
index 0000000..ca720b3
--- /dev/null
+++ b/common/Resources/Images/instr2.png
Binary files differ
diff --git a/common/Resources/Images/instr3.png b/common/Resources/Images/instr3.png
new file mode 100755
index 0000000..8c6dc63
--- /dev/null
+++ b/common/Resources/Images/instr3.png
Binary files differ
diff --git a/common/Resources/Images/instr4.png b/common/Resources/Images/instr4.png
new file mode 100755
index 0000000..05e16ec
--- /dev/null
+++ b/common/Resources/Images/instr4.png
Binary files differ
diff --git a/common/Resources/Images/jam-blockMask.png b/common/Resources/Images/jam-blockMask.png
new file mode 100644
index 0000000..dc3911f
--- /dev/null
+++ b/common/Resources/Images/jam-blockMask.png
Binary files differ
diff --git a/common/Resources/Images/kalimba.png b/common/Resources/Images/kalimba.png
new file mode 100644
index 0000000..b763869
--- /dev/null
+++ b/common/Resources/Images/kalimba.png
Binary files differ
diff --git a/common/Resources/Images/kalimbasel.png b/common/Resources/Images/kalimbasel.png
new file mode 100644
index 0000000..3e55881
--- /dev/null
+++ b/common/Resources/Images/kalimbasel.png
Binary files differ
diff --git a/common/Resources/Images/keyboard.png b/common/Resources/Images/keyboard.png
new file mode 100644
index 0000000..db31de3
--- /dev/null
+++ b/common/Resources/Images/keyboard.png
Binary files differ
diff --git a/common/Resources/Images/keyboardsel.png b/common/Resources/Images/keyboardsel.png
new file mode 100644
index 0000000..c665ef1
--- /dev/null
+++ b/common/Resources/Images/keyboardsel.png
Binary files differ
diff --git a/common/Resources/Images/koto.png b/common/Resources/Images/koto.png
new file mode 100644
index 0000000..716747d
--- /dev/null
+++ b/common/Resources/Images/koto.png
Binary files differ
diff --git a/common/Resources/Images/kotosel.png b/common/Resources/Images/kotosel.png
new file mode 100644
index 0000000..a560ea7
--- /dev/null
+++ b/common/Resources/Images/kotosel.png
Binary files differ
diff --git a/common/Resources/Images/laugh.png b/common/Resources/Images/laugh.png
new file mode 100644
index 0000000..493711e
--- /dev/null
+++ b/common/Resources/Images/laugh.png
Binary files differ
diff --git a/common/Resources/Images/laughsel.png b/common/Resources/Images/laughsel.png
new file mode 100644
index 0000000..28a1980
--- /dev/null
+++ b/common/Resources/Images/laughsel.png
Binary files differ
diff --git a/common/Resources/Images/mando.png b/common/Resources/Images/mando.png
new file mode 100644
index 0000000..d97a2e1
--- /dev/null
+++ b/common/Resources/Images/mando.png
Binary files differ
diff --git a/common/Resources/Images/mandosel.png b/common/Resources/Images/mandosel.png
new file mode 100644
index 0000000..d8d5ad6
--- /dev/null
+++ b/common/Resources/Images/mandosel.png
Binary files differ
diff --git a/common/Resources/Images/marimba.png b/common/Resources/Images/marimba.png
new file mode 100644
index 0000000..f5eb4ac
--- /dev/null
+++ b/common/Resources/Images/marimba.png
Binary files differ
diff --git a/common/Resources/Images/marimbasel.png b/common/Resources/Images/marimbasel.png
new file mode 100644
index 0000000..3231271
--- /dev/null
+++ b/common/Resources/Images/marimbasel.png
Binary files differ
diff --git a/common/Resources/Images/marquis.png b/common/Resources/Images/marquis.png
new file mode 100644
index 0000000..e14917a
--- /dev/null
+++ b/common/Resources/Images/marquis.png
Binary files differ
diff --git a/common/Resources/Images/mic1.png b/common/Resources/Images/mic1.png
new file mode 100644
index 0000000..c6c991b
--- /dev/null
+++ b/common/Resources/Images/mic1.png
Binary files differ
diff --git a/common/Resources/Images/mic1sel.png b/common/Resources/Images/mic1sel.png
new file mode 100644
index 0000000..577ffcf
--- /dev/null
+++ b/common/Resources/Images/mic1sel.png
Binary files differ
diff --git a/common/Resources/Images/mic2.png b/common/Resources/Images/mic2.png
new file mode 100644
index 0000000..c827229
--- /dev/null
+++ b/common/Resources/Images/mic2.png
Binary files differ
diff --git a/common/Resources/Images/mic2sel.png b/common/Resources/Images/mic2sel.png
new file mode 100644
index 0000000..4f2b800
--- /dev/null
+++ b/common/Resources/Images/mic2sel.png
Binary files differ
diff --git a/common/Resources/Images/mic3.png b/common/Resources/Images/mic3.png
new file mode 100644
index 0000000..a3cb9c2
--- /dev/null
+++ b/common/Resources/Images/mic3.png
Binary files differ
diff --git a/common/Resources/Images/mic3sel.png b/common/Resources/Images/mic3sel.png
new file mode 100644
index 0000000..82fcbf9
--- /dev/null
+++ b/common/Resources/Images/mic3sel.png
Binary files differ
diff --git a/common/Resources/Images/mic4.png b/common/Resources/Images/mic4.png
new file mode 100644
index 0000000..2109c6d
--- /dev/null
+++ b/common/Resources/Images/mic4.png
Binary files differ
diff --git a/common/Resources/Images/mic4sel.png b/common/Resources/Images/mic4sel.png
new file mode 100644
index 0000000..4d63e90
--- /dev/null
+++ b/common/Resources/Images/mic4sel.png
Binary files differ
diff --git a/common/Resources/Images/miniTam.png b/common/Resources/Images/miniTam.png
new file mode 100644
index 0000000..0fc0fc3
--- /dev/null
+++ b/common/Resources/Images/miniTam.png
Binary files differ
diff --git a/common/Resources/Images/miniTamDown.png b/common/Resources/Images/miniTamDown.png
new file mode 100644
index 0000000..ea6395f
--- /dev/null
+++ b/common/Resources/Images/miniTamDown.png
Binary files differ
diff --git a/common/Resources/Images/miniTamOver.png b/common/Resources/Images/miniTamOver.png
new file mode 100644
index 0000000..a9d1478
--- /dev/null
+++ b/common/Resources/Images/miniTamOver.png
Binary files differ
diff --git a/common/Resources/Images/miniplay.png b/common/Resources/Images/miniplay.png
new file mode 100644
index 0000000..674303b
--- /dev/null
+++ b/common/Resources/Images/miniplay.png
Binary files differ
diff --git a/common/Resources/Images/mysounds.png b/common/Resources/Images/mysounds.png
new file mode 100644
index 0000000..88791b6
--- /dev/null
+++ b/common/Resources/Images/mysounds.png
Binary files differ
diff --git a/common/Resources/Images/mysoundssel.png b/common/Resources/Images/mysoundssel.png
new file mode 100644
index 0000000..8aa802c
--- /dev/null
+++ b/common/Resources/Images/mysoundssel.png
Binary files differ
diff --git a/common/Resources/Images/note.png b/common/Resources/Images/note.png
new file mode 100644
index 0000000..98731c0
--- /dev/null
+++ b/common/Resources/Images/note.png
Binary files differ
diff --git a/common/Resources/Images/noteSelected.png b/common/Resources/Images/noteSelected.png
new file mode 100644
index 0000000..b887bb9
--- /dev/null
+++ b/common/Resources/Images/noteSelected.png
Binary files differ
diff --git a/common/Resources/Images/ocarina.png b/common/Resources/Images/ocarina.png
new file mode 100644
index 0000000..3c8f794
--- /dev/null
+++ b/common/Resources/Images/ocarina.png
Binary files differ
diff --git a/common/Resources/Images/ocarinasel.png b/common/Resources/Images/ocarinasel.png
new file mode 100644
index 0000000..00d519b
--- /dev/null
+++ b/common/Resources/Images/ocarinasel.png
Binary files differ
diff --git a/common/Resources/Images/ounk.png b/common/Resources/Images/ounk.png
new file mode 100644
index 0000000..4949262
--- /dev/null
+++ b/common/Resources/Images/ounk.png
Binary files differ
diff --git a/common/Resources/Images/ounksel.png b/common/Resources/Images/ounksel.png
new file mode 100644
index 0000000..f70aea7
--- /dev/null
+++ b/common/Resources/Images/ounksel.png
Binary files differ
diff --git a/common/Resources/Images/ow.png b/common/Resources/Images/ow.png
new file mode 100644
index 0000000..0d8d57d
--- /dev/null
+++ b/common/Resources/Images/ow.png
Binary files differ
diff --git a/common/Resources/Images/owsel.png b/common/Resources/Images/owsel.png
new file mode 100644
index 0000000..dd5e814
--- /dev/null
+++ b/common/Resources/Images/owsel.png
Binary files differ
diff --git a/common/Resources/Images/pageThumbnailBG.png b/common/Resources/Images/pageThumbnailBG.png
new file mode 100644
index 0000000..2c11493
--- /dev/null
+++ b/common/Resources/Images/pageThumbnailBG.png
Binary files differ
diff --git a/common/Resources/Images/pageThumbnailBG0.png b/common/Resources/Images/pageThumbnailBG0.png
new file mode 100644
index 0000000..db2c684
--- /dev/null
+++ b/common/Resources/Images/pageThumbnailBG0.png
Binary files differ
diff --git a/common/Resources/Images/pageThumbnailBG1.png b/common/Resources/Images/pageThumbnailBG1.png
new file mode 100644
index 0000000..f0c14ce
--- /dev/null
+++ b/common/Resources/Images/pageThumbnailBG1.png
Binary files differ
diff --git a/common/Resources/Images/pageThumbnailBG2.png b/common/Resources/Images/pageThumbnailBG2.png
new file mode 100644
index 0000000..4969241
--- /dev/null
+++ b/common/Resources/Images/pageThumbnailBG2.png
Binary files differ
diff --git a/common/Resources/Images/pageThumbnailBG3.png b/common/Resources/Images/pageThumbnailBG3.png
new file mode 100644
index 0000000..839b741
--- /dev/null
+++ b/common/Resources/Images/pageThumbnailBG3.png
Binary files differ
diff --git a/common/Resources/Images/pageThumbnailBut0.png b/common/Resources/Images/pageThumbnailBut0.png
new file mode 100755
index 0000000..e70e75c
--- /dev/null
+++ b/common/Resources/Images/pageThumbnailBut0.png
Binary files differ
diff --git a/common/Resources/Images/pageThumbnailBut0Down.png b/common/Resources/Images/pageThumbnailBut0Down.png
new file mode 100755
index 0000000..0266d10
--- /dev/null
+++ b/common/Resources/Images/pageThumbnailBut0Down.png
Binary files differ
diff --git a/common/Resources/Images/pageThumbnailBut1.png b/common/Resources/Images/pageThumbnailBut1.png
new file mode 100755
index 0000000..e74600c
--- /dev/null
+++ b/common/Resources/Images/pageThumbnailBut1.png
Binary files differ
diff --git a/common/Resources/Images/pageThumbnailBut1Down.png b/common/Resources/Images/pageThumbnailBut1Down.png
new file mode 100755
index 0000000..cfa3f69
--- /dev/null
+++ b/common/Resources/Images/pageThumbnailBut1Down.png
Binary files differ
diff --git a/common/Resources/Images/pageThumbnailBut2.png b/common/Resources/Images/pageThumbnailBut2.png
new file mode 100755
index 0000000..7f16f50
--- /dev/null
+++ b/common/Resources/Images/pageThumbnailBut2.png
Binary files differ
diff --git a/common/Resources/Images/pageThumbnailBut2Down.png b/common/Resources/Images/pageThumbnailBut2Down.png
new file mode 100755
index 0000000..9e7d79a
--- /dev/null
+++ b/common/Resources/Images/pageThumbnailBut2Down.png
Binary files differ
diff --git a/common/Resources/Images/pageThumbnailBut3.png b/common/Resources/Images/pageThumbnailBut3.png
new file mode 100755
index 0000000..8f7be4d
--- /dev/null
+++ b/common/Resources/Images/pageThumbnailBut3.png
Binary files differ
diff --git a/common/Resources/Images/pageThumbnailBut3Down.png b/common/Resources/Images/pageThumbnailBut3Down.png
new file mode 100755
index 0000000..90b6b92
--- /dev/null
+++ b/common/Resources/Images/pageThumbnailBut3Down.png
Binary files differ
diff --git a/common/Resources/Images/pageThumbnailMask.png b/common/Resources/Images/pageThumbnailMask.png
new file mode 100644
index 0000000..2a1d416
--- /dev/null
+++ b/common/Resources/Images/pageThumbnailMask.png
Binary files differ
diff --git a/common/Resources/Images/people.png b/common/Resources/Images/people.png
new file mode 100644
index 0000000..3bc11b7
--- /dev/null
+++ b/common/Resources/Images/people.png
Binary files differ
diff --git a/common/Resources/Images/peoplesel.png b/common/Resources/Images/peoplesel.png
new file mode 100644
index 0000000..0893c2e
--- /dev/null
+++ b/common/Resources/Images/peoplesel.png
Binary files differ
diff --git a/common/Resources/Images/percussions.png b/common/Resources/Images/percussions.png
new file mode 100644
index 0000000..e39e3ef
--- /dev/null
+++ b/common/Resources/Images/percussions.png
Binary files differ
diff --git a/common/Resources/Images/percussionssel.png b/common/Resources/Images/percussionssel.png
new file mode 100644
index 0000000..9d8fadd
--- /dev/null
+++ b/common/Resources/Images/percussionssel.png
Binary files differ
diff --git a/common/Resources/Images/piano.png b/common/Resources/Images/piano.png
new file mode 100644
index 0000000..dbd8e21
--- /dev/null
+++ b/common/Resources/Images/piano.png
Binary files differ
diff --git a/common/Resources/Images/pianosel.png b/common/Resources/Images/pianosel.png
new file mode 100644
index 0000000..9c1923a
--- /dev/null
+++ b/common/Resources/Images/pianosel.png
Binary files differ
diff --git a/common/Resources/Images/plane.png b/common/Resources/Images/plane.png
new file mode 100755
index 0000000..ccb8607
--- /dev/null
+++ b/common/Resources/Images/plane.png
Binary files differ
diff --git a/common/Resources/Images/planesel.png b/common/Resources/Images/planesel.png
new file mode 100755
index 0000000..1120b67
--- /dev/null
+++ b/common/Resources/Images/planesel.png
Binary files differ
diff --git a/common/Resources/Images/reverb0.png b/common/Resources/Images/reverb0.png
new file mode 100644
index 0000000..234bef6
--- /dev/null
+++ b/common/Resources/Images/reverb0.png
Binary files differ
diff --git a/common/Resources/Images/reverb1.png b/common/Resources/Images/reverb1.png
new file mode 100644
index 0000000..d05da05
--- /dev/null
+++ b/common/Resources/Images/reverb1.png
Binary files differ
diff --git a/common/Resources/Images/reverb2.png b/common/Resources/Images/reverb2.png
new file mode 100644
index 0000000..91942d5
--- /dev/null
+++ b/common/Resources/Images/reverb2.png
Binary files differ
diff --git a/common/Resources/Images/reverb3.png b/common/Resources/Images/reverb3.png
new file mode 100644
index 0000000..f503f7d
--- /dev/null
+++ b/common/Resources/Images/reverb3.png
Binary files differ
diff --git a/common/Resources/Images/reverb4.png b/common/Resources/Images/reverb4.png
new file mode 100644
index 0000000..1588275
--- /dev/null
+++ b/common/Resources/Images/reverb4.png
Binary files differ
diff --git a/common/Resources/Images/reverb5.png b/common/Resources/Images/reverb5.png
new file mode 100644
index 0000000..a67d360
--- /dev/null
+++ b/common/Resources/Images/reverb5.png
Binary files differ
diff --git a/common/Resources/Images/rhodes.png b/common/Resources/Images/rhodes.png
new file mode 100644
index 0000000..658991d
--- /dev/null
+++ b/common/Resources/Images/rhodes.png
Binary files differ
diff --git a/common/Resources/Images/rhodessel.png b/common/Resources/Images/rhodessel.png
new file mode 100644
index 0000000..95a920f
--- /dev/null
+++ b/common/Resources/Images/rhodessel.png
Binary files differ
diff --git a/common/Resources/Images/sampleBG.png b/common/Resources/Images/sampleBG.png
new file mode 100644
index 0000000..359244e
--- /dev/null
+++ b/common/Resources/Images/sampleBG.png
Binary files differ
diff --git a/common/Resources/Images/sampleNoteMask.png b/common/Resources/Images/sampleNoteMask.png
new file mode 100644
index 0000000..cc9448f
--- /dev/null
+++ b/common/Resources/Images/sampleNoteMask.png
Binary files differ
diff --git a/common/Resources/Images/saxo.png b/common/Resources/Images/saxo.png
new file mode 100644
index 0000000..cadf6fe
--- /dev/null
+++ b/common/Resources/Images/saxo.png
Binary files differ
diff --git a/common/Resources/Images/saxosel.png b/common/Resources/Images/saxosel.png
new file mode 100644
index 0000000..838d552
--- /dev/null
+++ b/common/Resources/Images/saxosel.png
Binary files differ
diff --git a/common/Resources/Images/scrollBar.png b/common/Resources/Images/scrollBar.png
new file mode 100644
index 0000000..b8fb3cb
--- /dev/null
+++ b/common/Resources/Images/scrollBar.png
Binary files differ
diff --git a/common/Resources/Images/sheep.png b/common/Resources/Images/sheep.png
new file mode 100644
index 0000000..3c46699
--- /dev/null
+++ b/common/Resources/Images/sheep.png
Binary files differ
diff --git a/common/Resources/Images/sheepsel.png b/common/Resources/Images/sheepsel.png
new file mode 100644
index 0000000..42548a0
--- /dev/null
+++ b/common/Resources/Images/sheepsel.png
Binary files differ
diff --git a/common/Resources/Images/shenai.png b/common/Resources/Images/shenai.png
new file mode 100644
index 0000000..99eb91d
--- /dev/null
+++ b/common/Resources/Images/shenai.png
Binary files differ
diff --git a/common/Resources/Images/shenaisel.png b/common/Resources/Images/shenaisel.png
new file mode 100644
index 0000000..bde3c4f
--- /dev/null
+++ b/common/Resources/Images/shenaisel.png
Binary files differ
diff --git a/common/Resources/Images/sitar.png b/common/Resources/Images/sitar.png
new file mode 100644
index 0000000..0a61628
--- /dev/null
+++ b/common/Resources/Images/sitar.png
Binary files differ
diff --git a/common/Resources/Images/sitarsel.png b/common/Resources/Images/sitarsel.png
new file mode 100644
index 0000000..512726e
--- /dev/null
+++ b/common/Resources/Images/sitarsel.png
Binary files differ
diff --git a/common/Resources/Images/slap.png b/common/Resources/Images/slap.png
new file mode 100755
index 0000000..cafbe5e
--- /dev/null
+++ b/common/Resources/Images/slap.png
Binary files differ
diff --git a/common/Resources/Images/slapsel.png b/common/Resources/Images/slapsel.png
new file mode 100755
index 0000000..85bd6b4
--- /dev/null
+++ b/common/Resources/Images/slapsel.png
Binary files differ
diff --git a/common/Resources/Images/sliderDrum.png b/common/Resources/Images/sliderDrum.png
new file mode 100644
index 0000000..dd65e6d
--- /dev/null
+++ b/common/Resources/Images/sliderDrum.png
Binary files differ
diff --git a/common/Resources/Images/sliderEditTempo.png b/common/Resources/Images/sliderEditTempo.png
new file mode 100644
index 0000000..0ec252d
--- /dev/null
+++ b/common/Resources/Images/sliderEditTempo.png
Binary files differ
diff --git a/common/Resources/Images/sliderEditVolume.png b/common/Resources/Images/sliderEditVolume.png
new file mode 100644
index 0000000..5f4daca
--- /dev/null
+++ b/common/Resources/Images/sliderEditVolume.png
Binary files differ
diff --git a/common/Resources/Images/sliderInst1.png b/common/Resources/Images/sliderInst1.png
new file mode 100644
index 0000000..fc48d15
--- /dev/null
+++ b/common/Resources/Images/sliderInst1.png
Binary files differ
diff --git a/common/Resources/Images/sliderInst2.png b/common/Resources/Images/sliderInst2.png
new file mode 100644
index 0000000..4f256eb
--- /dev/null
+++ b/common/Resources/Images/sliderInst2.png
Binary files differ
diff --git a/common/Resources/Images/sliderInst3.png b/common/Resources/Images/sliderInst3.png
new file mode 100644
index 0000000..e86b71e
--- /dev/null
+++ b/common/Resources/Images/sliderInst3.png
Binary files differ
diff --git a/common/Resources/Images/sliderInst4.png b/common/Resources/Images/sliderInst4.png
new file mode 100644
index 0000000..e812bd4
--- /dev/null
+++ b/common/Resources/Images/sliderInst4.png
Binary files differ
diff --git a/common/Resources/Images/sliderbutbleu.png b/common/Resources/Images/sliderbutbleu.png
new file mode 100644
index 0000000..6c34a77
--- /dev/null
+++ b/common/Resources/Images/sliderbutbleu.png
Binary files differ
diff --git a/common/Resources/Images/sliderbutjaune.png b/common/Resources/Images/sliderbutjaune.png
new file mode 100644
index 0000000..6f0fe9d
--- /dev/null
+++ b/common/Resources/Images/sliderbutjaune.png
Binary files differ
diff --git a/common/Resources/Images/sliderbutred.png b/common/Resources/Images/sliderbutred.png
new file mode 100644
index 0000000..2e44538
--- /dev/null
+++ b/common/Resources/Images/sliderbutred.png
Binary files differ
diff --git a/common/Resources/Images/sliderbutvert.png b/common/Resources/Images/sliderbutvert.png
new file mode 100644
index 0000000..bbe53e8
--- /dev/null
+++ b/common/Resources/Images/sliderbutvert.png
Binary files differ
diff --git a/common/Resources/Images/sliderbutviolet.png b/common/Resources/Images/sliderbutviolet.png
new file mode 100644
index 0000000..a2b2a54
--- /dev/null
+++ b/common/Resources/Images/sliderbutviolet.png
Binary files differ
diff --git a/common/Resources/Images/sliderlong.png b/common/Resources/Images/sliderlong.png
new file mode 100644
index 0000000..f6e05e4
--- /dev/null
+++ b/common/Resources/Images/sliderlong.png
Binary files differ
diff --git a/common/Resources/Images/slidershort.png b/common/Resources/Images/slidershort.png
new file mode 100644
index 0000000..aff8bb1
--- /dev/null
+++ b/common/Resources/Images/slidershort.png
Binary files differ
diff --git a/common/Resources/Images/stop.png b/common/Resources/Images/stop.png
new file mode 100644
index 0000000..cd55af1
--- /dev/null
+++ b/common/Resources/Images/stop.png
Binary files differ
diff --git a/common/Resources/Images/strings.png b/common/Resources/Images/strings.png
new file mode 100644
index 0000000..38de9ca
--- /dev/null
+++ b/common/Resources/Images/strings.png
Binary files differ
diff --git a/common/Resources/Images/stringssel.png b/common/Resources/Images/stringssel.png
new file mode 100644
index 0000000..08f8997
--- /dev/null
+++ b/common/Resources/Images/stringssel.png
Binary files differ
diff --git a/common/Resources/Images/synthTam.png b/common/Resources/Images/synthTam.png
new file mode 100644
index 0000000..e0837d2
--- /dev/null
+++ b/common/Resources/Images/synthTam.png
Binary files differ
diff --git a/common/Resources/Images/synthTamDown.png b/common/Resources/Images/synthTamDown.png
new file mode 100644
index 0000000..eef7fcb
--- /dev/null
+++ b/common/Resources/Images/synthTamDown.png
Binary files differ
diff --git a/common/Resources/Images/synthTamOver.png b/common/Resources/Images/synthTamOver.png
new file mode 100644
index 0000000..6f203e8
--- /dev/null
+++ b/common/Resources/Images/synthTamOver.png
Binary files differ
diff --git a/common/Resources/Images/synthlabMask.png b/common/Resources/Images/synthlabMask.png
new file mode 100644
index 0000000..b41d467
--- /dev/null
+++ b/common/Resources/Images/synthlabMask.png
Binary files differ
diff --git a/common/Resources/Images/tchiwo.png b/common/Resources/Images/tchiwo.png
new file mode 100644
index 0000000..666f004
--- /dev/null
+++ b/common/Resources/Images/tchiwo.png
Binary files differ
diff --git a/common/Resources/Images/tchiwosel.png b/common/Resources/Images/tchiwosel.png
new file mode 100644
index 0000000..9878149
--- /dev/null
+++ b/common/Resources/Images/tchiwosel.png
Binary files differ
diff --git a/common/Resources/Images/tempo1.png b/common/Resources/Images/tempo1.png
new file mode 100644
index 0000000..71f741c
--- /dev/null
+++ b/common/Resources/Images/tempo1.png
Binary files differ
diff --git a/common/Resources/Images/tempo2.png b/common/Resources/Images/tempo2.png
new file mode 100644
index 0000000..2c69512
--- /dev/null
+++ b/common/Resources/Images/tempo2.png
Binary files differ
diff --git a/common/Resources/Images/tempo3.png b/common/Resources/Images/tempo3.png
new file mode 100644
index 0000000..a7905d1
--- /dev/null
+++ b/common/Resources/Images/tempo3.png
Binary files differ
diff --git a/common/Resources/Images/tempo4.png b/common/Resources/Images/tempo4.png
new file mode 100644
index 0000000..c264a47
--- /dev/null
+++ b/common/Resources/Images/tempo4.png
Binary files differ
diff --git a/common/Resources/Images/tempo5.png b/common/Resources/Images/tempo5.png
new file mode 100644
index 0000000..1c89411
--- /dev/null
+++ b/common/Resources/Images/tempo5.png
Binary files differ
diff --git a/common/Resources/Images/tempo6.png b/common/Resources/Images/tempo6.png
new file mode 100644
index 0000000..68deca9
--- /dev/null
+++ b/common/Resources/Images/tempo6.png
Binary files differ
diff --git a/common/Resources/Images/tempo7.png b/common/Resources/Images/tempo7.png
new file mode 100644
index 0000000..81ffb5a
--- /dev/null
+++ b/common/Resources/Images/tempo7.png
Binary files differ
diff --git a/common/Resources/Images/tempo8.png b/common/Resources/Images/tempo8.png
new file mode 100644
index 0000000..751e68a
--- /dev/null
+++ b/common/Resources/Images/tempo8.png
Binary files differ
diff --git a/common/Resources/Images/trackBG.png b/common/Resources/Images/trackBG.png
new file mode 100644
index 0000000..6fdf29c
--- /dev/null
+++ b/common/Resources/Images/trackBG.png
Binary files differ
diff --git a/common/Resources/Images/trackBGDrum.png b/common/Resources/Images/trackBGDrum.png
new file mode 100644
index 0000000..1a53271
--- /dev/null
+++ b/common/Resources/Images/trackBGDrum.png
Binary files differ
diff --git a/common/Resources/Images/trackBGDrumSelected.png b/common/Resources/Images/trackBGDrumSelected.png
new file mode 100644
index 0000000..54f765e
--- /dev/null
+++ b/common/Resources/Images/trackBGDrumSelected.png
Binary files differ
diff --git a/common/Resources/Images/trackBGSelected.png b/common/Resources/Images/trackBGSelected.png
new file mode 100644
index 0000000..c800112
--- /dev/null
+++ b/common/Resources/Images/trackBGSelected.png
Binary files differ
diff --git a/common/Resources/Images/triangle.png b/common/Resources/Images/triangle.png
new file mode 100644
index 0000000..2a74f17
--- /dev/null
+++ b/common/Resources/Images/triangle.png
Binary files differ
diff --git a/common/Resources/Images/trianglesel.png b/common/Resources/Images/trianglesel.png
new file mode 100644
index 0000000..70d6e58
--- /dev/null
+++ b/common/Resources/Images/trianglesel.png
Binary files differ
diff --git a/common/Resources/Images/trumpet.png b/common/Resources/Images/trumpet.png
new file mode 100644
index 0000000..6876a92
--- /dev/null
+++ b/common/Resources/Images/trumpet.png
Binary files differ
diff --git a/common/Resources/Images/trumpetsel.png b/common/Resources/Images/trumpetsel.png
new file mode 100644
index 0000000..d77a8e4
--- /dev/null
+++ b/common/Resources/Images/trumpetsel.png
Binary files differ
diff --git a/common/Resources/Images/tuba.png b/common/Resources/Images/tuba.png
new file mode 100644
index 0000000..5cdf2f1
--- /dev/null
+++ b/common/Resources/Images/tuba.png
Binary files differ
diff --git a/common/Resources/Images/tubasel.png b/common/Resources/Images/tubasel.png
new file mode 100644
index 0000000..d194d91
--- /dev/null
+++ b/common/Resources/Images/tubasel.png
Binary files differ
diff --git a/common/Resources/Images/violin.png b/common/Resources/Images/violin.png
new file mode 100644
index 0000000..f13988f
--- /dev/null
+++ b/common/Resources/Images/violin.png
Binary files differ
diff --git a/common/Resources/Images/violinsel.png b/common/Resources/Images/violinsel.png
new file mode 100644
index 0000000..36f8b02
--- /dev/null
+++ b/common/Resources/Images/violinsel.png
Binary files differ
diff --git a/common/Resources/Images/voix.png b/common/Resources/Images/voix.png
new file mode 100644
index 0000000..0c1fc68
--- /dev/null
+++ b/common/Resources/Images/voix.png
Binary files differ
diff --git a/common/Resources/Images/voixsel.png b/common/Resources/Images/voixsel.png
new file mode 100644
index 0000000..8dc5a37
--- /dev/null
+++ b/common/Resources/Images/voixsel.png
Binary files differ
diff --git a/common/Resources/Images/volume0.png b/common/Resources/Images/volume0.png
new file mode 100644
index 0000000..f2af58b
--- /dev/null
+++ b/common/Resources/Images/volume0.png
Binary files differ
diff --git a/common/Resources/Images/volume1.png b/common/Resources/Images/volume1.png
new file mode 100644
index 0000000..67bd806
--- /dev/null
+++ b/common/Resources/Images/volume1.png
Binary files differ
diff --git a/common/Resources/Images/volume2.png b/common/Resources/Images/volume2.png
new file mode 100644
index 0000000..74511e9
--- /dev/null
+++ b/common/Resources/Images/volume2.png
Binary files differ
diff --git a/common/Resources/Images/volume3.png b/common/Resources/Images/volume3.png
new file mode 100644
index 0000000..fc0f894
--- /dev/null
+++ b/common/Resources/Images/volume3.png
Binary files differ
diff --git a/common/Resources/Images/water.png b/common/Resources/Images/water.png
new file mode 100644
index 0000000..c199fff
--- /dev/null
+++ b/common/Resources/Images/water.png
Binary files differ
diff --git a/common/Resources/Images/watersel.png b/common/Resources/Images/watersel.png
new file mode 100644
index 0000000..c685fe6
--- /dev/null
+++ b/common/Resources/Images/watersel.png
Binary files differ
diff --git a/common/Resources/Images/winds.png b/common/Resources/Images/winds.png
new file mode 100644
index 0000000..bfb9e26
--- /dev/null
+++ b/common/Resources/Images/winds.png
Binary files differ
diff --git a/common/Resources/Images/windssel.png b/common/Resources/Images/windssel.png
new file mode 100644
index 0000000..fee7452
--- /dev/null
+++ b/common/Resources/Images/windssel.png
Binary files differ
diff --git a/common/Resources/Images/zap.png b/common/Resources/Images/zap.png
new file mode 100644
index 0000000..6599e0f
--- /dev/null
+++ b/common/Resources/Images/zap.png
Binary files differ
diff --git a/common/Resources/Images/zapsel.png b/common/Resources/Images/zapsel.png
new file mode 100644
index 0000000..0f2b324
--- /dev/null
+++ b/common/Resources/Images/zapsel.png
Binary files differ
diff --git a/common/Resources/Loops/loop1.ttl b/common/Resources/Loops/loop1.ttl
new file mode 100644
index 0000000..97bb9a6
--- /dev/null
+++ b/common/Resources/Loops/loop1.ttl
@@ -0,0 +1,5 @@
+page_add 2 7 0 [88, 77, 67, 85, 137]
+note_add 92 2 0 0 29 0.75 0.5 24 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 93 2 0 24 44 0.75 0.5 7 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 94 2 0 36 44 0.75 0.5 6 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 95 2 0 48 32 0.75 0.5 24 0 88 0.005 0.098 0.1 0 1000 0 edit
diff --git a/common/Resources/Loops/loop2.ttl b/common/Resources/Loops/loop2.ttl
new file mode 100644
index 0000000..2e5e7ea
--- /dev/null
+++ b/common/Resources/Loops/loop2.ttl
@@ -0,0 +1,44 @@
+page_add 16 5 0 [88, 76, 56, 82, 135]
+note_add 73 16 0 0 48 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 74 16 0 12 24 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 75 16 0 1 48 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 76 16 0 2 48 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 77 16 0 3 48 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 78 16 0 4 48 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 79 16 0 13 24 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 80 16 0 14 24 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 81 16 0 15 24 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 82 16 0 16 24 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 83 16 0 24 48 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 84 16 0 25 48 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 85 16 0 26 48 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 86 16 0 27 48 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 87 16 0 36 24 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 88 16 0 37 24 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 89 16 0 38 24 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 90 16 0 39 24 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 91 16 0 55 35 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 92 16 0 56 36 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 93 16 0 57 34 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 94 16 0 58 36 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 95 16 0 59 34 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 96 16 0 43 35 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 97 16 0 44 36 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 98 16 0 45 34 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 99 16 0 46 36 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 100 16 0 47 34 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 101 16 0 31 35 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 102 16 0 32 36 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 103 16 0 33 34 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 104 16 0 34 36 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 105 16 0 35 34 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 106 16 0 19 35 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 107 16 0 20 36 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 108 16 0 21 34 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 109 16 0 22 36 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 110 16 0 23 34 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 111 16 0 7 35 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 112 16 0 8 36 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 113 16 0 9 34 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 114 16 0 10 36 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 115 16 0 11 34 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
diff --git a/common/Resources/Loops/loop3.ttl b/common/Resources/Loops/loop3.ttl
new file mode 100644
index 0000000..4b6bdd6
--- /dev/null
+++ b/common/Resources/Loops/loop3.ttl
@@ -0,0 +1,9 @@
+page_add 16 2 0 [88, 76, 56, 82, 135]
+note_add 116 16 0 0 45 0.75 0.5 3 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 117 16 0 3 45 0.75 0.5 3 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 118 16 0 6 45 0.75 0.5 3 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 119 16 0 9 41 0.75 0.5 3 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 120 16 0 12 24 0.75 0.5 3 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 121 16 0 15 24 0.75 0.5 3 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 122 16 0 18 38 0.75 0.5 3 0 88 0.005 0.098 0.1 0 1000 0 edit
+note_add 123 16 0 21 45 0.75 0.5 3 0 88 0.005 0.098 0.1 0 1000 0 edit
diff --git a/common/Resources/Sounds/acguit b/common/Resources/Sounds/acguit
new file mode 100755
index 0000000..ec431e8
--- /dev/null
+++ b/common/Resources/Sounds/acguit
Binary files differ
diff --git a/common/Resources/Sounds/alarm b/common/Resources/Sounds/alarm
new file mode 100755
index 0000000..34eb906
--- /dev/null
+++ b/common/Resources/Sounds/alarm
Binary files differ
diff --git a/common/Resources/Sounds/banjo b/common/Resources/Sounds/banjo
new file mode 100755
index 0000000..ec431e8
--- /dev/null
+++ b/common/Resources/Sounds/banjo
Binary files differ
diff --git a/common/Resources/Sounds/basse b/common/Resources/Sounds/basse
new file mode 100755
index 0000000..2bc1571
--- /dev/null
+++ b/common/Resources/Sounds/basse
Binary files differ
diff --git a/common/Resources/Sounds/bird b/common/Resources/Sounds/bird
new file mode 100755
index 0000000..fbe8a29
--- /dev/null
+++ b/common/Resources/Sounds/bird
Binary files differ
diff --git a/common/Resources/Sounds/bottle b/common/Resources/Sounds/bottle
new file mode 100755
index 0000000..8f3d680
--- /dev/null
+++ b/common/Resources/Sounds/bottle
Binary files differ
diff --git a/common/Resources/Sounds/bubbles b/common/Resources/Sounds/bubbles
new file mode 100755
index 0000000..849ff02
--- /dev/null
+++ b/common/Resources/Sounds/bubbles
Binary files differ
diff --git a/common/Resources/Sounds/byke b/common/Resources/Sounds/byke
new file mode 100755
index 0000000..6f428b8
--- /dev/null
+++ b/common/Resources/Sounds/byke
Binary files differ
diff --git a/common/Resources/Sounds/camera b/common/Resources/Sounds/camera
new file mode 100755
index 0000000..8eaa5b5
--- /dev/null
+++ b/common/Resources/Sounds/camera
Binary files differ
diff --git a/common/Resources/Sounds/car b/common/Resources/Sounds/car
new file mode 100755
index 0000000..66e42ae
--- /dev/null
+++ b/common/Resources/Sounds/car
Binary files differ
diff --git a/common/Resources/Sounds/cat b/common/Resources/Sounds/cat
new file mode 100755
index 0000000..845ee8e
--- /dev/null
+++ b/common/Resources/Sounds/cat
Binary files differ
diff --git a/common/Resources/Sounds/cello b/common/Resources/Sounds/cello
new file mode 100755
index 0000000..4249723
--- /dev/null
+++ b/common/Resources/Sounds/cello
Binary files differ
diff --git a/common/Resources/Sounds/chimes b/common/Resources/Sounds/chimes
new file mode 100755
index 0000000..f83e23c
--- /dev/null
+++ b/common/Resources/Sounds/chimes
Binary files differ
diff --git a/common/Resources/Sounds/clang b/common/Resources/Sounds/clang
new file mode 100755
index 0000000..01476fc
--- /dev/null
+++ b/common/Resources/Sounds/clang
Binary files differ
diff --git a/common/Resources/Sounds/clarinette b/common/Resources/Sounds/clarinette
new file mode 100755
index 0000000..329974e
--- /dev/null
+++ b/common/Resources/Sounds/clarinette
Binary files differ
diff --git a/common/Resources/Sounds/cling b/common/Resources/Sounds/cling
new file mode 100755
index 0000000..db3525f
--- /dev/null
+++ b/common/Resources/Sounds/cling
Binary files differ
diff --git a/common/Resources/Sounds/crash b/common/Resources/Sounds/crash
new file mode 100755
index 0000000..8408175
--- /dev/null
+++ b/common/Resources/Sounds/crash
Binary files differ
diff --git a/common/Resources/Sounds/diceinst b/common/Resources/Sounds/diceinst
new file mode 100755
index 0000000..5a41341
--- /dev/null
+++ b/common/Resources/Sounds/diceinst
Binary files differ
diff --git a/common/Resources/Sounds/didjeridu b/common/Resources/Sounds/didjeridu
new file mode 100755
index 0000000..d7556e7
--- /dev/null
+++ b/common/Resources/Sounds/didjeridu
Binary files differ
diff --git a/common/Resources/Sounds/dog b/common/Resources/Sounds/dog
new file mode 100755
index 0000000..c1e8e22
--- /dev/null
+++ b/common/Resources/Sounds/dog
Binary files differ
diff --git a/common/Resources/Sounds/door b/common/Resources/Sounds/door
new file mode 100755
index 0000000..2b3b21a
--- /dev/null
+++ b/common/Resources/Sounds/door
Binary files differ
diff --git a/common/Resources/Sounds/drum1chine b/common/Resources/Sounds/drum1chine
new file mode 100755
index 0000000..bb29f18
--- /dev/null
+++ b/common/Resources/Sounds/drum1chine
Binary files differ
diff --git a/common/Resources/Sounds/drum1crash b/common/Resources/Sounds/drum1crash
new file mode 100755
index 0000000..5f520c2
--- /dev/null
+++ b/common/Resources/Sounds/drum1crash
Binary files differ
diff --git a/common/Resources/Sounds/drum1floortom b/common/Resources/Sounds/drum1floortom
new file mode 100755
index 0000000..f43cb2b
--- /dev/null
+++ b/common/Resources/Sounds/drum1floortom
Binary files differ
diff --git a/common/Resources/Sounds/drum1hardride b/common/Resources/Sounds/drum1hardride
new file mode 100755
index 0000000..94f052f
--- /dev/null
+++ b/common/Resources/Sounds/drum1hardride
Binary files differ
diff --git a/common/Resources/Sounds/drum1hatpedal b/common/Resources/Sounds/drum1hatpedal
new file mode 100755
index 0000000..0c0afe6
--- /dev/null
+++ b/common/Resources/Sounds/drum1hatpedal
Binary files differ
diff --git a/common/Resources/Sounds/drum1hatshoulder b/common/Resources/Sounds/drum1hatshoulder
new file mode 100755
index 0000000..395ef0b
--- /dev/null
+++ b/common/Resources/Sounds/drum1hatshoulder
Binary files differ
diff --git a/common/Resources/Sounds/drum1kick b/common/Resources/Sounds/drum1kick
new file mode 100755
index 0000000..0acfb56
--- /dev/null
+++ b/common/Resources/Sounds/drum1kick
Binary files differ
diff --git a/common/Resources/Sounds/drum1ridebell b/common/Resources/Sounds/drum1ridebell
new file mode 100755
index 0000000..6f6b6ce
--- /dev/null
+++ b/common/Resources/Sounds/drum1ridebell
Binary files differ
diff --git a/common/Resources/Sounds/drum1snare b/common/Resources/Sounds/drum1snare
new file mode 100755
index 0000000..54a6372
--- /dev/null
+++ b/common/Resources/Sounds/drum1snare
Binary files differ
diff --git a/common/Resources/Sounds/drum1snaresidestick b/common/Resources/Sounds/drum1snaresidestick
new file mode 100755
index 0000000..a99e846
--- /dev/null
+++ b/common/Resources/Sounds/drum1snaresidestick
Binary files differ
diff --git a/common/Resources/Sounds/drum1splash b/common/Resources/Sounds/drum1splash
new file mode 100755
index 0000000..49a334e
--- /dev/null
+++ b/common/Resources/Sounds/drum1splash
Binary files differ
diff --git a/common/Resources/Sounds/drum1tom b/common/Resources/Sounds/drum1tom
new file mode 100755
index 0000000..ed1464c
--- /dev/null
+++ b/common/Resources/Sounds/drum1tom
Binary files differ
diff --git a/common/Resources/Sounds/drum2darbukadoom b/common/Resources/Sounds/drum2darbukadoom
new file mode 100755
index 0000000..5a90725
--- /dev/null
+++ b/common/Resources/Sounds/drum2darbukadoom
Binary files differ
diff --git a/common/Resources/Sounds/drum2darbukafinger b/common/Resources/Sounds/drum2darbukafinger
new file mode 100755
index 0000000..163aa3c
--- /dev/null
+++ b/common/Resources/Sounds/drum2darbukafinger
Binary files differ
diff --git a/common/Resources/Sounds/drum2darbukapied b/common/Resources/Sounds/drum2darbukapied
new file mode 100755
index 0000000..006586a
--- /dev/null
+++ b/common/Resources/Sounds/drum2darbukapied
Binary files differ
diff --git a/common/Resources/Sounds/drum2darbukapiedsoft b/common/Resources/Sounds/drum2darbukapiedsoft
new file mode 100755
index 0000000..cf2aaa8
--- /dev/null
+++ b/common/Resources/Sounds/drum2darbukapiedsoft
Binary files differ
diff --git a/common/Resources/Sounds/drum2darbukaroll b/common/Resources/Sounds/drum2darbukaroll
new file mode 100755
index 0000000..ded7a31
--- /dev/null
+++ b/common/Resources/Sounds/drum2darbukaroll
Binary files differ
diff --git a/common/Resources/Sounds/drum2darbukaslap b/common/Resources/Sounds/drum2darbukaslap
new file mode 100755
index 0000000..fd70b88
--- /dev/null
+++ b/common/Resources/Sounds/drum2darbukaslap
Binary files differ
diff --git a/common/Resources/Sounds/drum2darbukatak b/common/Resources/Sounds/drum2darbukatak
new file mode 100755
index 0000000..329f619
--- /dev/null
+++ b/common/Resources/Sounds/drum2darbukatak
Binary files differ
diff --git a/common/Resources/Sounds/drum2hatflanger b/common/Resources/Sounds/drum2hatflanger
new file mode 100755
index 0000000..9dd9389
--- /dev/null
+++ b/common/Resources/Sounds/drum2hatflanger
Binary files differ
diff --git a/common/Resources/Sounds/drum2hatpied b/common/Resources/Sounds/drum2hatpied
new file mode 100755
index 0000000..84e774e
--- /dev/null
+++ b/common/Resources/Sounds/drum2hatpied
Binary files differ
diff --git a/common/Resources/Sounds/drum2hatpied2 b/common/Resources/Sounds/drum2hatpied2
new file mode 100755
index 0000000..cd21b17
--- /dev/null
+++ b/common/Resources/Sounds/drum2hatpied2
Binary files differ
diff --git a/common/Resources/Sounds/drum2tambourinepied b/common/Resources/Sounds/drum2tambourinepied
new file mode 100755
index 0000000..d6b566a
--- /dev/null
+++ b/common/Resources/Sounds/drum2tambourinepied
Binary files differ
diff --git a/common/Resources/Sounds/drum2tambourinepiedsoft b/common/Resources/Sounds/drum2tambourinepiedsoft
new file mode 100755
index 0000000..4da2ea6
--- /dev/null
+++ b/common/Resources/Sounds/drum2tambourinepiedsoft
Binary files differ
diff --git a/common/Resources/Sounds/drum3cowbell b/common/Resources/Sounds/drum3cowbell
new file mode 100755
index 0000000..3c52687
--- /dev/null
+++ b/common/Resources/Sounds/drum3cowbell
Binary files differ
diff --git a/common/Resources/Sounds/drum3cowbelltip b/common/Resources/Sounds/drum3cowbelltip
new file mode 100755
index 0000000..7b79fe2
--- /dev/null
+++ b/common/Resources/Sounds/drum3cowbelltip
Binary files differ
diff --git a/common/Resources/Sounds/drum3cup b/common/Resources/Sounds/drum3cup
new file mode 100755
index 0000000..6cf6da2
--- /dev/null
+++ b/common/Resources/Sounds/drum3cup
Binary files differ
diff --git a/common/Resources/Sounds/drum3djembelow b/common/Resources/Sounds/drum3djembelow
new file mode 100755
index 0000000..ad5fd0a
--- /dev/null
+++ b/common/Resources/Sounds/drum3djembelow
Binary files differ
diff --git a/common/Resources/Sounds/drum3djembemid b/common/Resources/Sounds/drum3djembemid
new file mode 100755
index 0000000..55b6d9f
--- /dev/null
+++ b/common/Resources/Sounds/drum3djembemid
Binary files differ
diff --git a/common/Resources/Sounds/drum3djembesidestick b/common/Resources/Sounds/drum3djembesidestick
new file mode 100755
index 0000000..94c29e6
--- /dev/null
+++ b/common/Resources/Sounds/drum3djembesidestick
Binary files differ
diff --git a/common/Resources/Sounds/drum3djembeslap b/common/Resources/Sounds/drum3djembeslap
new file mode 100755
index 0000000..d201e52
--- /dev/null
+++ b/common/Resources/Sounds/drum3djembeslap
Binary files differ
diff --git a/common/Resources/Sounds/drum3djembestickmid b/common/Resources/Sounds/drum3djembestickmid
new file mode 100755
index 0000000..9da83ba
--- /dev/null
+++ b/common/Resources/Sounds/drum3djembestickmid
Binary files differ
diff --git a/common/Resources/Sounds/drum3metalstand b/common/Resources/Sounds/drum3metalstand
new file mode 100755
index 0000000..059efcc
--- /dev/null
+++ b/common/Resources/Sounds/drum3metalstand
Binary files differ
diff --git a/common/Resources/Sounds/drum3pedalperc b/common/Resources/Sounds/drum3pedalperc
new file mode 100755
index 0000000..c271d66
--- /dev/null
+++ b/common/Resources/Sounds/drum3pedalperc
Binary files differ
diff --git a/common/Resources/Sounds/drum3rainstick b/common/Resources/Sounds/drum3rainstick
new file mode 100755
index 0000000..561d0d9
--- /dev/null
+++ b/common/Resources/Sounds/drum3rainstick
Binary files differ
diff --git a/common/Resources/Sounds/drum3tambourinehigh b/common/Resources/Sounds/drum3tambourinehigh
new file mode 100755
index 0000000..cf2c61e
--- /dev/null
+++ b/common/Resources/Sounds/drum3tambourinehigh
Binary files differ
diff --git a/common/Resources/Sounds/drum3tambourinelow b/common/Resources/Sounds/drum3tambourinelow
new file mode 100755
index 0000000..ff8e278
--- /dev/null
+++ b/common/Resources/Sounds/drum3tambourinelow
Binary files differ
diff --git a/common/Resources/Sounds/drum4afrofeet b/common/Resources/Sounds/drum4afrofeet
new file mode 100644
index 0000000..b2044da
--- /dev/null
+++ b/common/Resources/Sounds/drum4afrofeet
Binary files differ
diff --git a/common/Resources/Sounds/drum4fingersn b/common/Resources/Sounds/drum4fingersn
new file mode 100644
index 0000000..e6b60a5
--- /dev/null
+++ b/common/Resources/Sounds/drum4fingersn
Binary files differ
diff --git a/common/Resources/Sounds/drum4mutecuic b/common/Resources/Sounds/drum4mutecuic
new file mode 100644
index 0000000..ef0c0c0
--- /dev/null
+++ b/common/Resources/Sounds/drum4mutecuic
Binary files differ
diff --git a/common/Resources/Sounds/drum4stompbass b/common/Resources/Sounds/drum4stompbass
new file mode 100644
index 0000000..68dd316
--- /dev/null
+++ b/common/Resources/Sounds/drum4stompbass
Binary files differ
diff --git a/common/Resources/Sounds/drum4tambouri b/common/Resources/Sounds/drum4tambouri
new file mode 100644
index 0000000..5b32be2
--- /dev/null
+++ b/common/Resources/Sounds/drum4tambouri
Binary files differ
diff --git a/common/Resources/Sounds/drum4tr707clap b/common/Resources/Sounds/drum4tr707clap
new file mode 100644
index 0000000..f9ea03e
--- /dev/null
+++ b/common/Resources/Sounds/drum4tr707clap
Binary files differ
diff --git a/common/Resources/Sounds/drum4tr707open b/common/Resources/Sounds/drum4tr707open
new file mode 100644
index 0000000..f7d54bf
--- /dev/null
+++ b/common/Resources/Sounds/drum4tr707open
Binary files differ
diff --git a/common/Resources/Sounds/drum4tr808closed b/common/Resources/Sounds/drum4tr808closed
new file mode 100644
index 0000000..8995edd
--- /dev/null
+++ b/common/Resources/Sounds/drum4tr808closed
Binary files differ
diff --git a/common/Resources/Sounds/drum4tr808sn b/common/Resources/Sounds/drum4tr808sn
new file mode 100644
index 0000000..adde850
--- /dev/null
+++ b/common/Resources/Sounds/drum4tr808sn
Binary files differ
diff --git a/common/Resources/Sounds/drum4tr909bass b/common/Resources/Sounds/drum4tr909bass
new file mode 100644
index 0000000..6420213
--- /dev/null
+++ b/common/Resources/Sounds/drum4tr909bass
Binary files differ
diff --git a/common/Resources/Sounds/drum4tr909kick b/common/Resources/Sounds/drum4tr909kick
new file mode 100644
index 0000000..6e33dd3
--- /dev/null
+++ b/common/Resources/Sounds/drum4tr909kick
Binary files differ
diff --git a/common/Resources/Sounds/drum4tr909sn b/common/Resources/Sounds/drum4tr909sn
new file mode 100644
index 0000000..486ed42
--- /dev/null
+++ b/common/Resources/Sounds/drum4tr909sn
Binary files differ
diff --git a/common/Resources/Sounds/drum5agogoaigu b/common/Resources/Sounds/drum5agogoaigu
new file mode 100755
index 0000000..3889332
--- /dev/null
+++ b/common/Resources/Sounds/drum5agogoaigu
Binary files differ
diff --git a/common/Resources/Sounds/drum5agogograve b/common/Resources/Sounds/drum5agogograve
new file mode 100755
index 0000000..5717751
--- /dev/null
+++ b/common/Resources/Sounds/drum5agogograve
Binary files differ
diff --git a/common/Resources/Sounds/drum5bongoaiguouvert b/common/Resources/Sounds/drum5bongoaiguouvert
new file mode 100755
index 0000000..95aba33
--- /dev/null
+++ b/common/Resources/Sounds/drum5bongoaiguouvert
Binary files differ
diff --git a/common/Resources/Sounds/drum5bongograveouvert b/common/Resources/Sounds/drum5bongograveouvert
new file mode 100755
index 0000000..d7d1e58
--- /dev/null
+++ b/common/Resources/Sounds/drum5bongograveouvert
Binary files differ
diff --git a/common/Resources/Sounds/drum5congaaiguouvert b/common/Resources/Sounds/drum5congaaiguouvert
new file mode 100755
index 0000000..a59ce75
--- /dev/null
+++ b/common/Resources/Sounds/drum5congaaiguouvert
Binary files differ
diff --git a/common/Resources/Sounds/drum5congagraveferme b/common/Resources/Sounds/drum5congagraveferme
new file mode 100755
index 0000000..a49c459
--- /dev/null
+++ b/common/Resources/Sounds/drum5congagraveferme
Binary files differ
diff --git a/common/Resources/Sounds/drum5congagraveouvert b/common/Resources/Sounds/drum5congagraveouvert
new file mode 100755
index 0000000..3b9503c
--- /dev/null
+++ b/common/Resources/Sounds/drum5congagraveouvert
Binary files differ
diff --git a/common/Resources/Sounds/drum5guiroretour b/common/Resources/Sounds/drum5guiroretour
new file mode 100755
index 0000000..025ebfb
--- /dev/null
+++ b/common/Resources/Sounds/drum5guiroretour
Binary files differ
diff --git a/common/Resources/Sounds/drum5quicaaigu b/common/Resources/Sounds/drum5quicaaigu
new file mode 100755
index 0000000..d952c8c
--- /dev/null
+++ b/common/Resources/Sounds/drum5quicaaigu
Binary files differ
diff --git a/common/Resources/Sounds/drum5quicamedium b/common/Resources/Sounds/drum5quicamedium
new file mode 100755
index 0000000..57e92e6
--- /dev/null
+++ b/common/Resources/Sounds/drum5quicamedium
Binary files differ
diff --git a/common/Resources/Sounds/drum5timablesaiguslap b/common/Resources/Sounds/drum5timablesaiguslap
new file mode 100755
index 0000000..1b531b0
--- /dev/null
+++ b/common/Resources/Sounds/drum5timablesaiguslap
Binary files differ
diff --git a/common/Resources/Sounds/drum5timablesslap b/common/Resources/Sounds/drum5timablesslap
new file mode 100755
index 0000000..1e5ec3e
--- /dev/null
+++ b/common/Resources/Sounds/drum5timablesslap
Binary files differ
diff --git a/common/Resources/Sounds/drum5vibraslap b/common/Resources/Sounds/drum5vibraslap
new file mode 100755
index 0000000..e539891
--- /dev/null
+++ b/common/Resources/Sounds/drum5vibraslap
Binary files differ
diff --git a/common/Resources/Sounds/duck b/common/Resources/Sounds/duck
new file mode 100755
index 0000000..37b5f85
--- /dev/null
+++ b/common/Resources/Sounds/duck
Binary files differ
diff --git a/common/Resources/Sounds/duck2 b/common/Resources/Sounds/duck2
new file mode 100755
index 0000000..1c62622
--- /dev/null
+++ b/common/Resources/Sounds/duck2
Binary files differ
diff --git a/common/Resources/Sounds/flute b/common/Resources/Sounds/flute
new file mode 100755
index 0000000..68a2580
--- /dev/null
+++ b/common/Resources/Sounds/flute
Binary files differ
diff --git a/common/Resources/Sounds/gam b/common/Resources/Sounds/gam
new file mode 100755
index 0000000..dca077b
--- /dev/null
+++ b/common/Resources/Sounds/gam
Binary files differ
diff --git a/common/Resources/Sounds/guidice1 b/common/Resources/Sounds/guidice1
new file mode 100755
index 0000000..9e48310
--- /dev/null
+++ b/common/Resources/Sounds/guidice1
Binary files differ
diff --git a/common/Resources/Sounds/guidice10 b/common/Resources/Sounds/guidice10
new file mode 100755
index 0000000..8da4267
--- /dev/null
+++ b/common/Resources/Sounds/guidice10
Binary files differ
diff --git a/common/Resources/Sounds/guidice2 b/common/Resources/Sounds/guidice2
new file mode 100755
index 0000000..7b12043
--- /dev/null
+++ b/common/Resources/Sounds/guidice2
Binary files differ
diff --git a/common/Resources/Sounds/guidice3 b/common/Resources/Sounds/guidice3
new file mode 100755
index 0000000..68d1f45
--- /dev/null
+++ b/common/Resources/Sounds/guidice3
Binary files differ
diff --git a/common/Resources/Sounds/guidice4 b/common/Resources/Sounds/guidice4
new file mode 100755
index 0000000..3d72119
--- /dev/null
+++ b/common/Resources/Sounds/guidice4
Binary files differ
diff --git a/common/Resources/Sounds/guidice5 b/common/Resources/Sounds/guidice5
new file mode 100755
index 0000000..79cc786
--- /dev/null
+++ b/common/Resources/Sounds/guidice5
Binary files differ
diff --git a/common/Resources/Sounds/guidice6 b/common/Resources/Sounds/guidice6
new file mode 100755
index 0000000..dc2f756
--- /dev/null
+++ b/common/Resources/Sounds/guidice6
Binary files differ
diff --git a/common/Resources/Sounds/guidice7 b/common/Resources/Sounds/guidice7
new file mode 100755
index 0000000..af341b7
--- /dev/null
+++ b/common/Resources/Sounds/guidice7
Binary files differ
diff --git a/common/Resources/Sounds/guidice8 b/common/Resources/Sounds/guidice8
new file mode 100755
index 0000000..9901020
--- /dev/null
+++ b/common/Resources/Sounds/guidice8
Binary files differ
diff --git a/common/Resources/Sounds/guidice9 b/common/Resources/Sounds/guidice9
new file mode 100755
index 0000000..8798781
--- /dev/null
+++ b/common/Resources/Sounds/guidice9
Binary files differ
diff --git a/common/Resources/Sounds/guit b/common/Resources/Sounds/guit
new file mode 100755
index 0000000..dfb1866
--- /dev/null
+++ b/common/Resources/Sounds/guit
Binary files differ
diff --git a/common/Resources/Sounds/guit2 b/common/Resources/Sounds/guit2
new file mode 100755
index 0000000..1495832
--- /dev/null
+++ b/common/Resources/Sounds/guit2
Binary files differ
diff --git a/common/Resources/Sounds/harmonica b/common/Resources/Sounds/harmonica
new file mode 100755
index 0000000..7b0af9f
--- /dev/null
+++ b/common/Resources/Sounds/harmonica
Binary files differ
diff --git a/common/Resources/Sounds/harmonium b/common/Resources/Sounds/harmonium
new file mode 100755
index 0000000..90a5630
--- /dev/null
+++ b/common/Resources/Sounds/harmonium
Binary files differ
diff --git a/common/Resources/Sounds/horse b/common/Resources/Sounds/horse
new file mode 100755
index 0000000..b7756a3
--- /dev/null
+++ b/common/Resources/Sounds/horse
Binary files differ
diff --git a/common/Resources/Sounds/kalimba b/common/Resources/Sounds/kalimba
new file mode 100755
index 0000000..2e02b48
--- /dev/null
+++ b/common/Resources/Sounds/kalimba
Binary files differ
diff --git a/common/Resources/Sounds/koto b/common/Resources/Sounds/koto
new file mode 100755
index 0000000..9279a7f
--- /dev/null
+++ b/common/Resources/Sounds/koto
Binary files differ
diff --git a/common/Resources/Sounds/lab1 b/common/Resources/Sounds/lab1
new file mode 100644
index 0000000..d26b87b
--- /dev/null
+++ b/common/Resources/Sounds/lab1
Binary files differ
diff --git a/common/Resources/Sounds/lab2 b/common/Resources/Sounds/lab2
new file mode 100644
index 0000000..d26b87b
--- /dev/null
+++ b/common/Resources/Sounds/lab2
Binary files differ
diff --git a/common/Resources/Sounds/lab3 b/common/Resources/Sounds/lab3
new file mode 100644
index 0000000..d26b87b
--- /dev/null
+++ b/common/Resources/Sounds/lab3
Binary files differ
diff --git a/common/Resources/Sounds/lab4 b/common/Resources/Sounds/lab4
new file mode 100644
index 0000000..d26b87b
--- /dev/null
+++ b/common/Resources/Sounds/lab4
Binary files differ
diff --git a/common/Resources/Sounds/lab5 b/common/Resources/Sounds/lab5
new file mode 100644
index 0000000..d26b87b
--- /dev/null
+++ b/common/Resources/Sounds/lab5
Binary files differ
diff --git a/common/Resources/Sounds/lab6 b/common/Resources/Sounds/lab6
new file mode 100644
index 0000000..d26b87b
--- /dev/null
+++ b/common/Resources/Sounds/lab6
Binary files differ
diff --git a/common/Resources/Sounds/laugh b/common/Resources/Sounds/laugh
new file mode 100755
index 0000000..05483ce
--- /dev/null
+++ b/common/Resources/Sounds/laugh
Binary files differ
diff --git a/common/Resources/Sounds/mando b/common/Resources/Sounds/mando
new file mode 100755
index 0000000..88c8484
--- /dev/null
+++ b/common/Resources/Sounds/mando
Binary files differ
diff --git a/common/Resources/Sounds/marimba b/common/Resources/Sounds/marimba
new file mode 100755
index 0000000..331b1db
--- /dev/null
+++ b/common/Resources/Sounds/marimba
Binary files differ
diff --git a/common/Resources/Sounds/mic1 b/common/Resources/Sounds/mic1
new file mode 100755
index 0000000..d26b87b
--- /dev/null
+++ b/common/Resources/Sounds/mic1
Binary files differ
diff --git a/common/Resources/Sounds/mic2 b/common/Resources/Sounds/mic2
new file mode 100755
index 0000000..d26b87b
--- /dev/null
+++ b/common/Resources/Sounds/mic2
Binary files differ
diff --git a/common/Resources/Sounds/mic3 b/common/Resources/Sounds/mic3
new file mode 100755
index 0000000..d26b87b
--- /dev/null
+++ b/common/Resources/Sounds/mic3
Binary files differ
diff --git a/common/Resources/Sounds/mic4 b/common/Resources/Sounds/mic4
new file mode 100755
index 0000000..d26b87b
--- /dev/null
+++ b/common/Resources/Sounds/mic4
Binary files differ
diff --git a/common/Resources/Sounds/ocarina b/common/Resources/Sounds/ocarina
new file mode 100755
index 0000000..d3a8c06
--- /dev/null
+++ b/common/Resources/Sounds/ocarina
Binary files differ
diff --git a/common/Resources/Sounds/ounk b/common/Resources/Sounds/ounk
new file mode 100755
index 0000000..1272c5f
--- /dev/null
+++ b/common/Resources/Sounds/ounk
Binary files differ
diff --git a/common/Resources/Sounds/ow b/common/Resources/Sounds/ow
new file mode 100755
index 0000000..8270199
--- /dev/null
+++ b/common/Resources/Sounds/ow
Binary files differ
diff --git a/common/Resources/Sounds/piano b/common/Resources/Sounds/piano
new file mode 100755
index 0000000..f98a513
--- /dev/null
+++ b/common/Resources/Sounds/piano
Binary files differ
diff --git a/common/Resources/Sounds/plane b/common/Resources/Sounds/plane
new file mode 100755
index 0000000..d20142a
--- /dev/null
+++ b/common/Resources/Sounds/plane
Binary files differ
diff --git a/common/Resources/Sounds/rhodes b/common/Resources/Sounds/rhodes
new file mode 100755
index 0000000..16cd8ec
--- /dev/null
+++ b/common/Resources/Sounds/rhodes
Binary files differ
diff --git a/common/Resources/Sounds/saxo b/common/Resources/Sounds/saxo
new file mode 100755
index 0000000..f422c74
--- /dev/null
+++ b/common/Resources/Sounds/saxo
Binary files differ
diff --git a/common/Resources/Sounds/sheep b/common/Resources/Sounds/sheep
new file mode 100755
index 0000000..178bb43
--- /dev/null
+++ b/common/Resources/Sounds/sheep
Binary files differ
diff --git a/common/Resources/Sounds/shenai b/common/Resources/Sounds/shenai
new file mode 100755
index 0000000..115f125
--- /dev/null
+++ b/common/Resources/Sounds/shenai
Binary files differ
diff --git a/common/Resources/Sounds/sitar b/common/Resources/Sounds/sitar
new file mode 100755
index 0000000..9ba4df5
--- /dev/null
+++ b/common/Resources/Sounds/sitar
Binary files differ
diff --git a/common/Resources/Sounds/slap b/common/Resources/Sounds/slap
new file mode 100755
index 0000000..6e1f375
--- /dev/null
+++ b/common/Resources/Sounds/slap
Binary files differ
diff --git a/common/Resources/Sounds/triangle b/common/Resources/Sounds/triangle
new file mode 100755
index 0000000..d916fd0
--- /dev/null
+++ b/common/Resources/Sounds/triangle
Binary files differ
diff --git a/common/Resources/Sounds/trumpet b/common/Resources/Sounds/trumpet
new file mode 100755
index 0000000..a858a96
--- /dev/null
+++ b/common/Resources/Sounds/trumpet
Binary files differ
diff --git a/common/Resources/Sounds/tuba b/common/Resources/Sounds/tuba
new file mode 100755
index 0000000..9e47196
--- /dev/null
+++ b/common/Resources/Sounds/tuba
Binary files differ
diff --git a/common/Resources/Sounds/violin b/common/Resources/Sounds/violin
new file mode 100755
index 0000000..f89733c
--- /dev/null
+++ b/common/Resources/Sounds/violin
Binary files differ
diff --git a/common/Resources/Sounds/voix b/common/Resources/Sounds/voix
new file mode 100755
index 0000000..87f6ca6
--- /dev/null
+++ b/common/Resources/Sounds/voix
Binary files differ
diff --git a/common/Resources/Sounds/water b/common/Resources/Sounds/water
new file mode 100755
index 0000000..c6cee2e
--- /dev/null
+++ b/common/Resources/Sounds/water
Binary files differ
diff --git a/common/Resources/Sounds/zap b/common/Resources/Sounds/zap
new file mode 100755
index 0000000..e401f6b
--- /dev/null
+++ b/common/Resources/Sounds/zap
Binary files differ
diff --git a/common/Resources/SynthFiles/synthFile1 b/common/Resources/SynthFiles/synthFile1
new file mode 100644
index 0000000..adf8bda
--- /dev/null
+++ b/common/Resources/SynthFiles/synthFile1
Binary files differ
diff --git a/common/Resources/SynthFiles/synthFile10 b/common/Resources/SynthFiles/synthFile10
new file mode 100644
index 0000000..ee1d300
--- /dev/null
+++ b/common/Resources/SynthFiles/synthFile10
Binary files differ
diff --git a/common/Resources/SynthFiles/synthFile2 b/common/Resources/SynthFiles/synthFile2
new file mode 100644
index 0000000..58ec8aa
--- /dev/null
+++ b/common/Resources/SynthFiles/synthFile2
Binary files differ
diff --git a/common/Resources/SynthFiles/synthFile3 b/common/Resources/SynthFiles/synthFile3
new file mode 100644
index 0000000..9608200
--- /dev/null
+++ b/common/Resources/SynthFiles/synthFile3
Binary files differ
diff --git a/common/Resources/SynthFiles/synthFile4 b/common/Resources/SynthFiles/synthFile4
new file mode 100644
index 0000000..ef6586a
--- /dev/null
+++ b/common/Resources/SynthFiles/synthFile4
Binary files differ
diff --git a/common/Resources/SynthFiles/synthFile5 b/common/Resources/SynthFiles/synthFile5
new file mode 100644
index 0000000..c0f4f29
--- /dev/null
+++ b/common/Resources/SynthFiles/synthFile5
Binary files differ
diff --git a/common/Resources/SynthFiles/synthFile6 b/common/Resources/SynthFiles/synthFile6
new file mode 100644
index 0000000..5008f47
--- /dev/null
+++ b/common/Resources/SynthFiles/synthFile6
Binary files differ
diff --git a/common/Resources/SynthFiles/synthFile7 b/common/Resources/SynthFiles/synthFile7
new file mode 100644
index 0000000..333cba1
--- /dev/null
+++ b/common/Resources/SynthFiles/synthFile7
Binary files differ
diff --git a/common/Resources/SynthFiles/synthFile8 b/common/Resources/SynthFiles/synthFile8
new file mode 100644
index 0000000..8f30e89
--- /dev/null
+++ b/common/Resources/SynthFiles/synthFile8
Binary files differ
diff --git a/common/Resources/SynthFiles/synthFile9 b/common/Resources/SynthFiles/synthFile9
new file mode 100644
index 0000000..c68bffb
--- /dev/null
+++ b/common/Resources/SynthFiles/synthFile9
Binary files differ
diff --git a/common/Resources/__init__.py b/common/Resources/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/common/Resources/__init__.py
diff --git a/common/Resources/crop.csd b/common/Resources/crop.csd
new file mode 100644
index 0000000..03b10a5
--- /dev/null
+++ b/common/Resources/crop.csd
@@ -0,0 +1,72 @@
+<CsoundSynthesizer>
+
+<CsOptions>
+-W -d -n
+</CsOptions>
+
+<CsInstruments>
+
+sr=16000
+ksmps=64
+nchnls=1
+
+/****************************************************************
+Playing temp file
+****************************************************************/
+instr 1
+
+asig diskin "/home/olpc/.sugar/default/tamtam/snds/tempMic.wav", 1
+gasig dcblock asig
+
+endin
+
+/****************************************************************
+Crop silence at the beginning
+****************************************************************/
+instr 2
+ktimer timeinstk
+ain = gasig
+krms rms ain
+if ktimer > 40 then
+ ktrig trigger krms, 1500, 0
+ if ktrig == 1 then
+ event "i", 3, 0, 2
+ event "i", 4, 2, 0.01
+ turnoff
+ endif
+endif
+endin
+
+/****************************************************************
+recording
+****************************************************************/
+instr 3
+kenv adsr 0.01, 0.05, .9, 0.01
+
+adel delay gasig, .005
+
+ihandle fiopen "/home/olpc/.sugar/default/tamtam/snds/micTemp", 2
+
+fout "/home/olpc/.sugar/default/tamtam/snds/micTemp", 2, adel*kenv
+
+;out adel*kenv
+adel = 0
+endin
+
+/****************************************************************
+Audio input recording ( closing file )
+****************************************************************/
+instr 4
+ficlose "/home/olpc/.sugar/default/tamtam/snds/micTemp"
+endin
+
+
+</CsInstruments>
+
+<CsScore>
+f1 0 8192 10 1
+i1 0 4
+i2 0 4
+</CsScore>
+
+</CsoundSynthesizer>
diff --git a/common/Resources/tamtamorc.csd b/common/Resources/tamtamorc.csd
new file mode 100644
index 0000000..de2f24a
--- /dev/null
+++ b/common/Resources/tamtamorc.csd
@@ -0,0 +1,1096 @@
+<CsoundSynthesizer>
+<CsOptions>
+-n -m0 -W -s -d
+</CsOptions>
+<CsInstruments>
+sr=16000
+ksmps=64
+nchnls=2
+giScale = 1/sr
+giAliasSr = sr/2.1
+
+gainrev init 0
+gaoutL init 0
+gaoutR init 0
+gasynth init 0
+gkTrackpadX init 0
+gkTrackpadY init 0
+
+/*****************************
+matrix for TamTam's SynthLab
+*****************************/
+zakinit 8, 32
+
+/*****************************
+opcodes needed by TamTam's SynthLab
+*****************************/
+
+opcode homeSine, a, kki
+kpitch, kspread, iTable xin
+
+kspread = kspread + 1
+
+kr1 randomi 0.99, 1.01, 3.45
+kr2 randomi 0.9901, 1.0101, 4.43
+kr3 randomi 0.9899, 1.0091, 5.25
+kr4 randomi 0.9889, 1.00921, 6.15
+
+kpit1 = kpitch
+kpit2 = kpit1*kspread
+kpit3 = kpit2*kspread
+kpit4 = kpit3*kspread
+kpit5 = kpit4*kspread
+kpit6 = kpit5*kspread
+kpit7 = kpit6*kspread
+kpit8 = kpit7*kspread
+
+a1 oscil 1000, kpit1*kr1, iTable
+a2 oscil 1000, kpit2*kr2, iTable
+a3 oscil 1000, kpit3*kr3, iTable
+a4 oscil 1000, kpit4*kr4, iTable
+a5 oscil 1000, kpit5*kr1, iTable
+a6 oscil 1000, kpit6*kr2, iTable
+a7 oscil 1000, kpit7*kr3, iTable
+a8 oscil 1000, kpit8*kr4, iTable
+
+aout = a1+a2+a3+a4+a5+a6+a7+a8
+xout aout
+endop
+
+opcode synthGrain, a, aaiiii
+aindex, atrans, ifreq, iphase itable, itabdur xin
+apha phasor ifreq, iphase
+aenv tab apha, 42, 1
+atrig = int(1-aenv)
+apos samphold aindex, atrig
+adur samphold atrans, atrig
+
+aline = apha * adur * sr + apos
+aline limit aline, 0 , itabdur
+ag tablei aline, itable, 0
+aout = ag * aenv
+
+xout aout
+endop
+
+
+opcode ControlMatrice, i, iikkkk
+iTable, iIndex, kc1, kc2, kc3, kc4 xin
+
+iSomme table iIndex, iTable+3
+
+if iSomme == 0 then
+goto noparams
+endif
+
+iPar table iIndex, iTable
+
+if iSomme == 1 then
+kp = iPar
+elseif iSomme == 3 then
+kp = iPar * kc1
+elseif iSomme == 5 then
+kp = iPar * kc2
+elseif iSomme == 7 then
+kp = iPar * ((kc1 + kc2)*.5)
+elseif iSomme == 9 then
+kp = iPar * kc3
+elseif iSomme == 11 then
+kp = iPar * ((kc1 + kc3)*.5)
+elseif iSomme == 13 then
+kp = iPar * ((kc2 + kc3)*.5)
+elseif iSomme == 15 then
+kp = iPar * ((kc1 + kc2 + kc3)*.33)
+elseif iSomme == 17 then
+kp = iPar * kc4
+elseif iSomme == 19 then
+kp = iPar * ((kc1 + kc4)*.5)
+elseif iSomme == 21 then
+kp = iPar * ((kc2 + kc4)*.5)
+elseif iSomme == 23 then
+kp = iPar * ((kc1 + kc2 + kc4)*.33)
+elseif iSomme == 25 then
+kp = iPar * ((kc3 + kc4)*.5)
+elseif iSomme == 27 then
+kp = iPar * ((kc1 + kc3 + kc4)*.5)
+elseif iSomme == 29 then
+kp = iPar * ((kc2 + kc3 + kc4)*.33)
+elseif iSomme == 31 then
+kp = iPar * ((kc1 + kc2 + kc3 + kc4)*.25)
+endif
+
+if iTable == 5201 then
+zkw kp, iIndex+1
+elseif iTable == 5202 then
+zkw kp, iIndex+17
+endif
+
+xout iIndex
+
+noparams:
+endop
+
+opcode SourceMatrice, i, iaaaa
+iIndex, as1, as2, as3, as4 xin
+
+iSomme table iIndex-1, 5206
+
+if iSomme == 0 then
+goto noparams
+endif
+
+if iSomme == 1 then
+as = as1
+elseif iSomme == 2 then
+as = as2
+elseif iSomme == 3 then
+as = as1 + as2
+elseif iSomme == 4 then
+as = as3
+elseif iSomme == 5 then
+as = as1 + as3
+elseif iSomme == 6 then
+as = as2 + as3
+elseif iSomme == 7 then
+as = as1 + as2 + as3
+elseif iSomme == 8 then
+as = as4
+elseif iSomme == 9 then
+as = as1 + as4
+elseif iSomme == 10 then
+as = as2 + as4
+elseif iSomme == 11 then
+as = as1 + as2 + as4
+elseif iSomme == 12 then
+as = as3 + as4
+elseif iSomme == 13 then
+as = as1 + as3 + as4
+elseif iSomme == 14 then
+as = as2 + as3 + as4
+elseif iSomme == 15 then
+as = as1 + as2 + as3 + as4
+endif
+
+zaw as, iIndex
+xout iIndex
+
+noparams:
+endop
+
+opcode FxMatrice, i, iaaaa
+iIndex, as1, as2, as3, as4 xin
+
+iSomme table iIndex-1, 5206
+
+if iSomme == 0 then
+goto noparams
+endif
+
+if iSomme == 1 then
+as = as1
+elseif iSomme == 2 then
+as = as2
+elseif iSomme == 3 then
+as = as1 + as2
+elseif iSomme == 4 then
+as = as3
+elseif iSomme == 5 then
+as = as1 + as3
+elseif iSomme == 6 then
+as = as2 + as3
+elseif iSomme == 7 then
+as = as1 + as2 + as3
+elseif iSomme == 8 then
+as = as4
+elseif iSomme == 9 then
+as = as1 + as4
+elseif iSomme == 10 then
+as = as2 + as4
+elseif iSomme == 11 then
+as = as1 + as2 + as4
+elseif iSomme == 12 then
+as = as3 + as4
+elseif iSomme == 13 then
+as = as1 + as3 + as4
+elseif iSomme == 14 then
+as = as2 + as3 + as4
+endif
+
+zaw as, iIndex
+xout iIndex
+
+noparams:
+endop
+
+opcode controller, k, ii
+iControlNum, idur xin
+
+iControlType table iControlNum-1, 5203
+
+if iControlType == 0 then
+goto nocontrol
+endif
+
+ioffset = (iControlNum-1)*4
+iPar1 table ioffset, 5200
+iPar2 table ioffset+1, 5200
+iPar3 table ioffset+2, 5200
+iPar4 table ioffset+3, 5200
+
+if iControlType == 1 then
+ kControl lfo iPar1, iPar2, int(iPar3)
+ kControl = kControl+iPar4
+elseif iControlType == 2 then
+ irange = (iPar2-iPar1)*.5
+ kControl randi irange, iPar3, iPar4-.001, 0, irange+iPar1
+elseif iControlType == 3 then
+ kControl adsr iPar1*idur+.0001, iPar2*idur, iPar3, iPar4*idur
+elseif iControlType == 4 then
+ if iPar3 == 0 then
+ kControl1 = ((gkTrackpadX+1)*.5)*(iPar2-iPar1)+iPar1
+ elseif iPar3 == 1 then
+ kval = (gkTrackpadX+1)*.5
+ kControl1 pow kval, 2
+ kControl1 = kControl1 * (iPar2-iPar1) + iPar1
+ endif
+ if iPar4 == 0 then
+ kControl = kControl1
+ else
+ ktrig oscil 1, 1/iPar4, 45
+ kControl samphold kControl1, ktrig, i(kControl1), 0
+ endif
+elseif iControlType == 5 then
+ if iPar3 == 0 then
+ kControl1 = ((gkTrackpadY+1)*.5)*(iPar2-iPar1)+iPar1
+ elseif iPar3 == 1 then
+ kval = (gkTrackpadY+1)*.5
+ kControl1 pow kval, 2
+ kControl1 = kControl1 * (iPar2-iPar1) + iPar1
+ endif
+ if iPar4 == 0 then
+ kControl = kControl1
+ else
+ ktrig oscil 1, 1/iPar4, 45
+ kControl samphold kControl1, ktrig, i(kControl1), 0
+ endif
+endif
+
+xout kControl
+
+nocontrol:
+endop
+
+opcode source, a, ii
+iSourceNum, ipitch xin
+
+iSourceType table iSourceNum+3, 5203
+
+if iSourceType == 0 then
+goto nosource
+endif
+
+ioffset = (iSourceNum-1)*4
+kpara1 zkr ioffset+1
+kpara2 zkr ioffset+2
+kpara3 zkr ioffset+3
+kpara4 zkr ioffset+4
+
+iPar1 table ioffset, 5201
+iPar2 table ioffset+1, 5201
+iPar3 table ioffset+2, 5201
+iPar4 table ioffset+3, 5201
+
+if iSourceType == 1 then
+ aSource foscil 2000*kpara4, ipitch, kpara1, kpara2, kpara3, 1
+elseif iSourceType == 2 then
+ aSource gbuzz 5000*kpara4, ipitch*kpara1, int(abs(kpara2))+5, 0, kpara3+0.01, 2
+elseif iSourceType == 3 then
+ iPar2 = int(iPar2)
+ if iPar2 == 0 then
+ imode = 0
+ elseif iPar2 == 1 then
+ imode = 10
+ elseif iPar2 == 2 then
+ imode = 12
+ endif
+ aSource vco2 2000*kpara4, ipitch*kpara1, imode, 0.1, 0, iPar3
+elseif iSourceType == 4 then
+ if iPar3 == 0 then
+ kvib = 0
+ goto novib
+ else
+ kvibenv linseg 0, .3, 1, p3-.3, 1
+ kvib oscil ipitch*.015, kpara3, 1
+ endif
+ novib:
+ aSource pluck 5000*kpara4, ipitch*(abs(kpara1))+.001+kvib, 40, 0, 6
+ aSource butterlp aSource, kpara2
+elseif iSourceType == 5 then
+ if int(iPar1) == 0 then
+ ar rand 5000*kpara4
+ elseif int(iPar1) == 1 then
+ ar pinkish 5000*kpara4
+ elseif int(iPar1) == 2 then
+ ar gauss 5000*kpara4
+ endif
+ knoisebandwith limit abs(kpara3), 1, sr/2
+ aSource butterbp ar, kpara2, knoisebandwith
+ aSource balance aSource, ar
+elseif iSourceType == 6 then
+ iSndpitch = p4/261.626
+ iLoopIndex = iPar2 * 3
+ ils table iLoopIndex, 5755
+ ile table iLoopIndex+1, 5755
+ icd table iLoopIndex+2, 5755
+ if ile == 0 then
+ ile = nsamp(5000+iPar2) * giScale - .01
+ endif
+ if icd == 0 then
+ icd = .01
+ endif
+ aSource flooper2 kpara4*.4, iSndpitch*abs(kpara1), ils, ile, icd, 5000+iPar2
+ aSource butterlp aSource, abs(kpara3)
+elseif iSourceType == 7 then
+ kvoy = int(kpara2*3)
+ kform1 table kvoy, 4
+ kform2 table kvoy+1, 4
+ kform3 table kvoy+2, 4
+ kform1 port kform1, .1, 500
+ kform2 port kform2, .1, 1500
+ kform3 port kform3, .1, 2500
+ kvibadev randomi -.0852, .0152, .5
+ kvibfdev randomi -.032, .032, .5
+ kvibfreqrand randomi kpara3-.75, kpara3+.75, .2
+ kvibfatt linseg 0, .3, 1, p3-.3, 1
+ kvib oscili (1+kvibadev)*kvibfatt, (kvibfreqrand+kvibfdev), 1
+ kharm randomi 40, 50, 1.34
+ kmul randomi .80, .84, 1.45
+ kbam randomi 480., 510., 2.07
+ kfunddev randomi -.0053, .0052, 1.05
+ ar gbuzz kbam, (p4*kpara1*(1+kfunddev)+kvib), int(kharm), 0, kmul, 2
+ a1 resonx ar, kform1, 140, 2, 1
+ a2 resonx ar, kform2, 180, 2, 1
+ a3 resonx ar, kform3, 220, 2 , 1
+ aSource = ((a1*80)+(a2*55)+(a3*40))*kpara4
+elseif iSourceType == 8 then
+ iSndPitch = p4/261.626
+ igrdur = .1
+ itable = 5000+iPar2
+ irealTable = 5500 + iSourceNum
+ itabdur = nsamp(itable)
+ ifreq = 1 / igrdur
+ kamp = kpara4 * .2
+ aindex upsamp abs(kpara3) * itabdur
+ atrans upsamp kpara1 * igrdur * iSndPitch
+
+ as1 synthGrain aindex, atrans, ifreq, 0.82, irealTable, itabdur
+ as2 synthGrain aindex, atrans, ifreq, .58, irealTable, itabdur
+ as3 synthGrain aindex, atrans, ifreq, .41, irealTable, itabdur
+ as4 synthGrain aindex, atrans, ifreq, 0.19, irealTable, itabdur
+ as5 synthGrain aindex, atrans, ifreq, 0, irealTable, itabdur
+ aSource = (as1+as2+as3+as4+as5)*kamp
+ aSource butterlp aSource, 7500
+elseif iSourceType == 9 then
+ aSource homeSine p4*kpara1, kpara2*0.1, iPar3+30
+ aSource = aSource*kpara4
+
+endif
+
+aSource dcblock aSource
+xout aSource
+
+nosource:
+endop
+
+opcode effects, a, ii
+iFxNum, ipitch xin
+
+iFxType table iFxNum+7, 5203
+
+if iFxType == 0 then
+goto nofx
+endif
+
+as1 zar iFxNum
+as2 zar iFxNum+4
+as = as1+as2
+
+ioffset = (iFxNum+3)*4
+kpara1 zkr ioffset+1
+kpara2 zkr ioffset+2
+kpara3 zkr ioffset+3
+kpara4 zkr ioffset+4
+
+ioffset2 = (iFxNum-1)*4
+iPar1 table ioffset2, 5202
+iPar2 table ioffset2+1, 5202
+iPar3 table ioffset2+2, 5202
+iPar4 table ioffset2+3, 5202
+
+if iFxType == 1 then
+ kwgfeed limit kpara3, 0, 1
+ aFx wguide1 as, abs(kpara1)+1, kpara2, kwgfeed
+ aFx = aFx*kpara4
+elseif iFxType == 2 then
+ aFx lpf18 as*.0005, abs(kpara1)+20, kpara2, kpara3
+ aFx = aFx*5000*kpara4
+elseif iFxType == 3 then
+ aFx bqrez as*kpara4, abs(kpara1)+20, abs(kpara2)+1, int(iPar3)
+ aFx balance aFx, as*kpara4
+elseif iFxType == 4 then
+ amod lfo 1, kpara1, int(iPar3)
+ aFx = ((as*amod*kpara2)+(as*(1-kpara2)))*kpara4
+elseif iFxType == 5 then
+ ain = as*kpara4
+ krevLength limit kpara1, 0.01, 10
+ arev reverb ain, krevLength
+ arev butterlp arev, kpara2
+ aFx = (arev*kpara3)+(as*(1-kpara3))
+elseif iFxType == 6 then
+ fsig pvsanal as, 1024, 256, 1024, 1
+ ftps1 pvscale fsig, kpara1
+ aFx pvsynth ftps1
+ adry delay as, iPar2
+ aFx = ((aFx*kpara3)+(adry*(1-kpara3)))*kpara4
+elseif iFxType == 7 then
+ aeq1 butterbp as, 700, 400
+ aeq2 butterbp as, 1500, 600
+ aeq3 butterbp as, 3000, 1000
+ aeq4 butterbp as, 5000, 2000
+ aFx = (aeq1*kpara1)+(aeq2*kpara2)+(aeq3*kpara3)+(aeq4*kpara4)
+elseif iFxType == 8 then
+ afeed init 0
+ adel oscil kpara1, kpara2, 1
+ adel = adel + kpara1 + kpara3
+ adel limit adel, 0, 50
+ aFx vdelay as+afeed, adel, 50
+ afeed = aFx * kpara4
+endif
+
+xout aFx
+
+nofx:
+endop
+
+
+/****************************************************************
+Reverb + master out
+*****************************************************************/
+instr 200
+
+gktime timek
+
+kTrackpadX chnget "trackpadX"
+gkTrackpadX = kTrackpadX / 600.
+gkTrackpadX limit gkTrackpadX, -1, 1
+
+kTrackpadY chnget "trackpadY"
+gkTrackpadY = kTrackpadY / 450.
+gkTrackpadY limit -gkTrackpadY, -1, 1
+
+koutGain chnget "masterVolume"
+koutGain = koutGain * 0.02
+gkduck init 1
+gkduck port gkduck, .03, 1.
+
+ain dcblock gainrev*0.05
+arev reverb ain, 2.5
+arev butterlp arev, 5000
+
+aLeft butterlp gaoutL, 7500
+aRight butterlp gaoutR, 7500
+
+aOutLeft dcblock (arev + aLeft) * koutGain * gkduck
+aOutRight dcblock (arev + aRight) * koutGain * gkduck
+gaRecL = aOutLeft
+gaRecR = aOutRight
+ outs aOutLeft, aOutRight
+
+ gaoutL = 0
+ gaoutR = 0
+ gainrev = 0
+
+endin
+
+/****************************************************************
+ducking
+****************************************************************/
+instr 5600
+gkduck linseg 1., 0.005, 0.05, 3.9, 0.05, 0.095, 1
+endin
+
+/****************************************************************
+Performance recording start
+*****************************************************************/
+instr 5400
+Sname strcpy "/home/olpc/.sugar/default/tamtam/perf.wav"
+ihandle fiopen Sname, 2
+fout Sname, 2, gaRecL, gaRecR
+clear gaRecL, gaRecR
+endin
+
+/****************************************************************
+Performance recording stop ( closing file )
+*****************************************************************/
+instr 5401
+Sname strcpy "/home/olpc/.sugar/default/tamtam/perf.wav"
+turnoff2 5400, 8, 0
+ficlose Sname
+endin
+
+/****************************************************************
+Handler audio input recording
+****************************************************************/
+instr 5201
+
+ktim timeinsts
+
+gkduck = .05
+itab = p4
+ain inch 1
+krms rms ain
+ktrig trigger krms, 1500, 0
+
+if ktrig == 1 then
+event "i", 5202, 0 , 1, itab
+turnoff
+endif
+
+ithresh = p3 - 1
+
+if ktim > ithresh then
+gkduck linseg .05, .8, .05, .2, 1
+endif
+
+endin
+
+/****************************************************************
+Audio input recording
+****************************************************************/
+instr 5202
+kenv adsr 0.005, 0.05, .9, 0.01
+gkduck linseg .05, .8, .05, .2, 1
+ain inch 1
+
+adel delay ain, .01
+
+Sname sprintf "/home/olpc/.sugar/default/tamtam/snds/mic%d", int(p4)-6
+ihandle fiopen Sname, 2
+event "i", 5212, 1 , .01, p4
+
+fout Sname, 2, adel*kenv
+adel = 0
+endin
+
+/****************************************************************
+Audio input recording ( closing file )
+****************************************************************/
+instr 5212
+Sname sprintf "/home/olpc/.sugar/default/tamtam/snds/mic%d", int(p4)-6
+ficlose Sname
+endin
+
+/****************************************************************
+SynthLab input recording
+****************************************************************/
+instr 5204
+
+Sname2 sprintf "/home/olpc/.sugar/default/tamtam/snds/lab%d", int(p4)-85
+fout Sname2, 2, gasynth * 0.707
+clear gasynth
+endin
+
+/************************
+TamTam's SynthLab instrument
+************************/
+instr 5203
+
+if p5 != 0 then
+event_i "i", 5204, 0, p3, p5
+endif
+
+aSource1 init 0
+aSource2 init 0
+aSource3 init 0
+aSource4 init 0
+aFx1 init 0
+aFx2 init 0
+aFx3 init 0
+aFx4 init 0
+aout init 0
+
+ipitch = p4
+
+kc1 controller 1,p3
+kc2 controller 2,p3
+kc3 controller 3,p3
+kc4 controller 4,p3
+
+is1p1 ControlMatrice 5201, 0, kc1, kc2, kc3, kc4
+is1p2 ControlMatrice 5201, 1, kc1, kc2, kc3, kc4
+is1p3 ControlMatrice 5201, 2, kc1, kc2, kc3, kc4
+is1p4 ControlMatrice 5201, 3, kc1, kc2, kc3, kc4
+is2p1 ControlMatrice 5201, 4, kc1, kc2, kc3, kc4
+is2p2 ControlMatrice 5201, 5, kc1, kc2, kc3, kc4
+is2p3 ControlMatrice 5201, 6, kc1, kc2, kc3, kc4
+is2p4 ControlMatrice 5201, 7, kc1, kc2, kc3, kc4
+is3p1 ControlMatrice 5201, 8, kc1, kc2, kc3, kc4
+is3p2 ControlMatrice 5201, 9, kc1, kc2, kc3, kc4
+is3p3 ControlMatrice 5201, 10, kc1, kc2, kc3, kc4
+is3p4 ControlMatrice 5201, 11, kc1, kc2, kc3, kc4
+is4p1 ControlMatrice 5201, 12, kc1, kc2, kc3, kc4
+is4p2 ControlMatrice 5201, 13, kc1, kc2, kc3, kc4
+is4p3 ControlMatrice 5201, 14, kc1, kc2, kc3, kc4
+is4p4 ControlMatrice 5201, 15, kc1, kc2, kc3, kc4
+
+aSource1 source 1, ipitch*2
+aSource2 source 2, ipitch*2
+aSource3 source 3, ipitch*2
+aSource4 source 4, ipitch*2
+
+ifx1p1 ControlMatrice 5202, 0, kc1, kc2, kc3, kc4
+ifx1p2 ControlMatrice 5202, 1, kc1, kc2, kc3, kc4
+ifx1p3 ControlMatrice 5202, 2, kc1, kc2, kc3, kc4
+ifx1p4 ControlMatrice 5202, 3, kc1, kc2, kc3, kc4
+ifx2p1 ControlMatrice 5202, 4, kc1, kc2, kc3, kc4
+ifx2p2 ControlMatrice 5202, 5, kc1, kc2, kc3, kc4
+ifx2p3 ControlMatrice 5202, 6, kc1, kc2, kc3, kc4
+ifx2p4 ControlMatrice 5202, 7, kc1, kc2, kc3, kc4
+ifx3p1 ControlMatrice 5202, 8, kc1, kc2, kc3, kc4
+ifx3p2 ControlMatrice 5202, 9, kc1, kc2, kc3, kc4
+ifx3p3 ControlMatrice 5202, 10, kc1, kc2, kc3, kc4
+ifx3p4 ControlMatrice 5202, 11, kc1, kc2, kc3, kc4
+ifx4p1 ControlMatrice 5202, 12, kc1, kc2, kc3, kc4
+ifx4p2 ControlMatrice 5202, 13, kc1, kc2, kc3, kc4
+ifx4p3 ControlMatrice 5202, 14, kc1, kc2, kc3, kc4
+ifx4p4 ControlMatrice 5202, 15, kc1, kc2, kc3, kc4
+
+ifx1in SourceMatrice 1, aSource1, aSource2, aSource3, aSource4
+ifx2in SourceMatrice 2, aSource1, aSource2, aSource3, aSource4
+ifx3in SourceMatrice 3, aSource1, aSource2, aSource3, aSource4
+ifx4in SourceMatrice 4, aSource1, aSource2, aSource3, aSource4
+
+ifx1in1 FxMatrice 5, aFx1, aFx2, aFx3, aFx4
+ifx2in1 FxMatrice 6, aFx1, aFx2, aFx3, aFx4
+ifx3in1 FxMatrice 7, aFx1, aFx2, aFx3, aFx4
+ifx4in1 FxMatrice 8, aFx1, aFx2, aFx3, aFx4
+
+aFx1 effects 1, ipitch
+aFx2 effects 2, ipitch
+aFx3 effects 3, ipitch
+aFx4 effects 4, ipitch
+
+iSourceOut1 table 8, 5206
+iSourceOut2 table 9, 5206
+iSourceOut3 table 10, 5206
+iSourceOut4 table 11, 5206
+iFxOut1 table 12, 5206
+iFxOut2 table 13, 5206
+iFxOut3 table 14, 5206
+iFxOut4 table 15, 5206
+
+aout = (aSource1*iSourceOut1)+(aSource2*iSourceOut2)+(aSource3*iSourceOut3)+(aSource4*iSourceOut4)+(aFx1*iFxOut1)+(aFx2*iFxOut2)+(aFx3*iFxOut3)+(aFx4*iFxOut4)
+
+kenv adsr p3*p6+0.001, p3*p7, p8, p3*p9
+aout = aout*kenv
+
+vincr gasynth, aout
+
+ outs aout, aout
+
+zacl 0, 8
+
+endin
+
+/***********************
+DELETE RESOURCES
+************************/
+
+instr 5000
+
+icount init 0
+
+again:
+ftfree 5000+icount, 0
+icount = icount+1
+
+if icount < p4 goto again
+
+turnoff
+
+endin
+
+/*************************
+Loop points editor
+*************************/
+instr 5022
+
+kstart chnget "lstart"
+kend chnget "lend"
+kdur chnget "ldur"
+
+idurfadein init 0.005
+idurfadeout init 0.095
+iampe0 init 1
+iampe1 init 1
+iampe2 init 1
+
+itie tival
+if itie == 1 igoto nofadein
+
+iampe0 init 0
+iskip = 1
+
+nofadein:
+iskip = 0
+igliss = 0.005
+
+if p3 < 0 igoto nofadeout
+
+iampe2 init 0
+
+nofadeout:
+
+idelta = idurfadein+idurfadeout
+if idelta > abs(p3) then
+idelta = abs(p3)
+endif
+
+iampe0 = iampe0
+iampe2 = iampe2
+kenv linseg iampe0, idurfadein, iampe1, abs(p3)-idelta, iampe1, idurfadeout, iampe2
+
+
+ivibRand random 4.1, 5.7
+
+kvibrato oscil .006, ivibRand, 1
+
+ tigoto tieskip
+
+a1 flooper2 1, 1+kvibrato, kstart, kend, kdur, 4999, 0, 0, 0, iskip
+
+a1 = a1*kenv
+
+gaoutL = a1*0.5+gaoutL
+gaoutR = a1*0.5+gaoutR
+
+gainrev = a1*0.1+gainrev
+
+ tieskip:
+endin
+
+/*************************
+Loop points editor, simple player
+*************************/
+instr 5023
+
+p3 = nsamp(4999) * giScale
+
+a1 loscil 1, 1, 4999, 1
+
+kenv adsr 0.005, 0.05, .8, 0.1
+
+a1 = a1*kenv
+
+gaoutL = a1*0.5+gaoutL
+gaoutR = a1*0.5+gaoutR
+
+gainrev = a1*0.1+gainrev
+
+endin
+
+/****************************************************************
+Soundfile player with miniTamTam's tied notes
+****************************************************************/
+/*************************
+pitch, reverbGain, amp, pan, table, att, dec, filtType, cutoff, loopstart, loopend, crossdur
+*************************/
+instr 5001, 5002, 5003, 5004, 5005, 5006, 5007, 5008, 5009, 5010
+
+idump = p16
+idump2 = p17
+idump3 = p18
+idump4 = p19
+
+iTrackId = int(p1-5001)
+SvolTrackName sprintf "trackVolume%0d", iTrackId
+kvol chnget SvolTrackName
+kvol = kvol * 0.01
+kvol port kvol, .01, i(kvol)
+
+idurfadein init 0.005
+idurfadeout init 0.095
+iampe0 init 1
+iampe1 = p6
+iampe2 init 1
+
+itie tival
+if itie == 1 igoto nofadein
+
+idurfadein init p9
+iampe0 init 0
+iskip = 1
+kpitch init p4
+kamp init p6
+kpan init p7
+krg init p5
+
+nofadein:
+iskip = 0
+igliss = 0.005
+
+if p3 < 0 igoto nofadeout
+
+idurfadeout init p10
+iampe2 init 0
+
+nofadeout:
+
+idelta = idurfadein+idurfadeout
+if idelta > abs(p3) then
+idelta = abs(p3)
+endif
+
+iampe0 = iampe0 * p6
+iampe2 = iampe2 * p6
+kenv linseg iampe0, idurfadein, iampe1, abs(p3)-idelta, iampe1, idurfadeout, iampe2
+
+kpitchBend port gkTrackpadX, .03, i(gkTrackpadX)
+kpitchBend pow kpitchBend + 1, 5
+kampBend port gkTrackpadY, .03, i(gkTrackpadY)
+kampBend pow kampBend + 1, 5
+
+ivibRand random 4.1, 5.7
+
+kvibrato oscil .006*kampBend, ivibRand*kpitchBend, 1
+
+ tigoto tieskip
+
+kpitch portk p4, igliss, p4
+kpan portk p7, igliss, p7
+krg portk p5, igliss, p5
+kcutoff portk p12, igliss, p12
+kls portk p13, igliss, p13
+kle portk p14, igliss, p14
+kcd portk p15, igliss, p15
+
+a1 flooper2 1, kpitch+kvibrato, kls, kle, kcd, p8, 0, 0, 0, iskip
+
+if (p11-1) != -1 then
+acomp = a1
+a1 bqrez a1, kcutoff, 6, p11-1
+a1 balance a1, acomp
+endif
+
+if kpitch < 1 then
+kalias = giAliasSr*kpitch
+else
+kalias = giAliasSr
+endif
+
+a1 tone a1, kalias
+
+a1 = a1*kenv*kvol
+
+gaoutL = a1*(1-kpan)+gaoutL
+gaoutR = a1*kpan+gaoutR
+
+gainrev = a1*krg+gainrev
+
+ tieskip:
+endin
+
+
+/*************************
+Soundfile player with edit's looped notes
+*************************/
+instr 5101, 5102, 5103, 5104, 5105, 5106, 5107, 5108, 5109, 5110
+
+if p16 != -1 then
+ inum = frac(p16) * 10000
+ itable2 = int(p16)
+ event_i "i", inum, 0, p3, p4, p5, p6, p7, itable2, p9, p10, p11, p12, p17, p18, p19, -1
+endif
+
+ipitch random p4*.995, p4*1.005
+
+iTrackId = int(p1-5101)
+SvolTrackName2 sprintf "trackVolume%0d", iTrackId
+kvol chnget SvolTrackName2
+kvol = kvol * 0.01
+kvol port kvol, .01, 0 ;i(kvol)
+
+ivibRand random 4.1, 5.7
+
+kvibrato oscil .006, ivibRand, 1
+
+a1 flooper2 1, ipitch+kvibrato, p13, p14, p15, p8, 0, 0, 0
+
+if (p11-1) != -1 then
+acomp = a1
+a1 bqrez a1, p12, 6, p11-1
+a1 balance a1, acomp
+endif
+
+;if p4 < 1 then
+;ialias = giAliasSr*p4
+;else
+;ialias = giAliasSr
+;endif
+
+;a1 tone a1, ialias
+
+aenv adsr p9, 0.005, p6, p10
+a1 = a1*aenv*kvol
+
+gaoutL = a1*(1-p7)+gaoutL
+gaoutR = a1*p7+gaoutR
+
+gainrev = a1*p5+gainrev
+
+endin
+
+/**************************************************************
+Simple soundfile player (miniTamTam)
+**************************************************************/
+
+instr 5011, 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5020
+
+idump = p16
+idump2 = p17
+idump3 = p18
+idump4 = p19
+
+iTrackId = int(p1-5011)
+SvolTrackName3 sprintf "trackVolume%0d", iTrackId
+kvol chnget SvolTrackName3
+kvol = kvol * 0.01
+kvol port kvol, .01
+
+p3 = nsamp(p8) * giScale / p4
+
+a1 loscil p6, p4, p8, 1
+
+if (p11-1) != -1 then
+acomp = a1
+a1 bqrez a1, p12, 6, p11-1
+a1 balance a1, acomp
+endif
+
+if p4 < 1 then
+ialias = giAliasSr*p4
+else
+ialias = giAliasSr
+endif
+
+a1 tone a1, ialias
+
+kenv adsr p9, 0.05, .8, p10
+a1 = a1*kenv*kvol
+
+gaoutL = a1*(1-p7)+gaoutL
+gaoutR = a1*p7+gaoutR
+
+gainrev = a1*p5+gainrev
+
+endin
+
+/**************************************************************
+Simple soundfile player (Edit)
+**************************************************************/
+
+instr 5111, 5112, 5113, 5114, 5115, 5116, 5117, 5118, 5119, 5120
+
+if p16 != -1 then
+ inum = frac(p16) * 10000
+ itable2 = int(p16)
+ event_i "i", inum, 0, p3, p4, p5, p6, p7, itable2, p9, p10, p11, p12, p17, p18, p19, -1
+endif
+
+iTrackId = int(p1-5111)
+SvolTrackName4 sprintf "trackVolume%0d", iTrackId
+kvol chnget SvolTrackName4
+kvol = kvol * 0.01
+kvol port kvol, .01
+
+a1 loscil p6, p4, p8, 1
+
+if (p11-1) != -1 then
+acomp = a1
+a1 bqrez a1, p12, 6, p11-1
+a1 balance a1, acomp
+endif
+
+;if p4 < 1 then
+;ialias = giAliasSr*p4
+;else
+;ialias = giAliasSr
+;endif
+
+;a1 tone a1, ialias
+
+kenv adsr p9, 0.05, .8, p10
+
+a1 = a1*kenv*kvol
+
+gaoutL = a1*(1-p7)+gaoutL
+gaoutR = a1*p7+gaoutR
+
+gainrev = a1*p5+gainrev
+
+endin
+
+
+
+/********************************************************************
+soundfile player for percussion - resonance notes
+********************************************************************/
+instr 5021
+
+a1 flooper2 1, p4, .25, .750, .2, p8
+
+if (p11-1) != -1 then
+acomp = a1
+a1 bqrez a1, p12, 6, p11-1
+a1 balance a1, acomp
+endif
+
+kenv expseg 0.001, .003, .6, p3 - .003, 0.001
+klocalenv adsr p8, 0.05, .8, p10
+
+a1 = a1*kenv*klocalenv
+
+gaoutL = a1*(1-p7)+gaoutL
+gaoutR = a1*p7+gaoutR
+
+gainrev = a1*p5+gainrev
+
+endin
+
+
+
+</CsInstruments>
+<CsScore>
+f1 0 8192 10 1
+f2 0 8192 11 1 1
+
+f4 0 32 -2 250 2250 2980 420 2050 2630 590 1770 2580
+ 750 1450 2590 290 750 2300 360 770 2530 520 900 2510 710 1230 2700 570 1560 2560 0 0 0 0 0
+f30 0 1024 10 1 0 .3 0 .1
+f31 0 1024 10 1 .5 .3 .25 .1
+f32 0 1024 10 1 0 .1 0 .3 .2 0 0 .1
+f33 0 1024 10 1 0 0 0 .1 0 0 .2 .1 0 0 .1
+f34 0 1024 10 1 .6 0 0 .4 .2 .1 0 0 .1
+f35 0 1024 10 1 .5 .3 0 .1 0 0 0 .1 .1
+f36 0 1024 10 1 0 .6 .4 .1 0 0 .2 .1 0 0 ,1
+f37 0 1024 10 1 0 0 0 .1 .2 .1 0 0 0 .1 0 0 .1
+f38 0 1024 10 1 .4 .3 0 .1 .2 .1 .1 .1 0 0 0 0 .1 .05
+f39 0 1024 10 1 0 .5 0 0 .3 0 0 .2 0 .1 0 0 0 0 .2 0 0 0 .05 0 0 0 0 .03 ; ADDITIVE SYNTHESIS WAVE
+f41 0 8193 19 .5 .5 270 .5 ; SIGMOID FUNCTION
+f42 0 8192 -20 2 1
+f44 0 8192 5 1 8192 0.001 ; EXPONENTIAL FUNCTION
+f45 0 512 7 0 500 0 2 1 10 1
+f5150 0 32768 7 0 32768 0
+i200 0 600000
+</CsScore>
+</CsoundSynthesizer>
diff --git a/common/Resources/tooltips_en.py b/common/Resources/tooltips_en.py
new file mode 100644
index 0000000..e59e88d
--- /dev/null
+++ b/common/Resources/tooltips_en.py
@@ -0,0 +1,128 @@
+from gettext import gettext as _
+
+class Tooltips:
+ def __init__(self):
+ # Edit
+ self.Edit = {}
+ # tools
+ self.Edit["2toolPointerButton"] = _('Select tool')
+ self.Edit["2toolPencilButton"] = _('Draw tool')
+ self.Edit["2toolBrushButton"] = _('Paint tool')
+ # create tune
+ self.Edit["2generateBtn"] = _('Generate new tune')
+ # page
+ self.Edit["2pageGenerateButton"] = _('Generate page')
+ self.Edit["2pagePropertiesButton"] = _('Page properties')
+ self.Edit["2pageDeleteButton"] = _('Delete page(s)')
+ self.Edit["2pageDuplicateButton"] = _('Duplicate page(s)')
+ self.Edit["2pageNewButton"] = _('Add page')
+ self.Edit["2pageBeatsButton"] = _('Beats per page')
+ self.Edit["2saveButton"] = _('Save tune')
+ self.Edit["2loadButton"] = _('Load tune')
+ # track
+ self.Edit["2trackGenerateButton"] = _('Generate track')
+ self.Edit["2trackPropertiesButton"] = _('Track properties')
+ self.Edit["2trackDeleteButton"] = _('Clear track')
+ self.Edit["2trackDuplicateButton"] = _('Duplicate track')
+ # note
+ self.Edit["2notePropertiesButton"] = _('Note(s) properties')
+ self.Edit["2noteDeleteButton"] = _('Delete note(s)')
+ self.Edit["2noteDuplicateButton"] = _('Duplicate note(s)')
+ self.Edit["2noteOnsetMinusButton"] = _('Move note in time')
+ self.Edit["2noteOnsetPlusButton"] = _('Move note in time')
+ self.Edit["2notePitchMinusButton"] = _('Lower pitch')
+ self.Edit["2notePitchPlusButton"] = _('Raise pitch')
+ self.Edit["2noteDurationMinusButton"] = _('Modify duration')
+ self.Edit["2noteDurationPlusButton"] = _('Modify duration')
+ self.Edit["2noteVolumeMinusButton"] = _('Lower volume')
+ self.Edit["2noteVolumePlusButton"] = _('Raise volume')
+ # transport
+ self.Edit["2playButton"] = _('Play')
+ self.Edit["2pauseButton"] = _('Pause')
+ self.Edit["2stopButton"] = _('Stop')
+ self.Edit["2keyRecordButton"] = _('Keyboard recording')
+ self.Edit["2recordButton"] = _('Save as .ogg')
+ self.Edit["2rewindButton"] = _('Rewind')
+ self.Edit["2closeButton"] = _('Save to journal and quit')
+ # volume and tempo
+ self.Edit["2volumeSlider"] = _('Master volume')
+ self.Edit["2tempoSlider"] = _('Tempo')
+ #InstrumentBox
+ self.Edit["2instrument1muteButton"] = _("Left click to mute, right click to solo")
+ self.Edit["2instrument2muteButton"] = _("Left click to mute, right click to solo")
+ self.Edit["2instrument3muteButton"] = _("Left click to mute, right click to solo")
+ self.Edit["2instrument4muteButton"] = _("Left click to mute, right click to solo")
+ self.Edit["2drumMuteButton"] = _("Left click to mute, right click to solo")
+
+ self.ALGO = {}
+ self.ALGO["XYButton1"] = _('-- Rythm density, | Rythm regularity' )
+ self.ALGO["XYButton2"] = _('-- Pitch regularity, | Pitch maximum step' )
+ self.ALGO["XYButton3"] = _('-- Average duration, | Silence probability')
+ self.ALGO["drunk"] = _('Drunk')
+ self.ALGO["droneJump"] = _('Drone and Jump')
+ self.ALGO["repeat"] = _('Repeater')
+ self.ALGO["loopSeg"] = _('Loop segments')
+ self.ALGO["majorKey"] = _('Major scale')
+ self.ALGO["minorHarmKey"] = _('Harmonic minor scale')
+ self.ALGO["minorKey"] = _('Natural minor scale')
+ self.ALGO["phrygienKey"] = _('Phrygian scale')
+ self.ALGO["dorienKey"] = _('Dorian scale')
+ self.ALGO["lydienKey"] = _('Lydian scale')
+ self.ALGO["myxoKey"] = _('Myxolydian scale')
+ self.ALGO["saveButton"] = _('Save preset')
+ self.ALGO["loadButton"] = _('Load preset')
+ self.ALGO["checkButton"] = _('Generate')
+ self.ALGO["cancelButton"] = _('Close')
+
+ self.PROP = {}
+ self.PROP['pitchUp'] = _('Transpose up')
+ self.PROP['pitchDown'] = _('Transpose down')
+ self.PROP['volumeUp'] = _('Volume up')
+ self.PROP['volumeDown'] = _('Volume down')
+ self.PROP['panSlider'] = _('Panoramisation')
+ self.PROP['reverbSlider'] = _('Reverb')
+ self.PROP['attackSlider'] = _('Attack duration')
+ self.PROP['decaySlider'] = _('Decay duration')
+ self.PROP['filterTypeLowButton'] = _('Lowpass filter')
+ self.PROP['filterTypeHighButton'] = _('Highpass filter')
+ self.PROP['filterTypeBandButton'] = _('Bandpass filter')
+ self.PROP['cutoffSlider'] = _('Filter cutoff')
+ self.PROP['pitchGen'] = _('Open algorithmic generator')
+ self.PROP['volumeGen'] = _('Open algorithmic generator')
+ self.PROP['panGen'] = _('Open algorithmic generator')
+ self.PROP['reverbGen'] = _('Open algorithmic generator')
+ self.PROP['attackGen'] = _('Open algorithmic generator')
+ self.PROP['decayGen'] = _('Open algorithmic generator')
+ self.PROP['cutoffGen'] = _('Open algorithmic generator')
+ self.PROP['line'] = _('Line')
+ self.PROP['drunk'] = _('Drunk')
+ self.PROP['droneJump'] = _('Drone and jump')
+ self.PROP['repeater'] = _('Repeater')
+ self.PROP['loopseg'] = _('Loop segments')
+ self.PROP['minSlider'] = _('Minimum value')
+ self.PROP['maxSlider'] = _('Maximum value')
+ self.PROP['paraSlider'] = _('Specific parameter')
+ self.PROP['checkButton'] = _('Apply generator')
+ self.PROP['cancelButton'] = _('Cancel')
+
+
+
+ #miniTamTam
+ VOL = _('Volume')
+ BAL = _('Balance')
+ REV = _('Reverb')
+ PLAY = _('Play / Stop')
+ STOP = _('Stop')
+ SEQ = _('Left click to record, right click to record on top')
+ GEN = _('Generate')
+ COMPL = _('Complexity of beat')
+ BEAT = _('Beats per bar')
+ TEMPO = _('Tempo')
+ JAZZ = _('Jazz / Rock Kit')
+ AFRI = _('African Kit')
+ ARAB = _('Arabic Kit')
+ BRES = _('South American Kit')
+ ELEC = _('Electronic Kit')
+ RECMIC = _('Record with the microphone')
+ RECLAB = _('Open SynthLab to create noise')
+ MT_RECORDBUTTONS = [_('Record mic into slot 1'), _('Record mic into slot 2'), _('Record mic into slot 3'), _('Record mic into slot 4')]
diff --git a/common/Resources/tooltips_fr.py b/common/Resources/tooltips_fr.py
new file mode 100644
index 0000000..e16ea53
--- /dev/null
+++ b/common/Resources/tooltips_fr.py
@@ -0,0 +1,153 @@
+class Tooltips:
+ #miniTamTam
+ VOL = 'Volume'
+ REV = 'Reverb'
+ PLAY = 'Play / Stop'
+ STOP = 'Stop'
+ SEQ = 'Sequencer'
+ GEN = 'Generate'
+ COMPL = 'Complexity du beat'
+ BEAT = 'Beats per bar'
+ TEMPO = 'Tempo'
+ JAZZ = 'Jazz / Rock Kit'
+ AFRI = 'African Kit'
+ ARAB = 'Arabic Kit'
+ RECMIC = 'Record avec le microphone'
+ RECLAB = 'Open SynthLab to create bruits'
+
+ #Synthlab
+ SOURCE = 'Source'
+ EFFECT = 'Effect'
+ CONTROL = 'Control'
+ SOUNDOUT = 'Sound Output'
+ SOUNDDUR = 'Sound Duration'
+ SAVE = 'Save'
+ LOAD = 'Load'
+ SAVEMINI = 'Save to miniTamTam'
+ CLOSE = 'Close'
+ RESET = 'Reset'
+
+ #Controls
+ LFO = 'LFO'
+ AMP = 'Amplitude'
+ FREQ = 'Frequency'
+ WAVEFORM = 'Waveform'
+ LFO_WAVEFORMS = ['Sine', 'Triangle', 'Bi-Square', 'Uni-Square', 'Sawtooth', 'Sawtooth-down']
+ OFFSET = 'Offset'
+
+ RANDOM = 'Random'
+ MIN = 'Minimum'
+ MAX = 'Maximum'
+ FREQ = FREQ
+ SEED = 'Seed'
+
+ ADSR = 'Envelope'
+ ATTACK = 'Attack'
+ DECAY = 'Decay'
+ SUSTAIN = 'Sustain'
+ RELEASE = 'Release'
+
+ #Source
+ FM = 'Fequency Modulator'
+ CAR = 'Carrier Frequency'
+ MOD = 'Modulator Frequency'
+ INDEX = 'Index'
+ GAIN = 'Gain'
+
+ BUZZ = 'Buzz'
+ FREQ = FREQ
+ NHARM = 'Number of harmonics'
+ FSLOPE = 'Filter Slope'
+ GAIN = GAIN
+
+ VCO = 'Voltage Controlled Oscillator'
+ FREQ = FREQ
+ WAVEFORM = WAVEFORM
+ VCO_WAVEFORMS = ['Sawtooth', 'Square', 'Triangle']
+ FSLOPE = FSLOPE
+ GAIN = GAIN
+
+ PLUCK = 'Pluck'
+ FREQ = FREQ
+ LFILTER = 'Lowpass Filter'
+ VIBRATO = 'Vibrato'
+ GAIN = GAIN
+
+ NOISE = 'Noise'
+ NOISETYPE = 'Type'
+ NOISE_TYPES = ['White', 'Pink', 'Gauss']
+ FREQ = FREQ
+ BANDWITH = 'Bandwith'
+ GAIN = GAIN
+
+ SAMPLE = 'Sound Sample'
+ FREQ = FREQ
+ SAMPLEN = 'Sample Number'
+ SAMPLE_NAMES = ['some inst'] * 100
+ LFILTER = LFILTER
+ GAIN = GAIN
+
+ VOICE = 'Voice'
+ FREQ = FREQ
+ VOWEL = 'Vowel'
+ VOWEL_TYPES = ['i', 'e', 'ee', 'a', 'u', 'o1', 'o2', 'oa', 'oe']
+ VIBRATO = VIBRATO
+ GAIN = GAIN
+
+ #Effects
+ DELAY = 'Delay'
+ FREQ = FREQ
+ LFILTER = LFILTER
+ FEEDBACK = 'Feedback'
+ GAIN = GAIN
+
+ DIST = 'Distortion'
+ FREQ = FREQ
+ RESON = 'Resonance'
+ DISTL = 'Distotion Level'
+ GAIN = GAIN
+
+ FILTER = 'Filter'
+ FREQ = FREQ
+ FSLOPE = FSLOPE
+ FTYPE = 'Type'
+ FILTER_TYPES = ['Lowpass', 'Highpass', 'Bandpass']
+ GAIN = GAIN
+
+ RINGMOD = 'Ring Modulator'
+ FREQ = FREQ
+ AMP = 'Amplitude'
+ WAVEFORM = WAVEFORM
+ LFO_WAVEFORMS = LFO_WAVEFORMS
+ GAIN = GAIN
+
+ REVERB = 'Reverb'
+ REVERBD = 'Length'
+ REVERBF = 'Lowpass Filter'
+ REVERBL = 'Reverb Level'
+ GAIN = GAIN
+
+ HARMON = 'Harmonizer'
+ FREQ = FREQ
+ DRYDELAY = 'Dry delay'
+ MIX = 'Mix'
+ GAIN = GAIN
+
+ SYNTHTYPES = [[LFO, RANDOM, ADSR], [FM, BUZZ, VCO, PLUCK, NOISE, SAMPLE, VOICE], [DELAY, DIST, FILTER, RINGMOD, REVERB, HARMON], [ADSR]]
+ SYNTHPARA = { 'lfo': [AMP, FREQ, WAVEFORM, OFFSET],
+ 'rand': [MIN, MAX, FREQ, SEED],
+ 'adsr': [ATTACK, DECAY, SUSTAIN, RELEASE],
+ 'fm': [CAR, MOD, INDEX, GAIN],
+ 'buzz': [FREQ, NHARM, FSLOPE, GAIN],
+ 'vco': [FREQ, WAVEFORM, FSLOPE, GAIN],
+ 'pluck': [FREQ, LFILTER, VIBRATO, GAIN],
+ 'noise': [NOISETYPE, FREQ, BANDWITH, GAIN],
+ 'sample': [FREQ, SAMPLEN, LFILTER, GAIN],
+ 'voice': [FREQ, VOWEL, VIBRATO, GAIN],
+ 'wguide': [FREQ, LFILTER, FEEDBACK, GAIN],
+ 'distort': [FREQ, RESON, DISTL, GAIN],
+ 'filter': [FREQ, FSLOPE, FTYPE, GAIN],
+ 'ring': [FREQ, AMP, WAVEFORM, GAIN],
+ 'reverb': [REVERBD, REVERBF, REVERBL, GAIN],
+ 'harmon': [FREQ, DRYDELAY, MIX, GAIN]}
+
diff --git a/common/Util/CSoundClient.py b/common/Util/CSoundClient.py
new file mode 100644
index 0000000..af1124d
--- /dev/null
+++ b/common/Util/CSoundClient.py
@@ -0,0 +1,356 @@
+import os
+import socket
+import select
+import sys
+import threading
+import time
+import array
+
+import common.Config as Config
+
+from common.Generation.GenerationConstants import GenerationConstants
+from common.Util.Clooper.aclient import *
+from common.Util import NoteDB
+
+
+_note_template = array.array('f', [0] * 19 )
+def _new_note_array():
+ return _note_template.__copy__()
+
+def _noteid(dbnote):
+ return (dbnote.page << 16) + dbnote.id
+
+_loop_default=0
+
+class _CSoundClientPlugin:
+
+ #array index constants for csound
+ (INSTR_TRACK, \
+ ONSET, \
+ DURATION, \
+ PITCH,
+ REVERBSEND, \
+ AMPLITUDE, \
+ PAN, \
+ INST_ID, \
+ ATTACK, \
+ DECAY, \
+ FILTERTYPE, \
+ FILTERCUTOFF, \
+ INSTRUMENT2 ) = range(13)
+
+ def __init__(self):
+ sc_initialize( Config.PLUGIN_UNIVORC, Config.PLUGIN_DEBUG,
+ Config.PLUGIN_PERIOD, Config.PLUGIN_NPERIODS,
+ Config.PLUGIN_VERBOSE,
+ Config.PLUGIN_KSMPS, Config.PLUGIN_RATE)
+ self.on = False
+ #self.masterVolume = 80.0
+ self.periods_per_buffer = 2
+ global _loop_default
+ _loop_default = self.loopCreate()
+
+ def __del__(self):
+ self.connect(False)
+ sc_destroy()
+
+ def setChannel(self, name, val):
+ sc_setChannel(name, val)
+
+ def setMasterVolume(self, volume):
+ sc_setChannel( 'masterVolume', volume)
+
+ def setTrackVolume( self, volume, trackId ):
+ sc_setChannel( 'trackVolume' + str(trackId + 1), volume )
+
+ def setTrackpadX( self, value ):
+ sc_setChannel( 'trackpadX', value)
+
+ def setTrackpadY( self, value ):
+ sc_setChannel( 'trackpadY', value)
+
+ def micRecording( self, table ):
+ sc_inputMessage( Config.CSOUND_MIC_RECORD % table )
+
+ def load_mic_instrument( self, inst ):
+ fileName = Config.SNDS_DIR + '/' + inst
+ instrumentId = Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[inst].instrumentId
+ sc_inputMessage(Config.CSOUND_LOAD_INSTRUMENT % (instrumentId, fileName))
+
+ def load_synth_instrument( self, inst ):
+ fileName = Config.SNDS_DIR + '/' + inst
+ instrumentId = Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[inst].instrumentId
+ sc_inputMessage(Config.CSOUND_LOAD_INSTRUMENT % (instrumentId, fileName))
+
+ def load_ls_instrument( self, inst ):
+ fileName = Config.SNDS_DIR + '/' + inst
+ sc_inputMessage(Config.CSOUND_LOAD_LS_INSTRUMENT % fileName)
+
+ def load_instruments( self ):
+ for instrumentSoundFile in Config.INSTRUMENTS.keys():
+ if instrumentSoundFile[0:3] == 'mic' or instrumentSoundFile[0:3] == 'lab' or Config.INSTRUMENTS[instrumentSoundFile].category == 'mysounds':
+ fileName = Config.SNDS_DIR + '/' + instrumentSoundFile
+ else:
+ fileName = Config.SOUNDS_DIR + "/" + instrumentSoundFile
+ instrumentId = Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[ instrumentSoundFile ].instrumentId
+ sc_inputMessage( Config.CSOUND_LOAD_INSTRUMENT % (instrumentId, fileName) )
+
+ def connect( self, init = True ):
+ def reconnect():
+ if sc_start(self.periods_per_buffer) :
+ if (Config.DEBUG > 0) : print 'ERROR connecting'
+ else:
+ self.on = True
+ def disconnect():
+ if sc_stop() :
+ if (Config.DEBUG > 0) : print 'ERROR connecting'
+ else:
+ self.on = False
+
+ if init and not self.on :
+ reconnect()
+ if not init and self.on :
+ disconnect()
+
+ def destroy( self ):
+ self.connect(False)
+ sc_destroy()
+
+ def inputMessage(self,msg):
+ sc_inputMessage(msg)
+
+ def getTick( self ):
+ return sc_getTickf()
+
+ def adjustTick( self, amt ):
+ sc_adjustTick(amt)
+
+ def setTempo(self,t):
+ if (Config.DEBUG > 3) : print 'INFO: loop tempo: %f -> %f' % (t, 60.0 / (Config.TICKS_PER_BEAT * t))
+ sc_setTickDuration( 60.0 / (Config.TICKS_PER_BEAT * t))
+
+
+ def loopCreate(self):
+ return sc_loop_new()
+
+ def loopDestroy(self, loopId):
+ sc_loop_delete(loopId)
+
+ def loopClear(self):
+ global _loop_default
+ sc_loop_delete(_loop_default)
+ _loop_default = sc_loop_new()
+
+ # this is function deletes an Event from a loop
+ # TODO: rename this function
+ def loopDelete(self, dbnote, loopId=_loop_default):
+ sc_loop_delScoreEvent( loopId, _noteid(dbnote))
+
+ def loopDelete1(self, page, id, loopId=_loop_default):
+ sc_loop_delScoreEvent( loopId, (page << 16) + id)
+
+ def loopStart(self, loopId=_loop_default):
+ sc_loop_playing(loopId, 1)
+
+ def loopPause(self, loopId=_loop_default):
+ sc_loop_playing(loopId, 0)
+
+ def loopSetTick(self,t, loopId=_loop_default):
+ sc_loop_setTickf(loopId, t)
+
+ def loopGetTick(self, loopId=_loop_default):
+ return sc_loop_getTickf(loopId)
+
+ def loopSetNumTicks(self,n, loopId=_loop_default):
+ sc_loop_setNumTicks(loopId, n)
+
+ def loopSetTickDuration(self,d, loopId=_loop_default):
+ sc_loop_setTickDuration(loopId, d)
+
+ def loopDeactivate(self, note = 'all', loopId=_loop_default):
+ if note == 'all':
+ sc_loop_deactivate_all(loopId)
+ else:
+ if (Config.DEBUG > 0) : print 'ERROR: deactivating a single note is not implemented'
+
+ def loopUpdate(self, note, parameter, value,cmd, loopId=_loop_default):
+ page = note.page
+ track = note.track
+ id = note.id
+ if note.cs.mode == 'mini':
+ instrument_id_offset = 0
+ elif note.cs.mode == 'edit':
+ if Config.INSTRUMENTSID[note.cs.instrumentId].kit != None:
+ instrument_id_offset = 0
+ else:
+ instrument_id_offset = 100
+ if (parameter == NoteDB.PARAMETER.ONSET):
+ if (Config.DEBUG > 2): print 'INFO: updating onset', (page<<16)+id, value
+ sc_loop_updateEvent( loopId, (page<<16)+id, 1, value, cmd)
+ elif (parameter == NoteDB.PARAMETER.PITCH):
+ if (Config.DEBUG > 2): print 'INFO: updating pitch', (page<<16)+id, value
+ pitch = value
+ if Config.INSTRUMENTSID[note.cs.instrumentId].kit != None:
+ instrument = Config.INSTRUMENTSID[note.cs.instrumentId].kit[pitch]
+ csoundInstId = instrument.csoundInstrumentId
+ csoundTable = Config.INSTRUMENT_TABLE_OFFSET + instrument.instrumentId
+ if (Config.DEBUG > 2): print 'INFO: updating drum instrument (pitch)', (page<<16)+id, instrument.name, csoundInstId
+ sc_loop_updateEvent( loopId, (page<<16)+id, 0, (csoundInstId + instrument_id_offset) + note.track * 0.01, -1 )
+ sc_loop_updateEvent( loopId, (page<<16)+id, 7, csoundTable , -1 )
+ pitch = 1
+ else:
+ pitch = GenerationConstants.TRANSPOSE[ pitch - 24 ]
+ sc_loop_updateEvent( loopId, (page<<16)+id, 3, pitch, cmd)
+ elif (parameter == NoteDB.PARAMETER.AMPLITUDE):
+ if (Config.DEBUG > 2): print 'INFO: updating amp', (page<<16)+id, value
+ sc_loop_updateEvent( loopId, (page<<16)+id, 5, value, cmd)
+ elif (parameter == NoteDB.PARAMETER.DURATION):
+ if (Config.DEBUG > 2): print 'INFO: updating duration', (page<<16)+id, value
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.DURATION, value, cmd)
+ elif (parameter == NoteDB.PARAMETER.INSTRUMENT):
+ pitch = note.cs.pitch
+ instrument = Config.INSTRUMENTSID[value]
+ if instrument.kit != None:
+ instrument = instrument.kit[pitch]
+ csoundInstId = instrument.csoundInstrumentId
+ csoundTable = Config.INSTRUMENT_TABLE_OFFSET + instrument.instrumentId
+ loopStart = instrument.loopStart
+ loopEnd = instrument.loopEnd
+ crossDur = instrument.crossDur
+ if (Config.DEBUG > 2): print 'INFO: updating instrument', (page<<16)+id, instrument.name, csoundInstId
+ sc_loop_updateEvent( loopId, (page<<16)+id, 0, (csoundInstId + (track+1) + instrument_id_offset) + note.track * 0.01, cmd )
+ sc_loop_updateEvent( loopId, (page<<16)+id, 7, csoundTable, -1 )
+ sc_loop_updateEvent( loopId, (page<<16)+id, 12, loopStart, -1 )
+ sc_loop_updateEvent( loopId, (page<<16)+id, 13, loopEnd, -1 )
+ sc_loop_updateEvent( loopId, (page<<16)+id, 14, crossDur , -1 )
+ elif (parameter == NoteDB.PARAMETER.PAN):
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.PAN, value, cmd)
+ elif (parameter == NoteDB.PARAMETER.REVERB):
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.REVERBSEND, value, cmd)
+ elif (parameter == NoteDB.PARAMETER.ATTACK):
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.ATTACK, value, cmd)
+ elif (parameter == NoteDB.PARAMETER.DECAY):
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.DECAY, value, cmd)
+ elif (parameter == NoteDB.PARAMETER.FILTERTYPE):
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.FILTERTYPE, value, cmd)
+ elif (parameter == NoteDB.PARAMETER.FILTERCUTOFF):
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.FILTERCUTOFF, value, cmd)
+ elif (parameter == NoteDB.PARAMETER.INSTRUMENT2):
+ sc_loop_updateEvent( loopId, (page<<16)+id, self.INSTRUMENT2, value, cmd)
+ else:
+ if (Config.DEBUG > 0): print 'ERROR: loopUpdate(): unsupported parameter change'
+
+ def loopPlay(self, dbnote, active, storage=_new_note_array(),
+ loopId=_loop_default ):
+ qid = (dbnote.page << 16) + dbnote.id
+ sc_loop_addScoreEvent( loopId, qid, 1, active, 'i',
+ self.csnote_to_array( dbnote.cs, storage))
+
+ def play(self, csnote, secs_per_tick, storage=_new_note_array()):
+ a = self.csnote_to_array(csnote, storage)
+ a[self.DURATION] = a[self.DURATION] * secs_per_tick
+ a[self.ATTACK] = max(a[self.ATTACK]*a[self.DURATION], 0.002)
+ a[self.DECAY] = max(a[self.DECAY]*a[self.DURATION], 0.002)
+ sc_scoreEvent( 'i', a)
+
+ def csnote_to_array(self, csnote, storage):
+ return self._csnote_to_array1(storage,
+ csnote.onset,
+ csnote.pitch,
+ csnote.amplitude,
+ csnote.pan,
+ csnote.duration,
+ csnote.trackId,
+ csnote.attack,
+ csnote.decay,
+ csnote.reverbSend,
+ csnote.filterType,
+ csnote.filterCutoff,
+ csnote.tied,
+ csnote.instrumentId,
+ csnote.mode,
+ csnote.instrumentId2 )
+
+ def _csnote_to_array1( self, storage, onset, pitch, amplitude, pan, duration,
+ trackId, attack, decay, reverbSend, filterType, filterCutoff,
+ tied, instrumentId, mode, instrumentId2 = -1):
+
+ rval=storage
+ instrument = Config.INSTRUMENTSID[instrumentId]
+ if instrument.kit != None:
+ instrument = instrument.kit[pitch]
+ pitch = 1
+ time_in_ticks = 0
+ else:
+ pitch = GenerationConstants.TRANSPOSE[ pitch - 24 ]
+ time_in_ticks = 1
+
+ instrument_id_offset = 0
+ # condition for tied notes
+ if instrument.csoundInstrumentId == Config.INST_TIED:
+ if tied:
+ if mode == 'mini':
+ duration = -1
+ instrument_id_offset = 0
+ elif mode == 'edit':
+ instrument_id_offset = 0
+ if duration < 0:
+ duration = -1
+ else:
+ if mode == 'mini':
+ instrument_id_offset = 0
+ elif mode == 'edit':
+ instrument_id_offset = 100
+
+ if instrument.csoundInstrumentId == Config.INST_SIMP:
+ if mode == 'mini':
+ instrument_id_offset = 0
+ elif mode == 'edit':
+ if instrument.soundClass == 'drum':
+ instrument_id_offset = 0
+ else:
+ instrument_id_offset = 100
+
+ rval[0] = (instrument.csoundInstrumentId + \
+ (trackId+1) + instrument_id_offset) + trackId * 0.01
+ rval[1] = onset
+ rval[2] = duration
+ rval[3] = pitch
+ rval[4] = reverbSend
+ rval[5] = amplitude
+ rval[6] = pan
+ rval[7] = Config.INSTRUMENT_TABLE_OFFSET + instrument.instrumentId
+ rval[8] = attack
+ rval[9] = decay
+ rval[10]= filterType
+ rval[11]= filterCutoff
+ rval[12]= instrument.loopStart
+ rval[13]= instrument.loopEnd
+ rval[14]= instrument.crossDur
+
+ if instrumentId2 != -1:
+ instrument2 = Config.INSTRUMENTSID[instrumentId2]
+ csInstrumentId2 = (instrument2.csoundInstrumentId + 100) * 0.0001
+ rval[15] = Config.INSTRUMENT_TABLE_OFFSET + instrumentId2 + csInstrumentId2
+ rval[16] = instrument2.loopStart
+ rval[17] = instrument2.loopEnd
+ rval[18] = instrument2.crossDur
+ else:
+ rval[15] = -1
+ rval[16] = 0
+ rval[17] = 0
+ rval[18] = 0
+
+ return rval
+
+_Client = None
+
+def new_csound_client():
+ global _Client
+ if _Client == None:
+ _Client = _CSoundClientPlugin()
+ _Client.connect(True)
+ _Client.setMasterVolume(100.0)
+ _Client.load_instruments()
+ time.sleep(0.2)
+ return _Client
diff --git a/common/Util/CSoundNote.py b/common/Util/CSoundNote.py
new file mode 100644
index 0000000..535084d
--- /dev/null
+++ b/common/Util/CSoundNote.py
@@ -0,0 +1,77 @@
+import common.Config as Config
+
+class CSoundNote :
+ def __init__( self,
+ onset,
+ pitch,
+ amplitude,
+ pan,
+ duration,
+ trackId,
+ instrumentId = Config.INSTRUMENTS["flute"].instrumentId,
+ attack = 0.005,
+ decay = 0.098,
+ reverbSend = 0.1,
+ filterType = 0,
+ filterCutoff = 1000,
+ tied = False,
+ mode = 'edit',
+ instrumentId2 = -1 ):
+
+ self.onset = onset
+ self.pitch = pitch
+ self.amplitude = amplitude
+ self.pan = pan
+ self.duration = duration
+ self.trackId = trackId
+ self.instrumentId = instrumentId
+ #temp: catch old code trying to pass in instrument names here
+ int(instrumentId)
+ self.attack = attack
+ self.decay = decay
+ self.reverbSend = reverbSend
+ self.filterType = filterType
+ self.filterCutoff = filterCutoff
+ self.tied = tied
+ self.mode = mode
+ self.instrumentId2 = instrumentId2
+
+ def clone( self ):
+ return CSoundNote( self.onset, self.pitch, self.amplitude, self.pan,
+ self.duration, self.trackId, self.instrumentId,
+ self.attack, self.decay, self.reverbSend,
+ self.filterType, self.filterCutoff, self.tied,
+ self.mode, self.instrumentId2 )
+
+ def __getstate__unused(self):
+ return {'onset': self.onset,
+ 'pitch': self.pitch,
+ 'amplitude': self.amplitude,
+ 'pan': self.pan,
+ 'duration': self.duration,
+ 'trackId': self.trackId,
+ 'instrumentId': self.instrumentId,
+ 'attack': self.attack,
+ 'decay': self.decay,
+ 'reverbSend': self.reverbSend,
+ 'filterType': self.filterType,
+ 'filterCutoff': self.filterCutoff,
+ 'tied': self.tied,
+ 'mode': self.mode }
+
+ def __setstate__unused(self,dict):
+ self.onset = dict['onset']
+ self.pitch = dict['pitch']
+ self.amplitude = dict['amplitude']
+ self.pan = dict['pan']
+ self.duration = dict['duration']
+ self.trackId = dict['trackId']
+ self.instrumentId = dict['instrumentId']
+ self.attack = dict['attack']
+ self.decay = dict['decay']
+ self.reverbSend = dict['reverbSend']
+ self.filterType = dict['filterType']
+ self.filterCutoff = dict['filterCutoff']
+ self.tied = dict['tied']
+ self.mode = dict['mode']
+ self.nchanges = 0
diff --git a/common/Util/Clooper/Makefile b/common/Util/Clooper/Makefile
new file mode 100644
index 0000000..6ea2e2c
--- /dev/null
+++ b/common/Util/Clooper/Makefile
@@ -0,0 +1,21 @@
+CC=gcc
+
+CXXFLAGS+= -Wall -Werror -fPIC -O2 -finline
+LDFLAGS+= -lasound
+
+LDFLAGS+= -L/usr/local/lib -lcsound
+
+CPPFLAGS+=-I/home/james/cvs/sugar-jhbuild/build/include/python2.5
+LDFLAGS+=-L/home/james/cvs/sugar-jhbuild/build/lib
+
+CPPFLAGS+=-I/usr/include/python2.5
+LDFLAGS+=-lpython2.5
+
+all : aclient.so
+
+aclient.so : aclient.cpp audio.cpp
+ g++ $(CPPFLAGS) $(CXXFLAGS) -shared -o $@ $< $(LDFLAGS)
+
+clean :
+ rm aclient.so
+
diff --git a/common/Util/Clooper/SoundClient.i b/common/Util/Clooper/SoundClient.i
new file mode 100644
index 0000000..80d77df
--- /dev/null
+++ b/common/Util/Clooper/SoundClient.i
@@ -0,0 +1,14 @@
+
+%module SClient
+
+%{
+#define SWIG_FILE_WITH_INIT
+#include "SoundClient.h"
+%}
+
+%pythoncode
+%{
+
+%}
+
+%include "SoundClient.h"
diff --git a/common/Util/Clooper/__init__.py b/common/Util/Clooper/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/common/Util/Clooper/__init__.py
diff --git a/common/Util/Clooper/aclient.cpp b/common/Util/Clooper/aclient.cpp
new file mode 100644
index 0000000..1146c3b
--- /dev/null
+++ b/common/Util/Clooper/aclient.cpp
@@ -0,0 +1,1090 @@
+#include <Python.h>
+
+#include <pthread.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sched.h>
+
+#include <vector>
+#include <map>
+#include <cmath>
+
+#include <csound/csound.h>
+#include <alsa/asoundlib.h>
+
+static double pytime(const struct timeval * tv)
+{
+ struct timeval t;
+ if (!tv)
+ {
+ tv = &t;
+ gettimeofday(&t, NULL);
+ }
+ return (double) tv->tv_sec + (double) tv->tv_usec / 1000000.0;
+}
+#include "log.cpp"
+#include "audio.cpp"
+
+#define FLOAT_TO_SHORT(in,out) __asm__ __volatile__ ("fistps %0" : "=m" (out) : "t" (in) : "st") ;
+
+int VERBOSE = 3;
+FILE * _debug = NULL;
+struct TamTamSound;
+struct Music;
+TamTamSound * g_tt = NULL;
+Music * g_music = NULL;
+log_t * g_log = NULL;
+const int STEP_eventMax = 16; //this is the most events that will be queued by a loop per step()
+
+/**
+ * Event is the type of event that Clooper puts in the loop buffer.
+ * It corresponds to a line of csound that starts with an 'i'
+ */
+struct Event
+{
+ char type; ///< if this event were listed in a csound file, the line would begin with this letter
+ int onset; ///< the onset time of this event (its temporal position)
+ bool time_in_ticks; ///< if true, then some parameters will be updated according to the tempo
+ bool active; ///< if true, then event() will actually do something
+ MYFLT prev_secs_per_tick; ///< normally used for ____, sometimes set to -1 to force recalculation of param[] entries
+ MYFLT duration, attack, decay;///< canonical values of some tempo-dependent parameters
+ std::vector<MYFLT> param; ///< parameter buffer for csound
+
+ Event(char type, MYFLT * p, int param_count, bool in_ticks, bool active)
+ : type(type), onset(0), time_in_ticks(in_ticks), active(active), param(param_count)
+ {
+ assert(param_count >= 4);
+ onset = (int) p[1];
+ duration = p[2];
+ attack = param_count > 8 ? p[8]: 0.0; //attack
+ decay = param_count > 9 ? p[9]: 0.0; //decay
+ prev_secs_per_tick = -1.0;
+ for (int i = 0; i < param_count; ++i) param[i] = p[i];
+
+ param[1] = 0.0; //onset
+ }
+ /*
+ bool operator<(const Event &e) const
+ {
+ return onset < e.onset;
+ }
+ */
+ void ev_print(FILE *f)
+ {
+ fprintf(f, "INFO: scoreEvent %c ", type);
+ for (size_t i = 0; i < param.size(); ++i) fprintf(f, "%lf ", param[i]);
+ fprintf(f, "[%s]\n", active ? "active": "inactive");
+ }
+ /**
+ * Update the idx'th param value to have a certain value.
+ *
+ * Certain of the parameters are linked in strange hack-y ways, as defined by
+ * the constructor, and update() (which should be consistent with one another!)
+ *
+ * These events are for use with the file: TamTam/Resources/univorc.csd.
+ * So that file defines how the parameters will be interpreted by csound.
+ */
+ void update(int idx, MYFLT val)
+ {
+ if ( (unsigned)idx >= param.size())
+ {
+ if (_debug && (VERBOSE > 0)) fprintf(_debug, "ERROR: updateEvent request for too-high parameter %i\n", idx);
+ return;
+ }
+ if (time_in_ticks)
+ {
+ switch(idx)
+ {
+ case 1: onset = (int) val; break;
+ case 2: duration = val; break;
+ case 8: attack = val; break;
+ case 9: decay = val; break;
+ default: param[idx] = val; break;
+ }
+ prev_secs_per_tick = -1.0; //force recalculation
+ }
+ else
+ {
+ param[idx] = val;
+ }
+ }
+ /**
+ * An Event instance can be in an active or inactive state. If an Event instance
+ * is active, then event() will call a corresponding csoundScoreEvent(). If an
+ * Event instance is inactive, then event() is a noop.
+ */
+ void activate_cmd(int cmd)
+ {
+ switch(cmd)
+ {
+ case 0: active = false; break;
+ case 1: active = true; break;
+ case 2: active = !active; break;
+ }
+ }
+
+ /**
+ * Iff this instance is active, this call generates a csound event.
+ * Parameters are passed directly as a buffer of floats. If secs_per_tick
+ * != prev_secs_per_tick (possibly because prev_secs_per_tick was set to -1
+ * by update() ) then this call will do some floating point ops to
+ * recalculate the parameter buffer.
+ */
+ void event(CSOUND * csound, MYFLT secs_per_tick)
+ {
+ if (!active) return;
+
+ if (time_in_ticks && (secs_per_tick != prev_secs_per_tick))
+ {
+ param[2] = duration * secs_per_tick;
+ if (param.size() > 8) param[8] = std::max(0.002f, attack * param[2]);
+ if (param.size() > 9) param[9] = std::max(0.002f, decay * param[2]);
+ prev_secs_per_tick = secs_per_tick;
+ if (_debug && (VERBOSE > 2)) fprintf(_debug, "setting duration to %f\n", param[5]);
+ }
+ csoundScoreEvent(csound, type, &param[0], param.size());
+ }
+};
+
+/**
+ *
+ * Loop is a repeat-able loop of Event instances.
+ * */
+struct Loop
+{
+ typedef int onset_t;
+ typedef int id_t;
+ typedef std::pair<onset_t, Event *> pair_t;
+ typedef std::multimap<onset_t, Event *>::iterator iter_t;
+ typedef std::map<id_t, iter_t>::iterator idmap_t;
+
+ int tick_prev;
+ int tickMax;
+ MYFLT rtick;
+
+ // a container of all events, sorted by onset time
+ // used for efficient playback
+ std::multimap<onset_t, Event *> ev;
+ // the playback head
+ std::multimap<onset_t, Event *>::iterator ev_pos;
+ // a container of pointers into ev, indexed by note id
+ // used for deleting, updating notes
+ std::map<id_t, iter_t> idmap;
+ int steps;
+ int playing; //true means that step() works, else step() is no-op
+
+ Loop() : tick_prev(0), tickMax(1), rtick(0.0), ev(), ev_pos(ev.end()), steps(0), playing(0)
+ {
+ }
+ ~Loop()
+ {
+ //TODO: send these events to a recycling queue, don't erase them
+ for (iter_t i = ev.begin(); i != ev.end(); ++i)
+ {
+ delete i->second;
+ }
+ }
+ void deactivateAll()
+ {
+ for (iter_t i = ev.begin(); i != ev.end(); ++i)
+ {
+ i->second->activate_cmd(0);
+ }
+ }
+ MYFLT getTickf()
+ {
+ return fmod(rtick, (MYFLT)tickMax);
+ }
+ void setNumTicks(int nticks)
+ {
+ tickMax = nticks;
+ MYFLT fnticks = nticks;
+ if (rtick > fnticks)
+ {
+ rtick = fmodf(rtick, fnticks);
+ }
+ }
+ void setTickf(float t)
+ {
+ rtick = fmodf(t, (MYFLT) tickMax);
+ ev_pos = ev.lower_bound( (int) rtick );
+ }
+ /** advance in play loop by rtick_inc ticks, possibly generate some
+ * csoundScoreEvent calls.
+ */
+ void step(MYFLT rtick_inc, MYFLT secs_per_tick , CSOUND * csound)
+ {
+ if (!playing) return;
+ rtick += rtick_inc;
+ int tick = (int)rtick % tickMax;
+ if (tick == tick_prev) return;
+
+ int events = 0;
+ int loop0 = 0;
+ int loop1 = 0;
+ if (!ev.empty())
+ {
+ if (steps && (tick < tick_prev)) // should be true only after the loop wraps (not after insert)
+ {
+ while (ev_pos != ev.end())
+ {
+ if (_debug && (VERBOSE > 3)) ev_pos->second->ev_print(_debug);
+ if (events < STEP_eventMax) ev_pos->second->event(csound, secs_per_tick);
+ ++ev_pos;
+ ++events;
+ ++loop0;
+ }
+ ev_pos = ev.begin();
+ }
+ while ((ev_pos != ev.end()) && (tick >= ev_pos->first))
+ {
+ if (_debug && (VERBOSE > 3)) ev_pos->second->ev_print(_debug);
+ if (events < STEP_eventMax) ev_pos->second->event(csound, secs_per_tick);
+ ++ev_pos;
+ ++events;
+ ++loop1;
+ }
+ }
+ tick_prev = tick;
+ if (_debug && (VERBOSE>1) && (events >= STEP_eventMax)) fprintf(_debug, "WARNING: %i/%i events at once (%i, %i)\n", events,ev.size(),loop0,loop1);
+ ++steps;
+ }
+ void addEvent(int id, char type, MYFLT * p, int np, bool in_ticks, bool active)
+ {
+ Event * e = new Event(type, p, np, in_ticks, active);
+
+ idmap_t id_iter = idmap.find(id);
+ if (id_iter == idmap.end())
+ {
+ //this is a new id
+ iter_t e_iter = ev.insert(pair_t(e->onset, e));
+
+ //TODO: optimize by thinking about whether to do ev_pos = e_iter
+ ev_pos = ev.upper_bound( tick_prev );
+ idmap[id] = e_iter;
+ }
+ else
+ {
+ g_log->printf(1, "%s duplicate note %i\n", __FUNCTION__, id);
+ }
+ }
+ void delEvent(int id)
+ {
+ idmap_t id_iter = idmap.find(id);
+ if (id_iter != idmap.end())
+ {
+ iter_t e_iter = id_iter->second;//idmap[id];
+ if (e_iter == ev_pos) ++ev_pos;
+
+ delete e_iter->second;
+ ev.erase(e_iter);
+ idmap.erase(id_iter);
+ }
+ else
+ {
+ g_log->printf( 1, "%s unknown note %i\n", __FUNCTION__, id);
+ }
+ }
+ void updateEvent(int id, int idx, float val, int activate_cmd)
+ {
+ idmap_t id_iter = idmap.find(id);
+ if (id_iter != idmap.end())
+ {
+ //this is a new id
+ iter_t e_iter = id_iter->second;
+ Event * e = e_iter->second;
+ int onset = e->onset;
+ e->update(idx, val);
+ e->activate_cmd(activate_cmd);
+ if (onset != e->onset)
+ {
+ ev.erase(e_iter);
+
+ e_iter = ev.insert(pair_t(e->onset, e));
+
+ //TODO: optimize by thinking about whether to do ev_pos = e_iter
+ ev_pos = ev.upper_bound( tick_prev );
+ idmap[id] = e_iter;
+ }
+ }
+ else
+ {
+ g_log->printf(1, "%s unknown note %i\n", __FUNCTION__, id);
+ }
+ }
+ void reset()
+ {
+ steps = 0;
+ }
+ void setPlaying(int tf)
+ {
+ playing = tf;
+ }
+};
+
+/** management of loops */
+struct Music
+{
+ typedef int loopIdx_t;
+ typedef std::map<int, Loop * > eventMap_t;
+
+ eventMap_t loop;
+ int loop_nextIdx;
+ void * mutex; //modification and playing of loops cannot be interwoven
+
+ Music() :
+ loop(),
+ loop_nextIdx(0),
+ mutex(csoundCreateMutex(0))
+ {
+ }
+ ~Music()
+ {
+ for (eventMap_t::iterator i = loop.begin(); i != loop.end(); ++i)
+ {
+ delete i->second;
+ }
+ csoundDestroyMutex(mutex);
+ }
+
+ void step(MYFLT amt, MYFLT secs_per_tick, CSOUND * csound)
+ {
+ csoundLockMutex(mutex);
+ for (eventMap_t::iterator i = loop.begin(); i != loop.end(); ++i)
+ {
+ i->second->step(amt, secs_per_tick, csound);
+ }
+ csoundUnlockMutex(mutex);
+ }
+
+ /** allocate a new loop, and return its index */
+ loopIdx_t alloc()
+ {
+ csoundLockMutex(mutex);
+ //find a loop_nextIdx that isn't in loop map already
+ while ( loop.find( loop_nextIdx) != loop.end()) ++loop_nextIdx;
+ loop[loop_nextIdx] = new Loop();
+ csoundUnlockMutex(mutex);
+ return loop_nextIdx;
+ }
+ /** de-allocate a loop */
+ void destroy(loopIdx_t loopIdx)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ csoundLockMutex(mutex);
+ //TODO: save the note events to a cache for recycling
+ delete loop[loopIdx];
+ loop.erase(loopIdx);
+ csoundUnlockMutex(mutex);
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+ /** set the playing flag of the given loop */
+ void playing(loopIdx_t loopIdx, int tf)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ csoundLockMutex(mutex);
+ loop[loopIdx]->setPlaying(tf);
+ csoundUnlockMutex(mutex);
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+ /** set the playing flag of the given loop */
+ void addEvent(loopIdx_t loopIdx, int eventId, char type, MYFLT * p, int np, bool in_ticks, bool active)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ csoundLockMutex(mutex);
+ loop[loopIdx]->addEvent(eventId, type, p, np, in_ticks, active);
+ csoundUnlockMutex(mutex);
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+ void delEvent(loopIdx_t loopIdx, int eventId)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ csoundLockMutex(mutex);
+ loop[loopIdx]->delEvent(eventId);
+ csoundUnlockMutex(mutex);
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+ void updateEvent(loopIdx_t loopIdx, int eventId, int pIdx, float pVal, int activate_cmd)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ csoundLockMutex(mutex);
+ loop[loopIdx]->updateEvent(eventId, pIdx, pVal, activate_cmd);
+ csoundUnlockMutex(mutex);
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+ MYFLT getTickf(loopIdx_t loopIdx)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ return loop[loopIdx]->getTickf();
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ return 0.0;
+ }
+ }
+ void setTickf(loopIdx_t loopIdx, MYFLT tickf)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ loop[loopIdx]->setTickf(tickf);
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+ void setNumTicks(loopIdx_t loopIdx, int numTicks)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ loop[loopIdx]->setNumTicks(numTicks);
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+ void deactivateAll(loopIdx_t loopIdx)
+ {
+ if (loop.find(loopIdx) != loop.end())
+ {
+ loop[loopIdx]->deactivateAll();
+ }
+ else
+ {
+ g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx);
+ }
+ }
+
+};
+
+/**
+ * The main object of control in the Clooper plugin.
+ *
+ * This guy controls the sound rendering thread, loads and unloads ALSA,
+ * maintains a csound instance, and maintains a subset of notes from the
+ * currently-loaded TamTam.
+ */
+struct TamTamSound
+{
+ /** the id of an running sound-rendering thread, or NULL */
+ void * ThreadID;
+ /** a flag to tell the thread to continue, or break */
+ enum {CONTINUE, STOP} PERF_STATUS;
+ /** our csound object, NULL iff there was a problem creating it */
+ CSOUND * csound;
+ /** our note sources */
+ Music music;
+
+ MYFLT secs_per_tick;
+ MYFLT ticks_per_period;
+ MYFLT tick_adjustment; //the default time increment in thread_fn
+ MYFLT tick_total;
+
+ /** the upsampling ratio from csound */
+ unsigned int csound_ksmps;
+ snd_pcm_uframes_t csound_frame_rate;
+ snd_pcm_uframes_t csound_period_size;
+ snd_pcm_uframes_t period0;
+ unsigned int period_per_buffer; //should be 2
+ int up_ratio; //if the hardware only supports a small integer multiple of our effective samplerate, do a real-time conversion
+
+ log_t * ll;
+ SystemStuff * sys_stuff;
+
+ TamTamSound(log_t * ll, char * orc, snd_pcm_uframes_t period0, unsigned int ppb, int ksmps, int framerate )
+ : ThreadID(NULL), PERF_STATUS(STOP), csound(NULL),
+ music(),
+ ticks_per_period(0.0),
+ tick_adjustment(0.0),
+ tick_total(0.0),
+ csound_ksmps(ksmps), //must agree with the orchestra file
+ csound_frame_rate(framerate), //must agree with the orchestra file
+ period0(period0),
+ period_per_buffer(ppb),
+ up_ratio(1),
+ ll( ll ),
+ sys_stuff(NULL)
+ {
+ sys_stuff = new SystemStuff(ll);
+ if (0 > sys_stuff->open(csound_frame_rate, 4, period0, period_per_buffer))
+ {
+ return;
+ }
+ sys_stuff->close(0);
+ up_ratio = sys_stuff->rate / csound_frame_rate;
+ csound_period_size = (sys_stuff->period_size % up_ratio == 0)
+ ? sys_stuff->period_size / up_ratio
+ : csound_ksmps * 4;
+
+ csound = csoundCreate(NULL);
+ int argc=3;
+ char **argv = (char**)malloc(argc*sizeof(char*));
+ argv[0] = "csound";
+ argv[1] = "-m0";
+ argv[2] = orc;
+
+ ll->printf(1, "loading csound orchestra file %s\n", orc);
+ //csoundInitialize(&argc, &argv, 0);
+ csoundPreCompile(csound);
+ csoundSetHostImplementedAudioIO(csound, 1, csound_period_size);
+ int result = csoundCompile(csound, argc, &(argv[0]));
+ if (result)
+ {
+ csound = NULL;
+ ll->printf( "ERROR: csoundCompile of orchestra %s failed with code %i\n", orc, result);
+ }
+ free(argv);
+ setTickDuration(0.05);
+ }
+ ~TamTamSound()
+ {
+ if (csound)
+ {
+ stop();
+ ll->printf(2, "Going for csoundDestroy\n");
+ csoundDestroy(csound);
+ }
+ ll->printf(2, "TamTamSound destroyed\n");
+ if (sys_stuff) delete sys_stuff;
+ delete ll;
+ }
+ bool good()
+ {
+ return csound != NULL;
+ }
+
+ uintptr_t thread_fn()
+ {
+ assert(csound);
+
+ const int nchannels = 2;
+ int nloops = 0;
+ long int csound_nsamples = csoundGetOutputBufferSize(csound);
+ long int csound_nframes = csound_nsamples / nchannels;
+
+ ll->printf(2, "INFO: nsamples = %li nframes = %li\n", csound_nsamples, csound_nframes);
+
+ if (0 > sys_stuff->open(csound_frame_rate, 4, period0, period_per_buffer))
+ {
+ ll->printf( "ERROR: failed to open alsa device, thread abort\n");
+ return 1;
+ }
+
+ assert(up_ratio == (signed)(sys_stuff->rate / csound_frame_rate));
+
+ bool do_upsample = (signed)sys_stuff->period_size != csound_nframes;
+ short *upbuf = new short[ sys_stuff->period_size * nchannels ];
+ int cbuf_pos = csound_nframes; // trigger a call to csoundPerformBuffer immediately
+ float *cbuf = NULL;
+ int up_pos = 0;
+ int ratio_pos = 0;
+
+ tick_total = 0.0f;
+
+ while (PERF_STATUS == CONTINUE)
+ {
+ if ( do_upsample ) //fill one period of audio buffer data by 0 or more calls to csound
+ {
+ up_pos = 0;
+ int messed = 0;
+ short cursample[2]={0,0};
+ while(!messed)
+ {
+ if (cbuf_pos == csound_nframes)
+ {
+ cbuf_pos = 0;
+ if (csoundPerformBuffer(csound)) { messed = 1;break;}
+ cbuf = csoundGetOutputBuffer(csound);
+ }
+ upbuf[2*up_pos+0] = cursample[0];
+ upbuf[2*up_pos+1] = cursample[1];
+
+ if (++ratio_pos == up_ratio)
+ {
+ ratio_pos = 0;
+ ++cbuf_pos;
+ cbuf[cbuf_pos*2+0] *= (float) ((1<<15)-100.0f);
+ cbuf[cbuf_pos*2+1] *= (float) ((1<<15)-100.0f);
+ FLOAT_TO_SHORT( cbuf[cbuf_pos*2+0], cursample[0]);
+ FLOAT_TO_SHORT( cbuf[cbuf_pos*2+1], cursample[1]);
+ }
+
+ if (++up_pos == (signed)sys_stuff->period_size) break;
+ }
+ if (messed || (up_pos != (signed)sys_stuff->period_size)) break;
+
+ if (0 > sys_stuff->writebuf(sys_stuff->period_size, upbuf)) break;
+ }
+ else //fill one period of audio directly from csound
+ {
+ if (csoundPerformBuffer(csound)) break;
+ cbuf = csoundGetOutputBuffer(csound);
+ for (int i = 0; i < csound_nframes * nchannels; ++i)
+ {
+ cbuf[i] *= (float) ((1<<15)-100.0f);
+ FLOAT_TO_SHORT( cbuf[i], upbuf[i]);
+ }
+ if (0 > sys_stuff->writebuf(csound_nframes,upbuf)) break;
+ }
+
+ if (tick_adjustment > - ticks_per_period)
+ {
+ MYFLT tick_inc = ticks_per_period + tick_adjustment;
+ music.step( tick_inc, secs_per_tick, csound);
+ tick_adjustment = 0.0;
+ tick_total += tick_inc;
+ }
+ else
+ {
+ tick_adjustment += ticks_per_period;
+ }
+ ++nloops;
+ }
+
+ sys_stuff->close(1);
+ delete [] upbuf;
+ ll->printf(2, "INFO: performance thread returning 0\n");
+ return 0;
+ }
+ static uintptr_t csThread(void *clientData)
+ {
+ return ((TamTamSound*)clientData)->thread_fn();
+ }
+ int start(int )
+ {
+ if (!csound) {
+ ll->printf(1, "skipping %s, csound==NULL\n", __FUNCTION__);
+ return 1;
+ }
+ if (!ThreadID)
+ {
+ PERF_STATUS = CONTINUE;
+ ThreadID = csoundCreateThread(csThread, (void*)this);
+ ll->printf( "INFO(%s:%i) aclient launching performance thread (%p)\n", __FILE__, __LINE__, ThreadID );
+ return 0;
+ }
+ ll->printf( "INFO(%s:%i) skipping duplicate request to launch a thread\n", __FILE__, __LINE__ );
+ return 1;
+ }
+ int stop()
+ {
+ if (!csound) {
+ ll->printf(1, "skipping %s, csound==NULL\n", __FUNCTION__);
+ return 1;
+ }
+ if (ThreadID)
+ {
+ PERF_STATUS = STOP;
+ ll->printf( "INFO(%s:%i) aclient joining performance thread\n", __FILE__, __LINE__ );
+ uintptr_t rval = csoundJoinThread(ThreadID);
+ ll->printf( "INFO(%s:%i) ... joined\n", __FILE__, __LINE__ );
+ if (rval) ll->printf( "WARNING: thread returned %zu\n", rval);
+ ThreadID = NULL;
+ return 0;
+ }
+ return 1;
+ }
+
+ /** pass an array event straight through to csound. only works if perf. thread is running */
+ void scoreEvent(char type, MYFLT * p, int np)
+ {
+ if (!csound) {
+ ll->printf(1, "skipping %s, csound==NULL\n", __FUNCTION__);
+ return;
+ }
+ if (!ThreadID)
+ {
+ if (_debug && (VERBOSE > 1)) fprintf(_debug, "skipping %s, ThreadID==NULL\n", __FUNCTION__);
+ return ;
+ }
+ if (_debug && (VERBOSE > 2))
+ {
+ fprintf(_debug, "INFO: scoreEvent %c ", type);
+ for (int i = 0; i < np; ++i) fprintf(_debug, "%lf ", p[i]);
+ fprintf(_debug, "\n");
+ }
+ csoundScoreEvent(csound, type, p, np);
+ }
+ /** pass a string event straight through to csound. only works if perf. thread is running */
+ void inputMessage(const char * msg)
+ {
+ if (!csound) {
+ ll->printf(1, "skipping %s, csound==NULL\n", __FUNCTION__);
+ return;
+ }
+ if (!ThreadID)
+ {
+ if (_debug && (VERBOSE > 1)) fprintf(_debug, "skipping %s, ThreadID==NULL\n", __FUNCTION__);
+ return ;
+ }
+ if (_debug &&(VERBOSE > 3)) fprintf(_debug, "%s\n", msg);
+ csoundInputMessage(csound, msg);
+ }
+ /** pass a setChannel command through to csound. only works if perf. thread is running */
+ void setChannel(const char * name, MYFLT vol)
+ {
+ if (!csound) {
+ ll->printf(1, "skipping %s, csound==NULL\n", __FUNCTION__);
+ return;
+ }
+ if (!ThreadID)
+ {
+ if (_debug && (VERBOSE > 1)) fprintf(_debug, "skipping %s, ThreadID==NULL\n", __FUNCTION__);
+ return ;
+ }
+ MYFLT *p;
+ if (!(csoundGetChannelPtr(csound, &p, name, CSOUND_CONTROL_CHANNEL | CSOUND_INPUT_CHANNEL)))
+ *p = (MYFLT) vol;
+ else
+ {
+ if (_debug && (VERBOSE >0)) fprintf(_debug, "ERROR: failed to set channel: %s\n", name);
+ }
+ }
+
+ /** adjust the global tick value by this much */
+ void adjustTick(MYFLT dtick)
+ {
+ tick_adjustment += dtick;
+ }
+ void setTickDuration(MYFLT d )
+ {
+ secs_per_tick = d;
+ ticks_per_period = csound_period_size / ( secs_per_tick * csound_frame_rate);
+ ll->printf( 3, "INFO: duration %lf := ticks_per_period %lf\n", secs_per_tick , ticks_per_period);
+ }
+ MYFLT getTickf()
+ {
+ return tick_total + tick_adjustment;
+ }
+};
+
+
+static void cleanup(void)
+{
+ if (g_tt)
+ {
+ delete g_tt;
+ g_tt = NULL;
+ }
+}
+
+#define DECL(s) static PyObject * s(PyObject * self, PyObject *args)
+#define RetNone Py_INCREF(Py_None); return Py_None;
+
+//call once at end
+DECL(sc_destroy)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ return NULL;
+ }
+ if (g_tt)
+ {
+ delete g_tt;
+ g_tt = NULL;
+ if (_debug) fclose(_debug);
+ }
+ RetNone;
+}
+//call once at startup, should return 0
+DECL(sc_initialize) //(char * csd)
+{
+ char * str;
+ char * log_file;
+ int period, ppb, ksmps, framerate;
+ if (!PyArg_ParseTuple(args, "ssiiiii", &str, &log_file, &period, &ppb, &VERBOSE, &ksmps, &framerate ))
+ {
+ return NULL;
+ }
+ if ( log_file[0] )
+ {
+ _debug = fopen(log_file,"w");
+ if (_debug==NULL)
+ {
+ fprintf(stderr, "WARNING: fopen(%s) failed, logging to stderr\n", log_file);
+ _debug = stderr;
+ }
+ }
+ else
+ {
+ _debug = NULL;
+ fprintf(stderr, "Logging disabled on purpose\n");
+ }
+ g_log = new log_t(_debug, VERBOSE);
+ g_tt = new TamTamSound(g_log, str, period, ppb, ksmps, framerate);
+ g_music = & g_tt->music;
+ atexit(&cleanup);
+ if (g_tt->good())
+ return Py_BuildValue("i", 0);
+ else
+ return Py_BuildValue("i", -1);
+}
+//compile the score, connect to device, start a sound rendering thread
+DECL(sc_start)
+{
+ int ppb;
+ if (!PyArg_ParseTuple(args, "i", &ppb ))
+ {
+ return NULL;
+ }
+ return Py_BuildValue("i", g_tt->start(ppb));
+}
+//stop csound rendering thread, disconnect from sound device, clear tables.
+DECL(sc_stop)
+{
+ if (!PyArg_ParseTuple(args, "" ))
+ {
+ return NULL;
+ }
+ return Py_BuildValue("i", g_tt->stop());
+}
+DECL(sc_scoreEvent) //(char type, farray param)
+{
+ char ev_type;
+ PyObject *o;
+ if (!PyArg_ParseTuple(args, "cO", &ev_type, &o ))
+ {
+ return NULL;
+ }
+ if (o->ob_type
+ && o->ob_type->tp_as_buffer
+ && (1 == o->ob_type->tp_as_buffer->bf_getsegcount(o, NULL)))
+ {
+ if (o->ob_type->tp_as_buffer->bf_getreadbuffer)
+ {
+ void * ptr;
+ size_t len;
+ len = o->ob_type->tp_as_buffer->bf_getreadbuffer(o, 0, &ptr);
+ float * fptr = (float*)ptr;
+ size_t flen = len / sizeof(float);
+ g_tt->scoreEvent(ev_type, fptr, flen);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ else
+ {
+ assert(!"asdf");
+ }
+ }
+ assert(!"not reached");
+ return NULL;
+}
+DECL (sc_inputMessage) //(const char *msg)
+{
+ char * msg;
+ if (!PyArg_ParseTuple(args, "s", &msg ))
+ {
+ return NULL;
+ }
+ g_tt->inputMessage(msg);
+ RetNone;
+}
+DECL(sc_setChannel) //(string name, float value)
+{
+ const char * str;
+ float v;
+ if (!PyArg_ParseTuple(args, "sf", &str,&v))
+ {
+ return NULL;
+ }
+ g_tt->setChannel(str,v);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+DECL(sc_getTickf) // () -> float
+{
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ return NULL;
+ }
+ return Py_BuildValue("f", g_tt->getTickf());
+}
+DECL(sc_adjustTick) // (MYFLT ntick)
+{
+ float spt;
+ if (!PyArg_ParseTuple(args, "f", &spt ))
+ {
+ return NULL;
+ }
+ g_tt->adjustTick(spt);
+ RetNone;
+}
+DECL(sc_setTickDuration) // (MYFLT secs_per_tick)
+{
+ float spt;
+ if (!PyArg_ParseTuple(args, "f", &spt ))
+ {
+ return NULL;
+ }
+ g_tt->setTickDuration(spt);
+ RetNone;
+}
+DECL(sc_loop_new) // () -> int
+{
+ if (!PyArg_ParseTuple(args, "" )) return NULL;
+ return Py_BuildValue("i", g_music->alloc());
+}
+DECL(sc_loop_delete) // (int loopIdx)
+{
+ int loopIdx;
+ if (!PyArg_ParseTuple(args, "i", &loopIdx )) return NULL;
+ g_music->destroy(loopIdx);
+ RetNone;
+}
+DECL(sc_loop_getTickf) // (int loopIdx) -> float
+{
+ int idx;
+ if (!PyArg_ParseTuple(args, "i", &idx ))
+ {
+ return NULL;
+ }
+ return Py_BuildValue("f", g_music->getTickf(idx));
+}
+DECL(sc_loop_setNumTicks) //(int loopIdx, int nticks)
+{
+ int loopIdx;
+ int nticks;
+ if (!PyArg_ParseTuple(args, "ii", &loopIdx, &nticks )) return NULL;
+ g_music->setNumTicks(loopIdx, nticks);
+ RetNone;
+}
+DECL(sc_loop_setTickf) // (int loopIdx, float pos)
+{
+ int loopIdx;
+ MYFLT pos;
+ if (!PyArg_ParseTuple(args, "if", &loopIdx, &pos )) return NULL;
+ g_music->setTickf(loopIdx, pos);
+ RetNone;
+}
+DECL(sc_loop_addScoreEvent) // (int loopIdx, int id, int duration_in_ticks, char type, farray param)
+{
+ int loopIdx, qid, inticks, active;
+ char ev_type;
+ PyObject *o;
+ if (!PyArg_ParseTuple(args, "iiiicO", &loopIdx, &qid, &inticks, &active, &ev_type, &o )) return NULL;
+
+ if (o->ob_type
+ && o->ob_type->tp_as_buffer
+ && (1 == o->ob_type->tp_as_buffer->bf_getsegcount(o, NULL)))
+ {
+ if (o->ob_type->tp_as_buffer->bf_getreadbuffer)
+ {
+ void * ptr;
+ size_t len;
+ len = o->ob_type->tp_as_buffer->bf_getreadbuffer(o, 0, &ptr);
+ float * fptr = (float*)ptr;
+ size_t flen = len / sizeof(float);
+
+ g_music->addEvent(loopIdx, qid, ev_type, fptr, flen, inticks, active);
+
+ RetNone;
+ }
+ else
+ {
+ assert(!"asdf");
+ }
+ }
+ assert(!"not reached");
+ return NULL;
+}
+DECL(sc_loop_delScoreEvent) // (int loopIdx, int id)
+{
+ int loopIdx, id;
+ if (!PyArg_ParseTuple(args, "ii", &loopIdx, &id ))
+ {
+ return NULL;
+ }
+ g_music->delEvent(loopIdx, id);
+ RetNone;
+}
+DECL(sc_loop_updateEvent) // (int loopIdx, int id, int paramIdx, float paramVal, int activate_cmd))
+{
+ int loopIdx, eventId;
+ int idx;
+ float val;
+ int cmd;
+ if (!PyArg_ParseTuple(args, "iiifi", &loopIdx, &eventId, &idx, &val, &cmd)) return NULL;
+ g_music->updateEvent(loopIdx, eventId, idx, val, cmd);
+ RetNone;
+}
+DECL(sc_loop_deactivate_all) // (int id)
+{
+ int loopIdx;
+ if (!PyArg_ParseTuple(args, "i", &loopIdx)) return NULL;
+ g_music->deactivateAll(loopIdx);
+ RetNone;
+}
+DECL(sc_loop_playing) // (int loopIdx, int tf)
+{
+ int loopIdx, tf;
+ if (!PyArg_ParseTuple(args, "ii", &loopIdx, &tf )) return NULL;
+ g_music->playing(loopIdx, tf);
+ RetNone;
+}
+
+#define MDECL(s) {""#s, s, METH_VARARGS, "documentation of "#s"... nothing!"}
+static PyMethodDef SpamMethods[] = {
+ MDECL(sc_destroy),
+ MDECL(sc_initialize),
+ MDECL(sc_start),
+ MDECL(sc_stop),
+
+ MDECL(sc_setChannel),
+ MDECL(sc_inputMessage),
+ MDECL(sc_scoreEvent),
+
+ MDECL(sc_getTickf),
+ MDECL(sc_adjustTick),
+ MDECL(sc_setTickDuration),
+
+ MDECL(sc_loop_new),
+ MDECL(sc_loop_delete),
+ MDECL(sc_loop_getTickf),
+ MDECL(sc_loop_setTickf),
+ MDECL(sc_loop_setNumTicks),
+ MDECL(sc_loop_delScoreEvent),
+ MDECL(sc_loop_addScoreEvent),
+ MDECL(sc_loop_updateEvent),
+ MDECL(sc_loop_deactivate_all),
+ MDECL(sc_loop_playing),
+ {NULL, NULL, 0, NULL} /*end of list */
+};
+
+PyMODINIT_FUNC
+initaclient(void)
+{
+ (void) Py_InitModule("aclient", SpamMethods);
+}
+
+
diff --git a/common/Util/Clooper/aclient.so b/common/Util/Clooper/aclient.so
new file mode 100755
index 0000000..996e9e3
--- /dev/null
+++ b/common/Util/Clooper/aclient.so
Binary files differ
diff --git a/common/Util/Clooper/audio.cpp b/common/Util/Clooper/audio.cpp
new file mode 100644
index 0000000..343bc99
--- /dev/null
+++ b/common/Util/Clooper/audio.cpp
@@ -0,0 +1,223 @@
+#ifndef AUDIO_HXX
+#define AUDIO_HXX
+
+/*
+ * Latency test program
+ *
+ * Author: Jaroslav Kysela <perex@suse.cz>
+ *
+ * This small demo program can be used for measuring latency between
+ * capture and playback. This latency is measured from driver (diff when
+ * playback and capture was started). Scheduler is set to SCHED_RR.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sched.h>
+#include <errno.h>
+#include <getopt.h>
+#include <sys/time.h>
+#include <math.h>
+
+#include <string>
+#include <alsa/asoundlib.h>
+
+#define ERROR_HERE ll->printf("ERROR_HERE: %s %i\n", __FILE__, __LINE__)
+
+struct SystemStuff
+{
+ log_t * ll;
+
+ snd_pcm_t *phandle;
+ snd_pcm_uframes_t period_size;
+ unsigned int rate;
+ const snd_pcm_format_t sample_format;
+ SystemStuff(log_t * ll) : ll(ll), phandle(NULL), period_size(0), rate(0), sample_format(SND_PCM_FORMAT_S16)
+ {
+ }
+ ~SystemStuff()
+ {
+ if (phandle) close(0);
+ }
+
+ void setscheduler(void)
+ {
+ struct sched_param sched_param;
+
+ if (sched_getparam(0, &sched_param) < 0) {
+ ll->printf( "Scheduler getparam failed...\n");
+ return;
+ }
+ sched_param.sched_priority = sched_get_priority_max(SCHED_RR);
+ if (!sched_setscheduler(0, SCHED_RR, &sched_param)) {
+ ll->printf( "Scheduler set to Round Robin with priority %i...\n", sched_param.sched_priority);
+ return;
+ }
+ ll->printf( "!!!Scheduler set to Round Robin with priority %i FAILED!!!\n", sched_param.sched_priority);
+ }
+
+ int open(unsigned int rate0, int upsample_max, snd_pcm_uframes_t period0, unsigned int p_per_buff)
+ {
+ snd_pcm_hw_params_t *hw;
+
+ if (phandle)
+ {
+ ll->printf( "ERROR: open called twice! First close the sound device\n");
+ return -1;
+ }
+
+ if ( 0 > snd_pcm_open(&phandle, "default", SND_PCM_STREAM_PLAYBACK, 0)) { ERROR_HERE; return -1; }
+ if ( 0 > snd_pcm_hw_params_malloc(&hw)) { ERROR_HERE; snd_pcm_close(phandle); phandle = NULL; return -1; }
+
+ //now we can be a bit flexible with the buffer size and the sample-rate...
+
+ int upsample;
+ for (upsample = 1; upsample < upsample_max; ++upsample)
+ {
+ rate = rate0 * upsample;
+
+ if ( 0 > snd_pcm_hw_params_any(phandle, hw)) { ERROR_HERE; goto open_error;}
+
+ //first do the compulsory steps... interleaved float, 2 channel
+ if ( 0 > snd_pcm_hw_params_set_rate_resample(phandle, hw, 0)) { ERROR_HERE; goto open_error;}
+ if ( 0 > snd_pcm_hw_params_test_access(phandle, hw, SND_PCM_ACCESS_RW_INTERLEAVED)){ ERROR_HERE; goto open_error;}
+ if ( 0 > snd_pcm_hw_params_set_access(phandle, hw, SND_PCM_ACCESS_RW_INTERLEAVED)){ ERROR_HERE; goto open_error;}
+ if ( 0 > snd_pcm_hw_params_test_format(phandle, hw, sample_format)) { ERROR_HERE; goto open_error;}
+ if ( 0 > snd_pcm_hw_params_set_format(phandle, hw, sample_format)) { ERROR_HERE; goto open_error;}
+ if ( 0 > snd_pcm_hw_params_set_channels(phandle, hw, 2)) { ERROR_HERE; goto open_error;}
+
+ if ( snd_pcm_hw_params_test_rate(phandle, hw, rate, 0))
+ {
+ ll->printf("test_rate failed( %i\n", rate);
+ continue;
+ }
+ else
+ {
+ ll->printf(1, "success! setting rate : %i\n", rate);
+ if (0 > snd_pcm_hw_params_set_rate(phandle, hw, rate, 0)) { ERROR_HERE; goto open_error;}
+
+ snd_pcm_uframes_t minb=0, maxb= 0;
+ int mind=0, maxd=0;
+ snd_pcm_hw_params_get_period_size_min(hw, &minb,&mind);
+ snd_pcm_hw_params_get_period_size_max(hw, &maxb,&maxd);
+ ll->printf(2, "FYI: period size range is [%li/%i,%li/%i]\n", minb,mind, maxb, maxd);
+
+ assert(mind == 0); //rate_resample 0 makes this true right?
+ assert(maxd == 0); //rate_resample 0 makes this true right?
+
+ if (period0 < minb)
+ {
+ ll->printf(1, "requested period size (%li) < min (%li), adjusting to min\n", period_size, minb);
+ period_size = minb;
+ }
+ else if (period0 > maxb)
+ {
+ ll->printf(2, "requested period size (%li) < max (%li), adjusting to min\n", period_size, maxb);
+ period_size = maxb;
+ }
+ else
+ {
+ period_size = period0;
+ }
+
+ ll->printf(1, "testing period size : %li\n", period_size);
+ if ( 0 > snd_pcm_hw_params_test_period_size(phandle, hw, period_size, 0)){ ERROR_HERE; goto open_error;}
+
+
+ ll->printf(1, "setting period size : %li\n", period_size);
+ if ( 0 > snd_pcm_hw_params_set_period_size(phandle, hw, period_size, 0)){ ERROR_HERE; goto open_error;}
+
+ ll->printf(1, "setting buffer size : %i * %li = %li\n", p_per_buff, period_size, p_per_buff * period_size);
+ if ( 0 > snd_pcm_hw_params_set_buffer_size(phandle, hw, p_per_buff*period_size)) { ERROR_HERE; goto open_error;}
+
+ break;
+ }
+ }
+
+ if (upsample_max == upsample) { ERROR_HERE; goto open_error; }
+
+ if (0 > snd_pcm_hw_params(phandle, hw)) { ERROR_HERE; goto open_error; }
+
+ snd_pcm_hw_params_free (hw);
+ return 0;
+
+open_error:
+ snd_pcm_hw_params_free (hw);
+ snd_pcm_close(phandle);
+ phandle = NULL;
+ return -1;
+ }
+ void close(int drain = 0)
+ {
+ if (!phandle)
+ {
+ ll->printf(0, "WARNING: attempt to close already-closed pcm\n");
+ return;
+ }
+ ll->printf(1, "INFO: closing phandle device\n");
+ if (drain) snd_pcm_drain(phandle);
+ snd_pcm_close(phandle);
+ phandle = NULL;
+ }
+ void prepare()
+ {
+ if (!phandle)
+ {
+ ll->printf(0, "ERROR: attempt to prepare a closed pcm\n");
+ return;
+ }
+ if (0 > snd_pcm_prepare(phandle)) { ERROR_HERE; }
+ }
+ int writebuf(snd_pcm_uframes_t frame_count, short int * frame_data)
+ {
+ if (!phandle)
+ {
+ ll->printf(0, "ERROR: attempt to write a closed phandle\n");
+ return -1;
+ }
+ int err;
+ err = snd_pcm_writei (phandle, frame_data, frame_count );
+ if (err == (signed)frame_count) return 0; //success
+
+ assert(err < 0);
+
+ const char * msg = NULL;
+ snd_pcm_state_t state = snd_pcm_state(phandle);
+ switch (state)
+ {
+ case SND_PCM_STATE_OPEN: msg = "open"; break;
+ case SND_PCM_STATE_SETUP: msg = "setup"; break;
+ case SND_PCM_STATE_PREPARED:msg = "prepared"; break;
+ case SND_PCM_STATE_RUNNING: msg = "running"; break;
+ case SND_PCM_STATE_XRUN: msg = "xrun"; break;
+ case SND_PCM_STATE_DRAINING: msg = "draining"; break;
+ case SND_PCM_STATE_PAUSED: msg = "paused"; break;
+ case SND_PCM_STATE_SUSPENDED: msg = "suspended"; break;
+ case SND_PCM_STATE_DISCONNECTED: msg = "disconnected"; break;
+ }
+ ll->printf(1, "WARNING: write failed (%s)\tstate = %s\ttime=%lf\n", snd_strerror (err), msg, pytime(NULL));
+ if (0 > snd_pcm_recover(phandle, err, 0)) { ERROR_HERE; return err;}
+ if (0 > snd_pcm_prepare(phandle)) { ERROR_HERE; return err;}
+ return 1; //warning
+ }
+};
+#undef ERROR_HERE
+
+#endif
diff --git a/common/Util/Clooper/cmd_csound.cpp b/common/Util/Clooper/cmd_csound.cpp
new file mode 100644
index 0000000..ef94f84
--- /dev/null
+++ b/common/Util/Clooper/cmd_csound.cpp
@@ -0,0 +1,22 @@
+
+#include <stdio.h>
+#include <csound/csound.hpp>
+
+#include "SoundClient.h"
+
+int main( int argc, char ** argv)
+{
+ int userInput = 200;
+ int rval = sc_initialize(argv[1]);
+ sc_setMasterVolume(30.0);
+
+ while ((userInput != 0) && (rval == 0))
+ {
+ fprintf(stderr, "Enter a pitch\n");
+ scanf("%i", &userInput);
+ //sc_instrumentLoad(5083, "/home/olpc/tamtam/Resources/Sounds/sitar");
+ scanf("%i", &userInput);
+ }
+
+ return 0;
+}
diff --git a/common/Util/Clooper/log.cpp b/common/Util/Clooper/log.cpp
new file mode 100644
index 0000000..d4a8c72
--- /dev/null
+++ b/common/Util/Clooper/log.cpp
@@ -0,0 +1,52 @@
+#ifndef LOG_HXX
+#define LOG_HXX
+
+#include <stdarg.h>
+#include <stdio.h>
+
+struct log_t
+{
+ FILE * _file;
+ int _level;
+ int _close;
+
+ log_t(const char * logpath, int level = 0) : _file(NULL), _level(level), _close(1)
+ {
+ _file = fopen(logpath, "w");
+ if (!_file)
+ {
+ fprintf(stderr, "Failed to open log file for writing: %s\n", logpath);
+ }
+ }
+ log_t(FILE * file, int level = 0): _file(file), _level(level), _close(0)
+ {
+ }
+ ~log_t()
+ {
+ if (_close && _file) fclose(_file);
+ }
+ void printf( const char * fmt, ... ) __attribute__(( format (printf, 2,3)))
+ {
+ if (!_file) return;
+ va_list ap;
+ va_start(ap,fmt);
+ ::vfprintf(_file, fmt, ap);
+ va_end(ap);
+ fflush(_file);
+ }
+ void printf( int level, const char * fmt, ... ) __attribute__(( format (printf, 3,4)))
+ {
+ if (level <= _level)
+ {
+ if (!_file) return;
+ fprintf(_file, "L%i:", level);
+ va_list ap;
+ va_start(ap,fmt);
+ ::vfprintf(_file, fmt, ap);
+ va_end(ap);
+ fflush(_file);
+ }
+ }
+};
+
+#endif
diff --git a/common/Util/Clooper/ttest.c b/common/Util/Clooper/ttest.c
new file mode 100644
index 0000000..9ff3d85
--- /dev/null
+++ b/common/Util/Clooper/ttest.c
@@ -0,0 +1,53 @@
+
+#include <pthread.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+double sleeptime = 0.0;
+int usleep(int);
+static void * threadfn(void * _arg)
+{
+ double pytime(const struct timeval * tv)
+ {
+ return (double) tv->tv_sec + (double) tv->tv_usec / 1000000.0;
+ }
+ struct timeval tv0, tv1;
+ double m = 0.0;
+
+ int loops = 0;
+
+ while (1)
+ {
+ gettimeofday(&tv0, 0);
+ usleep( (int) (sleeptime * 1000000) );
+ gettimeofday(&tv1, 0);
+ double t0 = pytime(&tv0);
+ double t1 = pytime(&tv1);
+ if (t1 - t0 > 1.2 * sleeptime)
+ {
+ fprintf(stderr, "critical lagginess %lf\n", t1 - t0);
+ }
+ if (m < t1 - t0)
+ {
+ m = t1 - t0;
+ fprintf(stderr, "maximum lag %lf\n", m);
+ }
+
+ if ( ( loops % 100 ) == 0 )
+ {
+ fprintf(stderr, "loop (%lf)\n", t0);
+ }
+ ++loops;
+ }
+ return NULL;
+}
+void testtimer(double st)
+{
+ pthread_t pth;
+ sleeptime = st;
+
+ pthread_create( &pth, NULL, &threadfn, NULL );
+}
+
diff --git a/common/Util/Clooper/ttest.h b/common/Util/Clooper/ttest.h
new file mode 100644
index 0000000..111f10c
--- /dev/null
+++ b/common/Util/Clooper/ttest.h
@@ -0,0 +1,15 @@
+#ifndef _MSL_MATH_H
+#define _MSL_MATH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void testtimer(double);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/common/Util/Clooper/ttest.i b/common/Util/Clooper/ttest.i
new file mode 100644
index 0000000..0c88add
--- /dev/null
+++ b/common/Util/Clooper/ttest.i
@@ -0,0 +1,15 @@
+
+%module ttest
+
+%{
+#define SWIG_FILE_WITH_INIT
+#include "ttest.h"
+%}
+
+%pythoncode
+%{
+def somefn(seed, mat):
+
+%}
+
+%include "ttest.h"
diff --git a/common/Util/Clooper/ttest.py b/common/Util/Clooper/ttest.py
new file mode 100644
index 0000000..302c8f3
--- /dev/null
+++ b/common/Util/Clooper/ttest.py
@@ -0,0 +1,54 @@
+# This file was automatically generated by SWIG (http://www.swig.org).
+# Version 1.3.31
+#
+# Don't modify this file, modify the SWIG interface instead.
+# This file is compatible with both classic and new-style classes.
+
+import _ttest
+import new
+new_instancemethod = new.instancemethod
+try:
+ _swig_property = property
+except NameError:
+ pass # Python < 2.2 doesn't have 'property'.
+def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
+ if (name == "thisown"): return self.this.own(value)
+ if (name == "this"):
+ if type(value).__name__ == 'PySwigObject':
+ self.__dict__[name] = value
+ return
+ method = class_type.__swig_setmethods__.get(name,None)
+ if method: return method(self,value)
+ if (not static) or hasattr(self,name):
+ self.__dict__[name] = value
+ else:
+ raise AttributeError("You cannot add attributes to %s" % self)
+
+def _swig_setattr(self,class_type,name,value):
+ return _swig_setattr_nondynamic(self,class_type,name,value,0)
+
+def _swig_getattr(self,class_type,name):
+ if (name == "thisown"): return self.this.own()
+ method = class_type.__swig_getmethods__.get(name,None)
+ if method: return method(self)
+ raise AttributeError,name
+
+def _swig_repr(self):
+ try: strthis = "proxy of " + self.this.__repr__()
+ except: strthis = ""
+ return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
+
+import types
+try:
+ _object = types.ObjectType
+ _newclass = 1
+except AttributeError:
+ class _object : pass
+ _newclass = 0
+del types
+
+
+
+testtimer = _ttest.testtimer
+
+
diff --git a/common/Util/Clooper/ttest_wrap.c b/common/Util/Clooper/ttest_wrap.c
new file mode 100644
index 0000000..a073e99
--- /dev/null
+++ b/common/Util/Clooper/ttest_wrap.c
@@ -0,0 +1,3042 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 1.3.31
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+#define SWIGPYTHON
+#define SWIG_PYTHON_DIRECTOR_NO_VTABLE
+/* -----------------------------------------------------------------------------
+ * This section contains generic SWIG labels for method/variable
+ * declarations/attributes, and other compiler dependent labels.
+ * ----------------------------------------------------------------------------- */
+
+/* template workaround for compilers that cannot correctly implement the C++ standard */
+#ifndef SWIGTEMPLATEDISAMBIGUATOR
+# if defined(__SUNPRO_CC)
+# if (__SUNPRO_CC <= 0x560)
+# define SWIGTEMPLATEDISAMBIGUATOR template
+# else
+# define SWIGTEMPLATEDISAMBIGUATOR
+# endif
+# else
+# define SWIGTEMPLATEDISAMBIGUATOR
+# endif
+#endif
+
+/* inline attribute */
+#ifndef SWIGINLINE
+# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
+# define SWIGINLINE inline
+# else
+# define SWIGINLINE
+# endif
+#endif
+
+/* attribute recognised by some compilers to avoid 'unused' warnings */
+#ifndef SWIGUNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define SWIGUNUSED __attribute__ ((__unused__))
+# else
+# define SWIGUNUSED
+# endif
+# elif defined(__ICC)
+# define SWIGUNUSED __attribute__ ((__unused__))
+# else
+# define SWIGUNUSED
+# endif
+#endif
+
+#ifndef SWIGUNUSEDPARM
+# ifdef __cplusplus
+# define SWIGUNUSEDPARM(p)
+# else
+# define SWIGUNUSEDPARM(p) p SWIGUNUSED
+# endif
+#endif
+
+/* internal SWIG method */
+#ifndef SWIGINTERN
+# define SWIGINTERN static SWIGUNUSED
+#endif
+
+/* internal inline SWIG method */
+#ifndef SWIGINTERNINLINE
+# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE
+#endif
+
+/* exporting methods */
+#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+# ifndef GCC_HASCLASSVISIBILITY
+# define GCC_HASCLASSVISIBILITY
+# endif
+#endif
+
+#ifndef SWIGEXPORT
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# if defined(STATIC_LINKED)
+# define SWIGEXPORT
+# else
+# define SWIGEXPORT __declspec(dllexport)
+# endif
+# else
+# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
+# define SWIGEXPORT __attribute__ ((visibility("default")))
+# else
+# define SWIGEXPORT
+# endif
+# endif
+#endif
+
+/* calling conventions for Windows */
+#ifndef SWIGSTDCALL
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# define SWIGSTDCALL __stdcall
+# else
+# define SWIGSTDCALL
+# endif
+#endif
+
+/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
+#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+
+/* Python.h has to appear first */
+#include <Python.h>
+
+/* -----------------------------------------------------------------------------
+ * swigrun.swg
+ *
+ * This file contains generic CAPI SWIG runtime support for pointer
+ * type checking.
+ * ----------------------------------------------------------------------------- */
+
+/* This should only be incremented when either the layout of swig_type_info changes,
+ or for whatever reason, the runtime changes incompatibly */
+#define SWIG_RUNTIME_VERSION "3"
+
+/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
+#ifdef SWIG_TYPE_TABLE
+# define SWIG_QUOTE_STRING(x) #x
+# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x)
+# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE)
+#else
+# define SWIG_TYPE_TABLE_NAME
+#endif
+
+/*
+ You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
+ creating a static or dynamic library from the swig runtime code.
+ In 99.9% of the cases, swig just needs to declare them as 'static'.
+
+ But only do this if is strictly necessary, ie, if you have problems
+ with your compiler or so.
+*/
+
+#ifndef SWIGRUNTIME
+# define SWIGRUNTIME SWIGINTERN
+#endif
+
+#ifndef SWIGRUNTIMEINLINE
+# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE
+#endif
+
+/* Generic buffer size */
+#ifndef SWIG_BUFFER_SIZE
+# define SWIG_BUFFER_SIZE 1024
+#endif
+
+/* Flags for pointer conversions */
+#define SWIG_POINTER_DISOWN 0x1
+
+/* Flags for new pointer objects */
+#define SWIG_POINTER_OWN 0x1
+
+
+/*
+ Flags/methods for returning states.
+
+ The swig conversion methods, as ConvertPtr, return and integer
+ that tells if the conversion was successful or not. And if not,
+ an error code can be returned (see swigerrors.swg for the codes).
+
+ Use the following macros/flags to set or process the returning
+ states.
+
+ In old swig versions, you usually write code as:
+
+ if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) {
+ // success code
+ } else {
+ //fail code
+ }
+
+ Now you can be more explicit as:
+
+ int res = SWIG_ConvertPtr(obj,vptr,ty.flags);
+ if (SWIG_IsOK(res)) {
+ // success code
+ } else {
+ // fail code
+ }
+
+ that seems to be the same, but now you can also do
+
+ Type *ptr;
+ int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags);
+ if (SWIG_IsOK(res)) {
+ // success code
+ if (SWIG_IsNewObj(res) {
+ ...
+ delete *ptr;
+ } else {
+ ...
+ }
+ } else {
+ // fail code
+ }
+
+ I.e., now SWIG_ConvertPtr can return new objects and you can
+ identify the case and take care of the deallocation. Of course that
+ requires also to SWIG_ConvertPtr to return new result values, as
+
+ int SWIG_ConvertPtr(obj, ptr,...) {
+ if (<obj is ok>) {
+ if (<need new object>) {
+ *ptr = <ptr to new allocated object>;
+ return SWIG_NEWOBJ;
+ } else {
+ *ptr = <ptr to old object>;
+ return SWIG_OLDOBJ;
+ }
+ } else {
+ return SWIG_BADOBJ;
+ }
+ }
+
+ Of course, returning the plain '0(success)/-1(fail)' still works, but you can be
+ more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the
+ swig errors code.
+
+ Finally, if the SWIG_CASTRANK_MODE is enabled, the result code
+ allows to return the 'cast rank', for example, if you have this
+
+ int food(double)
+ int fooi(int);
+
+ and you call
+
+ food(1) // cast rank '1' (1 -> 1.0)
+ fooi(1) // cast rank '0'
+
+ just use the SWIG_AddCast()/SWIG_CheckState()
+
+
+ */
+#define SWIG_OK (0)
+#define SWIG_ERROR (-1)
+#define SWIG_IsOK(r) (r >= 0)
+#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError)
+
+/* The CastRankLimit says how many bits are used for the cast rank */
+#define SWIG_CASTRANKLIMIT (1 << 8)
+/* The NewMask denotes the object was created (using new/malloc) */
+#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1)
+/* The TmpMask is for in/out typemaps that use temporal objects */
+#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1)
+/* Simple returning values */
+#define SWIG_BADOBJ (SWIG_ERROR)
+#define SWIG_OLDOBJ (SWIG_OK)
+#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK)
+#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK)
+/* Check, add and del mask methods */
+#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r)
+#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r)
+#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK))
+#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r)
+#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r)
+#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK))
+
+
+/* Cast-Rank Mode */
+#if defined(SWIG_CASTRANK_MODE)
+# ifndef SWIG_TypeRank
+# define SWIG_TypeRank unsigned long
+# endif
+# ifndef SWIG_MAXCASTRANK /* Default cast allowed */
+# define SWIG_MAXCASTRANK (2)
+# endif
+# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1)
+# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK)
+SWIGINTERNINLINE int SWIG_AddCast(int r) {
+ return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r;
+}
+SWIGINTERNINLINE int SWIG_CheckState(int r) {
+ return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0;
+}
+#else /* no cast-rank mode */
+# define SWIG_AddCast
+# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0)
+#endif
+
+
+
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *(*swig_converter_func)(void *);
+typedef struct swig_type_info *(*swig_dycast_func)(void **);
+
+/* Structure to store inforomation on one type */
+typedef struct swig_type_info {
+ const char *name; /* mangled name of this type */
+ const char *str; /* human readable name of this type */
+ swig_dycast_func dcast; /* dynamic cast function down a hierarchy */
+ struct swig_cast_info *cast; /* linked list of types that can cast into this type */
+ void *clientdata; /* language specific type data */
+ int owndata; /* flag if the structure owns the clientdata */
+} swig_type_info;
+
+/* Structure to store a type and conversion function used for casting */
+typedef struct swig_cast_info {
+ swig_type_info *type; /* pointer to type that is equivalent to this type */
+ swig_converter_func converter; /* function to cast the void pointers */
+ struct swig_cast_info *next; /* pointer to next cast in linked list */
+ struct swig_cast_info *prev; /* pointer to the previous cast */
+} swig_cast_info;
+
+/* Structure used to store module information
+ * Each module generates one structure like this, and the runtime collects
+ * all of these structures and stores them in a circularly linked list.*/
+typedef struct swig_module_info {
+ swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */
+ size_t size; /* Number of types in this module */
+ struct swig_module_info *next; /* Pointer to next element in circularly linked list */
+ swig_type_info **type_initial; /* Array of initially generated type structures */
+ swig_cast_info **cast_initial; /* Array of initially generated casting structures */
+ void *clientdata; /* Language specific module data */
+} swig_module_info;
+
+/*
+ Compare two type names skipping the space characters, therefore
+ "char*" == "char *" and "Class<int>" == "Class<int >", etc.
+
+ Return 0 when the two name types are equivalent, as in
+ strncmp, but skipping ' '.
+*/
+SWIGRUNTIME int
+SWIG_TypeNameComp(const char *f1, const char *l1,
+ const char *f2, const char *l2) {
+ for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) {
+ while ((*f1 == ' ') && (f1 != l1)) ++f1;
+ while ((*f2 == ' ') && (f2 != l2)) ++f2;
+ if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1;
+ }
+ return (l1 - f1) - (l2 - f2);
+}
+
+/*
+ Check type equivalence in a name list like <name1>|<name2>|...
+ Return 0 if not equal, 1 if equal
+*/
+SWIGRUNTIME int
+SWIG_TypeEquiv(const char *nb, const char *tb) {
+ int equiv = 0;
+ const char* te = tb + strlen(tb);
+ const char* ne = nb;
+ while (!equiv && *ne) {
+ for (nb = ne; *ne; ++ne) {
+ if (*ne == '|') break;
+ }
+ equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
+ if (*ne) ++ne;
+ }
+ return equiv;
+}
+
+/*
+ Check type equivalence in a name list like <name1>|<name2>|...
+ Return 0 if equal, -1 if nb < tb, 1 if nb > tb
+*/
+SWIGRUNTIME int
+SWIG_TypeCompare(const char *nb, const char *tb) {
+ int equiv = 0;
+ const char* te = tb + strlen(tb);
+ const char* ne = nb;
+ while (!equiv && *ne) {
+ for (nb = ne; *ne; ++ne) {
+ if (*ne == '|') break;
+ }
+ equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
+ if (*ne) ++ne;
+ }
+ return equiv;
+}
+
+
+/* think of this as a c++ template<> or a scheme macro */
+#define SWIG_TypeCheck_Template(comparison, ty) \
+ if (ty) { \
+ swig_cast_info *iter = ty->cast; \
+ while (iter) { \
+ if (comparison) { \
+ if (iter == ty->cast) return iter; \
+ /* Move iter to the top of the linked list */ \
+ iter->prev->next = iter->next; \
+ if (iter->next) \
+ iter->next->prev = iter->prev; \
+ iter->next = ty->cast; \
+ iter->prev = 0; \
+ if (ty->cast) ty->cast->prev = iter; \
+ ty->cast = iter; \
+ return iter; \
+ } \
+ iter = iter->next; \
+ } \
+ } \
+ return 0
+
+/*
+ Check the typename
+*/
+SWIGRUNTIME swig_cast_info *
+SWIG_TypeCheck(const char *c, swig_type_info *ty) {
+ SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty);
+}
+
+/* Same as previous function, except strcmp is replaced with a pointer comparison */
+SWIGRUNTIME swig_cast_info *
+SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) {
+ SWIG_TypeCheck_Template(iter->type == from, into);
+}
+
+/*
+ Cast a pointer up an inheritance hierarchy
+*/
+SWIGRUNTIMEINLINE void *
+SWIG_TypeCast(swig_cast_info *ty, void *ptr) {
+ return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr);
+}
+
+/*
+ Dynamic pointer casting. Down an inheritance hierarchy
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) {
+ swig_type_info *lastty = ty;
+ if (!ty || !ty->dcast) return ty;
+ while (ty && (ty->dcast)) {
+ ty = (*ty->dcast)(ptr);
+ if (ty) lastty = ty;
+ }
+ return lastty;
+}
+
+/*
+ Return the name associated with this type
+*/
+SWIGRUNTIMEINLINE const char *
+SWIG_TypeName(const swig_type_info *ty) {
+ return ty->name;
+}
+
+/*
+ Return the pretty name associated with this type,
+ that is an unmangled type name in a form presentable to the user.
+*/
+SWIGRUNTIME const char *
+SWIG_TypePrettyName(const swig_type_info *type) {
+ /* The "str" field contains the equivalent pretty names of the
+ type, separated by vertical-bar characters. We choose
+ to print the last name, as it is often (?) the most
+ specific. */
+ if (!type) return NULL;
+ if (type->str != NULL) {
+ const char *last_name = type->str;
+ const char *s;
+ for (s = type->str; *s; s++)
+ if (*s == '|') last_name = s+1;
+ return last_name;
+ }
+ else
+ return type->name;
+}
+
+/*
+ Set the clientdata field for a type
+*/
+SWIGRUNTIME void
+SWIG_TypeClientData(swig_type_info *ti, void *clientdata) {
+ swig_cast_info *cast = ti->cast;
+ /* if (ti->clientdata == clientdata) return; */
+ ti->clientdata = clientdata;
+
+ while (cast) {
+ if (!cast->converter) {
+ swig_type_info *tc = cast->type;
+ if (!tc->clientdata) {
+ SWIG_TypeClientData(tc, clientdata);
+ }
+ }
+ cast = cast->next;
+ }
+}
+SWIGRUNTIME void
+SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) {
+ SWIG_TypeClientData(ti, clientdata);
+ ti->owndata = 1;
+}
+
+/*
+ Search for a swig_type_info structure only by mangled name
+ Search is a O(log #types)
+
+ We start searching at module start, and finish searching when start == end.
+ Note: if start == end at the beginning of the function, we go all the way around
+ the circular list.
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_MangledTypeQueryModule(swig_module_info *start,
+ swig_module_info *end,
+ const char *name) {
+ swig_module_info *iter = start;
+ do {
+ if (iter->size) {
+ register size_t l = 0;
+ register size_t r = iter->size - 1;
+ do {
+ /* since l+r >= 0, we can (>> 1) instead (/ 2) */
+ register size_t i = (l + r) >> 1;
+ const char *iname = iter->types[i]->name;
+ if (iname) {
+ register int compare = strcmp(name, iname);
+ if (compare == 0) {
+ return iter->types[i];
+ } else if (compare < 0) {
+ if (i) {
+ r = i - 1;
+ } else {
+ break;
+ }
+ } else if (compare > 0) {
+ l = i + 1;
+ }
+ } else {
+ break; /* should never happen */
+ }
+ } while (l <= r);
+ }
+ iter = iter->next;
+ } while (iter != end);
+ return 0;
+}
+
+/*
+ Search for a swig_type_info structure for either a mangled name or a human readable name.
+ It first searches the mangled names of the types, which is a O(log #types)
+ If a type is not found it then searches the human readable names, which is O(#types).
+
+ We start searching at module start, and finish searching when start == end.
+ Note: if start == end at the beginning of the function, we go all the way around
+ the circular list.
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_TypeQueryModule(swig_module_info *start,
+ swig_module_info *end,
+ const char *name) {
+ /* STEP 1: Search the name field using binary search */
+ swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name);
+ if (ret) {
+ return ret;
+ } else {
+ /* STEP 2: If the type hasn't been found, do a complete search
+ of the str field (the human readable name) */
+ swig_module_info *iter = start;
+ do {
+ register size_t i = 0;
+ for (; i < iter->size; ++i) {
+ if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name)))
+ return iter->types[i];
+ }
+ iter = iter->next;
+ } while (iter != end);
+ }
+
+ /* neither found a match */
+ return 0;
+}
+
+/*
+ Pack binary data into a string
+*/
+SWIGRUNTIME char *
+SWIG_PackData(char *c, void *ptr, size_t sz) {
+ static const char hex[17] = "0123456789abcdef";
+ register const unsigned char *u = (unsigned char *) ptr;
+ register const unsigned char *eu = u + sz;
+ for (; u != eu; ++u) {
+ register unsigned char uu = *u;
+ *(c++) = hex[(uu & 0xf0) >> 4];
+ *(c++) = hex[uu & 0xf];
+ }
+ return c;
+}
+
+/*
+ Unpack binary data from a string
+*/
+SWIGRUNTIME const char *
+SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
+ register unsigned char *u = (unsigned char *) ptr;
+ register const unsigned char *eu = u + sz;
+ for (; u != eu; ++u) {
+ register char d = *(c++);
+ register unsigned char uu;
+ if ((d >= '0') && (d <= '9'))
+ uu = ((d - '0') << 4);
+ else if ((d >= 'a') && (d <= 'f'))
+ uu = ((d - ('a'-10)) << 4);
+ else
+ return (char *) 0;
+ d = *(c++);
+ if ((d >= '0') && (d <= '9'))
+ uu |= (d - '0');
+ else if ((d >= 'a') && (d <= 'f'))
+ uu |= (d - ('a'-10));
+ else
+ return (char *) 0;
+ *u = uu;
+ }
+ return c;
+}
+
+/*
+ Pack 'void *' into a string buffer.
+*/
+SWIGRUNTIME char *
+SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) {
+ char *r = buff;
+ if ((2*sizeof(void *) + 2) > bsz) return 0;
+ *(r++) = '_';
+ r = SWIG_PackData(r,&ptr,sizeof(void *));
+ if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
+ strcpy(r,name);
+ return buff;
+}
+
+SWIGRUNTIME const char *
+SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) {
+ if (*c != '_') {
+ if (strcmp(c,"NULL") == 0) {
+ *ptr = (void *) 0;
+ return name;
+ } else {
+ return 0;
+ }
+ }
+ return SWIG_UnpackData(++c,ptr,sizeof(void *));
+}
+
+SWIGRUNTIME char *
+SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) {
+ char *r = buff;
+ size_t lname = (name ? strlen(name) : 0);
+ if ((2*sz + 2 + lname) > bsz) return 0;
+ *(r++) = '_';
+ r = SWIG_PackData(r,ptr,sz);
+ if (lname) {
+ strncpy(r,name,lname+1);
+ } else {
+ *r = 0;
+ }
+ return buff;
+}
+
+SWIGRUNTIME const char *
+SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
+ if (*c != '_') {
+ if (strcmp(c,"NULL") == 0) {
+ memset(ptr,0,sz);
+ return name;
+ } else {
+ return 0;
+ }
+ }
+ return SWIG_UnpackData(++c,ptr,sz);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Errors in SWIG */
+#define SWIG_UnknownError -1
+#define SWIG_IOError -2
+#define SWIG_RuntimeError -3
+#define SWIG_IndexError -4
+#define SWIG_TypeError -5
+#define SWIG_DivisionByZero -6
+#define SWIG_OverflowError -7
+#define SWIG_SyntaxError -8
+#define SWIG_ValueError -9
+#define SWIG_SystemError -10
+#define SWIG_AttributeError -11
+#define SWIG_MemoryError -12
+#define SWIG_NullReferenceError -13
+
+
+
+
+/* Add PyOS_snprintf for old Pythons */
+#if PY_VERSION_HEX < 0x02020000
+# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM)
+# define PyOS_snprintf _snprintf
+# else
+# define PyOS_snprintf snprintf
+# endif
+#endif
+
+/* A crude PyString_FromFormat implementation for old Pythons */
+#if PY_VERSION_HEX < 0x02020000
+
+#ifndef SWIG_PYBUFFER_SIZE
+# define SWIG_PYBUFFER_SIZE 1024
+#endif
+
+static PyObject *
+PyString_FromFormat(const char *fmt, ...) {
+ va_list ap;
+ char buf[SWIG_PYBUFFER_SIZE * 2];
+ int res;
+ va_start(ap, fmt);
+ res = vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf);
+}
+#endif
+
+/* Add PyObject_Del for old Pythons */
+#if PY_VERSION_HEX < 0x01060000
+# define PyObject_Del(op) PyMem_DEL((op))
+#endif
+#ifndef PyObject_DEL
+# define PyObject_DEL PyObject_Del
+#endif
+
+/* A crude PyExc_StopIteration exception for old Pythons */
+#if PY_VERSION_HEX < 0x02020000
+# ifndef PyExc_StopIteration
+# define PyExc_StopIteration PyExc_RuntimeError
+# endif
+# ifndef PyObject_GenericGetAttr
+# define PyObject_GenericGetAttr 0
+# endif
+#endif
+/* Py_NotImplemented is defined in 2.1 and up. */
+#if PY_VERSION_HEX < 0x02010000
+# ifndef Py_NotImplemented
+# define Py_NotImplemented PyExc_RuntimeError
+# endif
+#endif
+
+
+/* A crude PyString_AsStringAndSize implementation for old Pythons */
+#if PY_VERSION_HEX < 0x02010000
+# ifndef PyString_AsStringAndSize
+# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;}
+# endif
+#endif
+
+/* PySequence_Size for old Pythons */
+#if PY_VERSION_HEX < 0x02000000
+# ifndef PySequence_Size
+# define PySequence_Size PySequence_Length
+# endif
+#endif
+
+
+/* PyBool_FromLong for old Pythons */
+#if PY_VERSION_HEX < 0x02030000
+static
+PyObject *PyBool_FromLong(long ok)
+{
+ PyObject *result = ok ? Py_True : Py_False;
+ Py_INCREF(result);
+ return result;
+}
+#endif
+
+/* Py_ssize_t for old Pythons */
+/* This code is as recommended by: */
+/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+# define PY_SSIZE_T_MAX INT_MAX
+# define PY_SSIZE_T_MIN INT_MIN
+#endif
+
+/* -----------------------------------------------------------------------------
+ * error manipulation
+ * ----------------------------------------------------------------------------- */
+
+SWIGRUNTIME PyObject*
+SWIG_Python_ErrorType(int code) {
+ PyObject* type = 0;
+ switch(code) {
+ case SWIG_MemoryError:
+ type = PyExc_MemoryError;
+ break;
+ case SWIG_IOError:
+ type = PyExc_IOError;
+ break;
+ case SWIG_RuntimeError:
+ type = PyExc_RuntimeError;
+ break;
+ case SWIG_IndexError:
+ type = PyExc_IndexError;
+ break;
+ case SWIG_TypeError:
+ type = PyExc_TypeError;
+ break;
+ case SWIG_DivisionByZero:
+ type = PyExc_ZeroDivisionError;
+ break;
+ case SWIG_OverflowError:
+ type = PyExc_OverflowError;
+ break;
+ case SWIG_SyntaxError:
+ type = PyExc_SyntaxError;
+ break;
+ case SWIG_ValueError:
+ type = PyExc_ValueError;
+ break;
+ case SWIG_SystemError:
+ type = PyExc_SystemError;
+ break;
+ case SWIG_AttributeError:
+ type = PyExc_AttributeError;
+ break;
+ default:
+ type = PyExc_RuntimeError;
+ }
+ return type;
+}
+
+
+SWIGRUNTIME void
+SWIG_Python_AddErrorMsg(const char* mesg)
+{
+ PyObject *type = 0;
+ PyObject *value = 0;
+ PyObject *traceback = 0;
+
+ if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback);
+ if (value) {
+ PyObject *old_str = PyObject_Str(value);
+ PyErr_Clear();
+ Py_XINCREF(type);
+ PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg);
+ Py_DECREF(old_str);
+ Py_DECREF(value);
+ } else {
+ PyErr_Format(PyExc_RuntimeError, mesg);
+ }
+}
+
+
+
+#if defined(SWIG_PYTHON_NO_THREADS)
+# if defined(SWIG_PYTHON_THREADS)
+# undef SWIG_PYTHON_THREADS
+# endif
+#endif
+#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */
+# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL)
+# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */
+# define SWIG_PYTHON_USE_GIL
+# endif
+# endif
+# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */
+# ifndef SWIG_PYTHON_INITIALIZE_THREADS
+# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads()
+# endif
+# ifdef __cplusplus /* C++ code */
+ class SWIG_Python_Thread_Block {
+ bool status;
+ PyGILState_STATE state;
+ public:
+ void end() { if (status) { PyGILState_Release(state); status = false;} }
+ SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {}
+ ~SWIG_Python_Thread_Block() { end(); }
+ };
+ class SWIG_Python_Thread_Allow {
+ bool status;
+ PyThreadState *save;
+ public:
+ void end() { if (status) { PyEval_RestoreThread(save); status = false; }}
+ SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {}
+ ~SWIG_Python_Thread_Allow() { end(); }
+ };
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block
+# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end()
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow
+# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end()
+# else /* C code */
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure()
+# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block)
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread()
+# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow)
+# endif
+# else /* Old thread way, not implemented, user must provide it */
+# if !defined(SWIG_PYTHON_INITIALIZE_THREADS)
+# define SWIG_PYTHON_INITIALIZE_THREADS
+# endif
+# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK)
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK
+# endif
+# if !defined(SWIG_PYTHON_THREAD_END_BLOCK)
+# define SWIG_PYTHON_THREAD_END_BLOCK
+# endif
+# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW)
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW
+# endif
+# if !defined(SWIG_PYTHON_THREAD_END_ALLOW)
+# define SWIG_PYTHON_THREAD_END_ALLOW
+# endif
+# endif
+#else /* No thread support */
+# define SWIG_PYTHON_INITIALIZE_THREADS
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK
+# define SWIG_PYTHON_THREAD_END_BLOCK
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW
+# define SWIG_PYTHON_THREAD_END_ALLOW
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Python API portion that goes into the runtime
+ * ----------------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* cc-mode */
+#endif
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Constant declarations
+ * ----------------------------------------------------------------------------- */
+
+/* Constant Types */
+#define SWIG_PY_POINTER 4
+#define SWIG_PY_BINARY 5
+
+/* Constant information structure */
+typedef struct swig_const_info {
+ int type;
+ char *name;
+ long lvalue;
+ double dvalue;
+ void *pvalue;
+ swig_type_info **ptype;
+} swig_const_info;
+
+#ifdef __cplusplus
+#if 0
+{ /* cc-mode */
+#endif
+}
+#endif
+
+
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * pyrun.swg
+ *
+ * This file contains the runtime support for Python modules
+ * and includes code for managing global variables and pointer
+ * type checking.
+ *
+ * ----------------------------------------------------------------------------- */
+
+/* Common SWIG API */
+
+/* for raw pointers */
+#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
+#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags)
+#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own)
+#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags)
+#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty)
+#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src)
+#define swig_owntype int
+
+/* for raw packed data */
+#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
+#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type)
+
+/* for class or struct pointers */
+#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags)
+#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags)
+
+/* for C or C++ function pointers */
+#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type)
+#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0)
+
+/* for C++ member pointers, ie, member methods */
+#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
+#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type)
+
+
+/* Runtime API */
+
+#define SWIG_GetModule(clientdata) SWIG_Python_GetModule()
+#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer)
+#define SWIG_NewClientData(obj) PySwigClientData_New(obj)
+
+#define SWIG_SetErrorObj SWIG_Python_SetErrorObj
+#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg
+#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code)
+#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg)
+#define SWIG_fail goto fail
+
+
+/* Runtime API implementation */
+
+/* Error manipulation */
+
+SWIGINTERN void
+SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) {
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ PyErr_SetObject(errtype, obj);
+ Py_DECREF(obj);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+}
+
+SWIGINTERN void
+SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) {
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ PyErr_SetString(errtype, (char *) msg);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+}
+
+#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj)
+
+/* Set a constant value */
+
+SWIGINTERN void
+SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) {
+ PyDict_SetItemString(d, (char*) name, obj);
+ Py_DECREF(obj);
+}
+
+/* Append a value to the result obj */
+
+SWIGINTERN PyObject*
+SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) {
+#if !defined(SWIG_PYTHON_OUTPUT_TUPLE)
+ if (!result) {
+ result = obj;
+ } else if (result == Py_None) {
+ Py_DECREF(result);
+ result = obj;
+ } else {
+ if (!PyList_Check(result)) {
+ PyObject *o2 = result;
+ result = PyList_New(1);
+ PyList_SetItem(result, 0, o2);
+ }
+ PyList_Append(result,obj);
+ Py_DECREF(obj);
+ }
+ return result;
+#else
+ PyObject* o2;
+ PyObject* o3;
+ if (!result) {
+ result = obj;
+ } else if (result == Py_None) {
+ Py_DECREF(result);
+ result = obj;
+ } else {
+ if (!PyTuple_Check(result)) {
+ o2 = result;
+ result = PyTuple_New(1);
+ PyTuple_SET_ITEM(result, 0, o2);
+ }
+ o3 = PyTuple_New(1);
+ PyTuple_SET_ITEM(o3, 0, obj);
+ o2 = result;
+ result = PySequence_Concat(o2, o3);
+ Py_DECREF(o2);
+ Py_DECREF(o3);
+ }
+ return result;
+#endif
+}
+
+/* Unpack the argument tuple */
+
+SWIGINTERN int
+SWIG_Python_UnpackTuple(PyObject *args, const char *name, int min, int max, PyObject **objs)
+{
+ if (!args) {
+ if (!min && !max) {
+ return 1;
+ } else {
+ PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none",
+ name, (min == max ? "" : "at least "), min);
+ return 0;
+ }
+ }
+ if (!PyTuple_Check(args)) {
+ PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple");
+ return 0;
+ } else {
+ register int l = PyTuple_GET_SIZE(args);
+ if (l < min) {
+ PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d",
+ name, (min == max ? "" : "at least "), min, l);
+ return 0;
+ } else if (l > max) {
+ PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d",
+ name, (min == max ? "" : "at most "), max, l);
+ return 0;
+ } else {
+ register int i;
+ for (i = 0; i < l; ++i) {
+ objs[i] = PyTuple_GET_ITEM(args, i);
+ }
+ for (; l < max; ++l) {
+ objs[l] = 0;
+ }
+ return i + 1;
+ }
+ }
+}
+
+/* A functor is a function object with one single object argument */
+#if PY_VERSION_HEX >= 0x02020000
+#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL);
+#else
+#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj);
+#endif
+
+/*
+ Helper for static pointer initialization for both C and C++ code, for example
+ static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...);
+*/
+#ifdef __cplusplus
+#define SWIG_STATIC_POINTER(var) var
+#else
+#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Pointer declarations
+ * ----------------------------------------------------------------------------- */
+
+/* Flags for new pointer objects */
+#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1)
+#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN)
+
+#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1)
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* cc-mode */
+#endif
+#endif
+
+/* How to access Py_None */
+#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# ifndef SWIG_PYTHON_NO_BUILD_NONE
+# ifndef SWIG_PYTHON_BUILD_NONE
+# define SWIG_PYTHON_BUILD_NONE
+# endif
+# endif
+#endif
+
+#ifdef SWIG_PYTHON_BUILD_NONE
+# ifdef Py_None
+# undef Py_None
+# define Py_None SWIG_Py_None()
+# endif
+SWIGRUNTIMEINLINE PyObject *
+_SWIG_Py_None(void)
+{
+ PyObject *none = Py_BuildValue((char*)"");
+ Py_DECREF(none);
+ return none;
+}
+SWIGRUNTIME PyObject *
+SWIG_Py_None(void)
+{
+ static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None();
+ return none;
+}
+#endif
+
+/* The python void return value */
+
+SWIGRUNTIMEINLINE PyObject *
+SWIG_Py_Void(void)
+{
+ PyObject *none = Py_None;
+ Py_INCREF(none);
+ return none;
+}
+
+/* PySwigClientData */
+
+typedef struct {
+ PyObject *klass;
+ PyObject *newraw;
+ PyObject *newargs;
+ PyObject *destroy;
+ int delargs;
+ int implicitconv;
+} PySwigClientData;
+
+SWIGRUNTIMEINLINE int
+SWIG_Python_CheckImplicit(swig_type_info *ty)
+{
+ PySwigClientData *data = (PySwigClientData *)ty->clientdata;
+ return data ? data->implicitconv : 0;
+}
+
+SWIGRUNTIMEINLINE PyObject *
+SWIG_Python_ExceptionType(swig_type_info *desc) {
+ PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0;
+ PyObject *klass = data ? data->klass : 0;
+ return (klass ? klass : PyExc_RuntimeError);
+}
+
+
+SWIGRUNTIME PySwigClientData *
+PySwigClientData_New(PyObject* obj)
+{
+ if (!obj) {
+ return 0;
+ } else {
+ PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData));
+ /* the klass element */
+ data->klass = obj;
+ Py_INCREF(data->klass);
+ /* the newraw method and newargs arguments used to create a new raw instance */
+ if (PyClass_Check(obj)) {
+ data->newraw = 0;
+ data->newargs = obj;
+ Py_INCREF(obj);
+ } else {
+#if (PY_VERSION_HEX < 0x02020000)
+ data->newraw = 0;
+#else
+ data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__");
+#endif
+ if (data->newraw) {
+ Py_INCREF(data->newraw);
+ data->newargs = PyTuple_New(1);
+ PyTuple_SetItem(data->newargs, 0, obj);
+ } else {
+ data->newargs = obj;
+ }
+ Py_INCREF(data->newargs);
+ }
+ /* the destroy method, aka as the C++ delete method */
+ data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__");
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ data->destroy = 0;
+ }
+ if (data->destroy) {
+ int flags;
+ Py_INCREF(data->destroy);
+ flags = PyCFunction_GET_FLAGS(data->destroy);
+#ifdef METH_O
+ data->delargs = !(flags & (METH_O));
+#else
+ data->delargs = 0;
+#endif
+ } else {
+ data->delargs = 0;
+ }
+ data->implicitconv = 0;
+ return data;
+ }
+}
+
+SWIGRUNTIME void
+PySwigClientData_Del(PySwigClientData* data)
+{
+ Py_XDECREF(data->newraw);
+ Py_XDECREF(data->newargs);
+ Py_XDECREF(data->destroy);
+}
+
+/* =============== PySwigObject =====================*/
+
+typedef struct {
+ PyObject_HEAD
+ void *ptr;
+ swig_type_info *ty;
+ int own;
+ PyObject *next;
+} PySwigObject;
+
+SWIGRUNTIME PyObject *
+PySwigObject_long(PySwigObject *v)
+{
+ return PyLong_FromVoidPtr(v->ptr);
+}
+
+SWIGRUNTIME PyObject *
+PySwigObject_format(const char* fmt, PySwigObject *v)
+{
+ PyObject *res = NULL;
+ PyObject *args = PyTuple_New(1);
+ if (args) {
+ if (PyTuple_SetItem(args, 0, PySwigObject_long(v)) == 0) {
+ PyObject *ofmt = PyString_FromString(fmt);
+ if (ofmt) {
+ res = PyString_Format(ofmt,args);
+ Py_DECREF(ofmt);
+ }
+ Py_DECREF(args);
+ }
+ }
+ return res;
+}
+
+SWIGRUNTIME PyObject *
+PySwigObject_oct(PySwigObject *v)
+{
+ return PySwigObject_format("%o",v);
+}
+
+SWIGRUNTIME PyObject *
+PySwigObject_hex(PySwigObject *v)
+{
+ return PySwigObject_format("%x",v);
+}
+
+SWIGRUNTIME PyObject *
+#ifdef METH_NOARGS
+PySwigObject_repr(PySwigObject *v)
+#else
+PySwigObject_repr(PySwigObject *v, PyObject *args)
+#endif
+{
+ const char *name = SWIG_TypePrettyName(v->ty);
+ PyObject *hex = PySwigObject_hex(v);
+ PyObject *repr = PyString_FromFormat("<Swig Object of type '%s' at 0x%s>", name, PyString_AsString(hex));
+ Py_DECREF(hex);
+ if (v->next) {
+#ifdef METH_NOARGS
+ PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next);
+#else
+ PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next, args);
+#endif
+ PyString_ConcatAndDel(&repr,nrep);
+ }
+ return repr;
+}
+
+SWIGRUNTIME int
+PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSEDPARM(flags))
+{
+#ifdef METH_NOARGS
+ PyObject *repr = PySwigObject_repr(v);
+#else
+ PyObject *repr = PySwigObject_repr(v, NULL);
+#endif
+ if (repr) {
+ fputs(PyString_AsString(repr), fp);
+ Py_DECREF(repr);
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+SWIGRUNTIME PyObject *
+PySwigObject_str(PySwigObject *v)
+{
+ char result[SWIG_BUFFER_SIZE];
+ return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ?
+ PyString_FromString(result) : 0;
+}
+
+SWIGRUNTIME int
+PySwigObject_compare(PySwigObject *v, PySwigObject *w)
+{
+ void *i = v->ptr;
+ void *j = w->ptr;
+ return (i < j) ? -1 : ((i > j) ? 1 : 0);
+}
+
+SWIGRUNTIME PyTypeObject* _PySwigObject_type(void);
+
+SWIGRUNTIME PyTypeObject*
+PySwigObject_type(void) {
+ static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type();
+ return type;
+}
+
+SWIGRUNTIMEINLINE int
+PySwigObject_Check(PyObject *op) {
+ return ((op)->ob_type == PySwigObject_type())
+ || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0);
+}
+
+SWIGRUNTIME PyObject *
+PySwigObject_New(void *ptr, swig_type_info *ty, int own);
+
+SWIGRUNTIME void
+PySwigObject_dealloc(PyObject *v)
+{
+ PySwigObject *sobj = (PySwigObject *) v;
+ PyObject *next = sobj->next;
+ if (sobj->own) {
+ swig_type_info *ty = sobj->ty;
+ PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0;
+ PyObject *destroy = data ? data->destroy : 0;
+ if (destroy) {
+ /* destroy is always a VARARGS method */
+ PyObject *res;
+ if (data->delargs) {
+ /* we need to create a temporal object to carry the destroy operation */
+ PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0);
+ res = SWIG_Python_CallFunctor(destroy, tmp);
+ Py_DECREF(tmp);
+ } else {
+ PyCFunction meth = PyCFunction_GET_FUNCTION(destroy);
+ PyObject *mself = PyCFunction_GET_SELF(destroy);
+ res = ((*meth)(mself, v));
+ }
+ Py_XDECREF(res);
+ } else {
+ const char *name = SWIG_TypePrettyName(ty);
+#if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
+ printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name);
+#endif
+ }
+ }
+ Py_XDECREF(next);
+ PyObject_DEL(v);
+}
+
+SWIGRUNTIME PyObject*
+PySwigObject_append(PyObject* v, PyObject* next)
+{
+ PySwigObject *sobj = (PySwigObject *) v;
+#ifndef METH_O
+ PyObject *tmp = 0;
+ if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL;
+ next = tmp;
+#endif
+ if (!PySwigObject_Check(next)) {
+ return NULL;
+ }
+ sobj->next = next;
+ Py_INCREF(next);
+ return SWIG_Py_Void();
+}
+
+SWIGRUNTIME PyObject*
+#ifdef METH_NOARGS
+PySwigObject_next(PyObject* v)
+#else
+PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+#endif
+{
+ PySwigObject *sobj = (PySwigObject *) v;
+ if (sobj->next) {
+ Py_INCREF(sobj->next);
+ return sobj->next;
+ } else {
+ return SWIG_Py_Void();
+ }
+}
+
+SWIGINTERN PyObject*
+#ifdef METH_NOARGS
+PySwigObject_disown(PyObject *v)
+#else
+PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+#endif
+{
+ PySwigObject *sobj = (PySwigObject *)v;
+ sobj->own = 0;
+ return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject*
+#ifdef METH_NOARGS
+PySwigObject_acquire(PyObject *v)
+#else
+PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+#endif
+{
+ PySwigObject *sobj = (PySwigObject *)v;
+ sobj->own = SWIG_POINTER_OWN;
+ return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject*
+PySwigObject_own(PyObject *v, PyObject *args)
+{
+ PyObject *val = 0;
+#if (PY_VERSION_HEX < 0x02020000)
+ if (!PyArg_ParseTuple(args,(char *)"|O:own",&val))
+#else
+ if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val))
+#endif
+ {
+ return NULL;
+ }
+ else
+ {
+ PySwigObject *sobj = (PySwigObject *)v;
+ PyObject *obj = PyBool_FromLong(sobj->own);
+ if (val) {
+#ifdef METH_NOARGS
+ if (PyObject_IsTrue(val)) {
+ PySwigObject_acquire(v);
+ } else {
+ PySwigObject_disown(v);
+ }
+#else
+ if (PyObject_IsTrue(val)) {
+ PySwigObject_acquire(v,args);
+ } else {
+ PySwigObject_disown(v,args);
+ }
+#endif
+ }
+ return obj;
+ }
+}
+
+#ifdef METH_O
+static PyMethodDef
+swigobject_methods[] = {
+ {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"},
+ {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"},
+ {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
+ {(char *)"append", (PyCFunction)PySwigObject_append, METH_O, (char *)"appends another 'this' object"},
+ {(char *)"next", (PyCFunction)PySwigObject_next, METH_NOARGS, (char *)"returns the next 'this' object"},
+ {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_NOARGS, (char *)"returns object representation"},
+ {0, 0, 0, 0}
+};
+#else
+static PyMethodDef
+swigobject_methods[] = {
+ {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"},
+ {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"},
+ {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
+ {(char *)"append", (PyCFunction)PySwigObject_append, METH_VARARGS, (char *)"appends another 'this' object"},
+ {(char *)"next", (PyCFunction)PySwigObject_next, METH_VARARGS, (char *)"returns the next 'this' object"},
+ {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_VARARGS, (char *)"returns object representation"},
+ {0, 0, 0, 0}
+};
+#endif
+
+#if PY_VERSION_HEX < 0x02020000
+SWIGINTERN PyObject *
+PySwigObject_getattr(PySwigObject *sobj,char *name)
+{
+ return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name);
+}
+#endif
+
+SWIGRUNTIME PyTypeObject*
+_PySwigObject_type(void) {
+ static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer";
+
+ static PyNumberMethods PySwigObject_as_number = {
+ (binaryfunc)0, /*nb_add*/
+ (binaryfunc)0, /*nb_subtract*/
+ (binaryfunc)0, /*nb_multiply*/
+ (binaryfunc)0, /*nb_divide*/
+ (binaryfunc)0, /*nb_remainder*/
+ (binaryfunc)0, /*nb_divmod*/
+ (ternaryfunc)0,/*nb_power*/
+ (unaryfunc)0, /*nb_negative*/
+ (unaryfunc)0, /*nb_positive*/
+ (unaryfunc)0, /*nb_absolute*/
+ (inquiry)0, /*nb_nonzero*/
+ 0, /*nb_invert*/
+ 0, /*nb_lshift*/
+ 0, /*nb_rshift*/
+ 0, /*nb_and*/
+ 0, /*nb_xor*/
+ 0, /*nb_or*/
+ (coercion)0, /*nb_coerce*/
+ (unaryfunc)PySwigObject_long, /*nb_int*/
+ (unaryfunc)PySwigObject_long, /*nb_long*/
+ (unaryfunc)0, /*nb_float*/
+ (unaryfunc)PySwigObject_oct, /*nb_oct*/
+ (unaryfunc)PySwigObject_hex, /*nb_hex*/
+#if PY_VERSION_HEX >= 0x02020000
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */
+#elif PY_VERSION_HEX >= 0x02000000
+ 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */
+#endif
+ };
+
+ static PyTypeObject pyswigobject_type;
+ static int type_init = 0;
+ if (!type_init) {
+ const PyTypeObject tmp
+ = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ (char *)"PySwigObject", /* tp_name */
+ sizeof(PySwigObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)PySwigObject_dealloc, /* tp_dealloc */
+ (printfunc)PySwigObject_print, /* tp_print */
+#if PY_VERSION_HEX < 0x02020000
+ (getattrfunc)PySwigObject_getattr, /* tp_getattr */
+#else
+ (getattrfunc)0, /* tp_getattr */
+#endif
+ (setattrfunc)0, /* tp_setattr */
+ (cmpfunc)PySwigObject_compare, /* tp_compare */
+ (reprfunc)PySwigObject_repr, /* tp_repr */
+ &PySwigObject_as_number, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)0, /* tp_hash */
+ (ternaryfunc)0, /* tp_call */
+ (reprfunc)PySwigObject_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ swigobject_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+#if PY_VERSION_HEX >= 0x02020000
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ swigobject_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#endif
+#if PY_VERSION_HEX >= 0x02030000
+ 0, /* tp_del */
+#endif
+#ifdef COUNT_ALLOCS
+ 0,0,0,0 /* tp_alloc -> tp_next */
+#endif
+ };
+ pyswigobject_type = tmp;
+ pyswigobject_type.ob_type = &PyType_Type;
+ type_init = 1;
+ }
+ return &pyswigobject_type;
+}
+
+SWIGRUNTIME PyObject *
+PySwigObject_New(void *ptr, swig_type_info *ty, int own)
+{
+ PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type());
+ if (sobj) {
+ sobj->ptr = ptr;
+ sobj->ty = ty;
+ sobj->own = own;
+ sobj->next = 0;
+ }
+ return (PyObject *)sobj;
+}
+
+/* -----------------------------------------------------------------------------
+ * Implements a simple Swig Packed type, and use it instead of string
+ * ----------------------------------------------------------------------------- */
+
+typedef struct {
+ PyObject_HEAD
+ void *pack;
+ swig_type_info *ty;
+ size_t size;
+} PySwigPacked;
+
+SWIGRUNTIME int
+PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags))
+{
+ char result[SWIG_BUFFER_SIZE];
+ fputs("<Swig Packed ", fp);
+ if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
+ fputs("at ", fp);
+ fputs(result, fp);
+ }
+ fputs(v->ty->name,fp);
+ fputs(">", fp);
+ return 0;
+}
+
+SWIGRUNTIME PyObject *
+PySwigPacked_repr(PySwigPacked *v)
+{
+ char result[SWIG_BUFFER_SIZE];
+ if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
+ return PyString_FromFormat("<Swig Packed at %s%s>", result, v->ty->name);
+ } else {
+ return PyString_FromFormat("<Swig Packed %s>", v->ty->name);
+ }
+}
+
+SWIGRUNTIME PyObject *
+PySwigPacked_str(PySwigPacked *v)
+{
+ char result[SWIG_BUFFER_SIZE];
+ if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){
+ return PyString_FromFormat("%s%s", result, v->ty->name);
+ } else {
+ return PyString_FromString(v->ty->name);
+ }
+}
+
+SWIGRUNTIME int
+PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w)
+{
+ size_t i = v->size;
+ size_t j = w->size;
+ int s = (i < j) ? -1 : ((i > j) ? 1 : 0);
+ return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size);
+}
+
+SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void);
+
+SWIGRUNTIME PyTypeObject*
+PySwigPacked_type(void) {
+ static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type();
+ return type;
+}
+
+SWIGRUNTIMEINLINE int
+PySwigPacked_Check(PyObject *op) {
+ return ((op)->ob_type == _PySwigPacked_type())
+ || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0);
+}
+
+SWIGRUNTIME void
+PySwigPacked_dealloc(PyObject *v)
+{
+ if (PySwigPacked_Check(v)) {
+ PySwigPacked *sobj = (PySwigPacked *) v;
+ free(sobj->pack);
+ }
+ PyObject_DEL(v);
+}
+
+SWIGRUNTIME PyTypeObject*
+_PySwigPacked_type(void) {
+ static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer";
+ static PyTypeObject pyswigpacked_type;
+ static int type_init = 0;
+ if (!type_init) {
+ const PyTypeObject tmp
+ = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ (char *)"PySwigPacked", /* tp_name */
+ sizeof(PySwigPacked), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)PySwigPacked_dealloc, /* tp_dealloc */
+ (printfunc)PySwigPacked_print, /* tp_print */
+ (getattrfunc)0, /* tp_getattr */
+ (setattrfunc)0, /* tp_setattr */
+ (cmpfunc)PySwigPacked_compare, /* tp_compare */
+ (reprfunc)PySwigPacked_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)0, /* tp_hash */
+ (ternaryfunc)0, /* tp_call */
+ (reprfunc)PySwigPacked_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ swigpacked_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+#if PY_VERSION_HEX >= 0x02020000
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#endif
+#if PY_VERSION_HEX >= 0x02030000
+ 0, /* tp_del */
+#endif
+#ifdef COUNT_ALLOCS
+ 0,0,0,0 /* tp_alloc -> tp_next */
+#endif
+ };
+ pyswigpacked_type = tmp;
+ pyswigpacked_type.ob_type = &PyType_Type;
+ type_init = 1;
+ }
+ return &pyswigpacked_type;
+}
+
+SWIGRUNTIME PyObject *
+PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty)
+{
+ PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type());
+ if (sobj) {
+ void *pack = malloc(size);
+ if (pack) {
+ memcpy(pack, ptr, size);
+ sobj->pack = pack;
+ sobj->ty = ty;
+ sobj->size = size;
+ } else {
+ PyObject_DEL((PyObject *) sobj);
+ sobj = 0;
+ }
+ }
+ return (PyObject *) sobj;
+}
+
+SWIGRUNTIME swig_type_info *
+PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
+{
+ if (PySwigPacked_Check(obj)) {
+ PySwigPacked *sobj = (PySwigPacked *)obj;
+ if (sobj->size != size) return 0;
+ memcpy(ptr, sobj->pack, size);
+ return sobj->ty;
+ } else {
+ return 0;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * pointers/data manipulation
+ * ----------------------------------------------------------------------------- */
+
+SWIGRUNTIMEINLINE PyObject *
+_SWIG_This(void)
+{
+ return PyString_FromString("this");
+}
+
+SWIGRUNTIME PyObject *
+SWIG_This(void)
+{
+ static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This();
+ return swig_this;
+}
+
+/* #define SWIG_PYTHON_SLOW_GETSET_THIS */
+
+SWIGRUNTIME PySwigObject *
+SWIG_Python_GetSwigThis(PyObject *pyobj)
+{
+ if (PySwigObject_Check(pyobj)) {
+ return (PySwigObject *) pyobj;
+ } else {
+ PyObject *obj = 0;
+#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000))
+ if (PyInstance_Check(pyobj)) {
+ obj = _PyInstance_Lookup(pyobj, SWIG_This());
+ } else {
+ PyObject **dictptr = _PyObject_GetDictPtr(pyobj);
+ if (dictptr != NULL) {
+ PyObject *dict = *dictptr;
+ obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0;
+ } else {
+#ifdef PyWeakref_CheckProxy
+ if (PyWeakref_CheckProxy(pyobj)) {
+ PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
+ return wobj ? SWIG_Python_GetSwigThis(wobj) : 0;
+ }
+#endif
+ obj = PyObject_GetAttr(pyobj,SWIG_This());
+ if (obj) {
+ Py_DECREF(obj);
+ } else {
+ if (PyErr_Occurred()) PyErr_Clear();
+ return 0;
+ }
+ }
+ }
+#else
+ obj = PyObject_GetAttr(pyobj,SWIG_This());
+ if (obj) {
+ Py_DECREF(obj);
+ } else {
+ if (PyErr_Occurred()) PyErr_Clear();
+ return 0;
+ }
+#endif
+ if (obj && !PySwigObject_Check(obj)) {
+ /* a PyObject is called 'this', try to get the 'real this'
+ PySwigObject from it */
+ return SWIG_Python_GetSwigThis(obj);
+ }
+ return (PySwigObject *)obj;
+ }
+}
+
+/* Acquire a pointer value */
+
+SWIGRUNTIME int
+SWIG_Python_AcquirePtr(PyObject *obj, int own) {
+ if (own) {
+ PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
+ if (sobj) {
+ int oldown = sobj->own;
+ sobj->own = own;
+ return oldown;
+ }
+ }
+ return 0;
+}
+
+/* Convert a pointer value */
+
+SWIGRUNTIME int
+SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) {
+ if (!obj) return SWIG_ERROR;
+ if (obj == Py_None) {
+ if (ptr) *ptr = 0;
+ return SWIG_OK;
+ } else {
+ PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
+ while (sobj) {
+ void *vptr = sobj->ptr;
+ if (ty) {
+ swig_type_info *to = sobj->ty;
+ if (to == ty) {
+ /* no type cast needed */
+ if (ptr) *ptr = vptr;
+ break;
+ } else {
+ swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
+ if (!tc) {
+ sobj = (PySwigObject *)sobj->next;
+ } else {
+ if (ptr) *ptr = SWIG_TypeCast(tc,vptr);
+ break;
+ }
+ }
+ } else {
+ if (ptr) *ptr = vptr;
+ break;
+ }
+ }
+ if (sobj) {
+ if (own) *own = sobj->own;
+ if (flags & SWIG_POINTER_DISOWN) {
+ sobj->own = 0;
+ }
+ return SWIG_OK;
+ } else {
+ int res = SWIG_ERROR;
+ if (flags & SWIG_POINTER_IMPLICIT_CONV) {
+ PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0;
+ if (data && !data->implicitconv) {
+ PyObject *klass = data->klass;
+ if (klass) {
+ PyObject *impconv;
+ data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/
+ impconv = SWIG_Python_CallFunctor(klass, obj);
+ data->implicitconv = 0;
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ impconv = 0;
+ }
+ if (impconv) {
+ PySwigObject *iobj = SWIG_Python_GetSwigThis(impconv);
+ if (iobj) {
+ void *vptr;
+ res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0);
+ if (SWIG_IsOK(res)) {
+ if (ptr) {
+ *ptr = vptr;
+ /* transfer the ownership to 'ptr' */
+ iobj->own = 0;
+ res = SWIG_AddCast(res);
+ res = SWIG_AddNewMask(res);
+ } else {
+ res = SWIG_AddCast(res);
+ }
+ }
+ }
+ Py_DECREF(impconv);
+ }
+ }
+ }
+ }
+ return res;
+ }
+ }
+}
+
+/* Convert a function ptr value */
+
+SWIGRUNTIME int
+SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
+ if (!PyCFunction_Check(obj)) {
+ return SWIG_ConvertPtr(obj, ptr, ty, 0);
+ } else {
+ void *vptr = 0;
+
+ /* here we get the method pointer for callbacks */
+ const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc);
+ const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0;
+ if (desc) {
+ desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0;
+ if (!desc) return SWIG_ERROR;
+ }
+ if (ty) {
+ swig_cast_info *tc = SWIG_TypeCheck(desc,ty);
+ if (!tc) return SWIG_ERROR;
+ *ptr = SWIG_TypeCast(tc,vptr);
+ } else {
+ *ptr = vptr;
+ }
+ return SWIG_OK;
+ }
+}
+
+/* Convert a packed value value */
+
+SWIGRUNTIME int
+SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) {
+ swig_type_info *to = PySwigPacked_UnpackData(obj, ptr, sz);
+ if (!to) return SWIG_ERROR;
+ if (ty) {
+ if (to != ty) {
+ /* check type cast? */
+ swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
+ if (!tc) return SWIG_ERROR;
+ }
+ }
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Create a new pointer object
+ * ----------------------------------------------------------------------------- */
+
+/*
+ Create a new instance object, whitout calling __init__, and set the
+ 'this' attribute.
+*/
+
+SWIGRUNTIME PyObject*
+SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this)
+{
+#if (PY_VERSION_HEX >= 0x02020000)
+ PyObject *inst = 0;
+ PyObject *newraw = data->newraw;
+ if (newraw) {
+ inst = PyObject_Call(newraw, data->newargs, NULL);
+ if (inst) {
+#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
+ PyObject **dictptr = _PyObject_GetDictPtr(inst);
+ if (dictptr != NULL) {
+ PyObject *dict = *dictptr;
+ if (dict == NULL) {
+ dict = PyDict_New();
+ *dictptr = dict;
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ }
+ }
+#else
+ PyObject *key = SWIG_This();
+ PyObject_SetAttr(inst, key, swig_this);
+#endif
+ }
+ } else {
+ PyObject *dict = PyDict_New();
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ inst = PyInstance_NewRaw(data->newargs, dict);
+ Py_DECREF(dict);
+ }
+ return inst;
+#else
+#if (PY_VERSION_HEX >= 0x02010000)
+ PyObject *inst;
+ PyObject *dict = PyDict_New();
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ inst = PyInstance_NewRaw(data->newargs, dict);
+ Py_DECREF(dict);
+ return (PyObject *) inst;
+#else
+ PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type);
+ if (inst == NULL) {
+ return NULL;
+ }
+ inst->in_class = (PyClassObject *)data->newargs;
+ Py_INCREF(inst->in_class);
+ inst->in_dict = PyDict_New();
+ if (inst->in_dict == NULL) {
+ Py_DECREF(inst);
+ return NULL;
+ }
+#ifdef Py_TPFLAGS_HAVE_WEAKREFS
+ inst->in_weakreflist = NULL;
+#endif
+#ifdef Py_TPFLAGS_GC
+ PyObject_GC_Init(inst);
+#endif
+ PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this);
+ return (PyObject *) inst;
+#endif
+#endif
+}
+
+SWIGRUNTIME void
+SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this)
+{
+ PyObject *dict;
+#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
+ PyObject **dictptr = _PyObject_GetDictPtr(inst);
+ if (dictptr != NULL) {
+ dict = *dictptr;
+ if (dict == NULL) {
+ dict = PyDict_New();
+ *dictptr = dict;
+ }
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ return;
+ }
+#endif
+ dict = PyObject_GetAttrString(inst, (char*)"__dict__");
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ Py_DECREF(dict);
+}
+
+
+SWIGINTERN PyObject *
+SWIG_Python_InitShadowInstance(PyObject *args) {
+ PyObject *obj[2];
+ if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) {
+ return NULL;
+ } else {
+ PySwigObject *sthis = SWIG_Python_GetSwigThis(obj[0]);
+ if (sthis) {
+ PySwigObject_append((PyObject*) sthis, obj[1]);
+ } else {
+ SWIG_Python_SetSwigThis(obj[0], obj[1]);
+ }
+ return SWIG_Py_Void();
+ }
+}
+
+/* Create a new pointer object */
+
+SWIGRUNTIME PyObject *
+SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) {
+ if (!ptr) {
+ return SWIG_Py_Void();
+ } else {
+ int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
+ PyObject *robj = PySwigObject_New(ptr, type, own);
+ PySwigClientData *clientdata = type ? (PySwigClientData *)(type->clientdata) : 0;
+ if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
+ PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
+ if (inst) {
+ Py_DECREF(robj);
+ robj = inst;
+ }
+ }
+ return robj;
+ }
+}
+
+/* Create a new packed object */
+
+SWIGRUNTIMEINLINE PyObject *
+SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) {
+ return ptr ? PySwigPacked_New((void *) ptr, sz, type) : SWIG_Py_Void();
+}
+
+/* -----------------------------------------------------------------------------*
+ * Get type list
+ * -----------------------------------------------------------------------------*/
+
+#ifdef SWIG_LINK_RUNTIME
+void *SWIG_ReturnGlobalTypeList(void *);
+#endif
+
+SWIGRUNTIME swig_module_info *
+SWIG_Python_GetModule(void) {
+ static void *type_pointer = (void *)0;
+ /* first check if module already created */
+ if (!type_pointer) {
+#ifdef SWIG_LINK_RUNTIME
+ type_pointer = SWIG_ReturnGlobalTypeList((void *)0);
+#else
+ type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
+ (char*)"type_pointer" SWIG_TYPE_TABLE_NAME);
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ type_pointer = (void *)0;
+ }
+#endif
+ }
+ return (swig_module_info *) type_pointer;
+}
+
+#if PY_MAJOR_VERSION < 2
+/* PyModule_AddObject function was introduced in Python 2.0. The following function
+ is copied out of Python/modsupport.c in python version 2.3.4 */
+SWIGINTERN int
+PyModule_AddObject(PyObject *m, char *name, PyObject *o)
+{
+ PyObject *dict;
+ if (!PyModule_Check(m)) {
+ PyErr_SetString(PyExc_TypeError,
+ "PyModule_AddObject() needs module as first arg");
+ return SWIG_ERROR;
+ }
+ if (!o) {
+ PyErr_SetString(PyExc_TypeError,
+ "PyModule_AddObject() needs non-NULL value");
+ return SWIG_ERROR;
+ }
+
+ dict = PyModule_GetDict(m);
+ if (dict == NULL) {
+ /* Internal error -- modules must have a dict! */
+ PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
+ PyModule_GetName(m));
+ return SWIG_ERROR;
+ }
+ if (PyDict_SetItemString(dict, name, o))
+ return SWIG_ERROR;
+ Py_DECREF(o);
+ return SWIG_OK;
+}
+#endif
+
+SWIGRUNTIME void
+SWIG_Python_DestroyModule(void *vptr)
+{
+ swig_module_info *swig_module = (swig_module_info *) vptr;
+ swig_type_info **types = swig_module->types;
+ size_t i;
+ for (i =0; i < swig_module->size; ++i) {
+ swig_type_info *ty = types[i];
+ if (ty->owndata) {
+ PySwigClientData *data = (PySwigClientData *) ty->clientdata;
+ if (data) PySwigClientData_Del(data);
+ }
+ }
+ Py_DECREF(SWIG_This());
+}
+
+SWIGRUNTIME void
+SWIG_Python_SetModule(swig_module_info *swig_module) {
+ static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */
+
+ PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
+ swig_empty_runtime_method_table);
+ PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule);
+ if (pointer && module) {
+ PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer);
+ } else {
+ Py_XDECREF(pointer);
+ }
+}
+
+/* The python cached type query */
+SWIGRUNTIME PyObject *
+SWIG_Python_TypeCache(void) {
+ static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New();
+ return cache;
+}
+
+SWIGRUNTIME swig_type_info *
+SWIG_Python_TypeQuery(const char *type)
+{
+ PyObject *cache = SWIG_Python_TypeCache();
+ PyObject *key = PyString_FromString(type);
+ PyObject *obj = PyDict_GetItem(cache, key);
+ swig_type_info *descriptor;
+ if (obj) {
+ descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj);
+ } else {
+ swig_module_info *swig_module = SWIG_Python_GetModule();
+ descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type);
+ if (descriptor) {
+ obj = PyCObject_FromVoidPtr(descriptor, NULL);
+ PyDict_SetItem(cache, key, obj);
+ Py_DECREF(obj);
+ }
+ }
+ Py_DECREF(key);
+ return descriptor;
+}
+
+/*
+ For backward compatibility only
+*/
+#define SWIG_POINTER_EXCEPTION 0
+#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg)
+#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags)
+
+SWIGRUNTIME int
+SWIG_Python_AddErrMesg(const char* mesg, int infront)
+{
+ if (PyErr_Occurred()) {
+ PyObject *type = 0;
+ PyObject *value = 0;
+ PyObject *traceback = 0;
+ PyErr_Fetch(&type, &value, &traceback);
+ if (value) {
+ PyObject *old_str = PyObject_Str(value);
+ Py_XINCREF(type);
+ PyErr_Clear();
+ if (infront) {
+ PyErr_Format(type, "%s %s", mesg, PyString_AsString(old_str));
+ } else {
+ PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg);
+ }
+ Py_DECREF(old_str);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+SWIGRUNTIME int
+SWIG_Python_ArgFail(int argnum)
+{
+ if (PyErr_Occurred()) {
+ /* add information about failing argument */
+ char mesg[256];
+ PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum);
+ return SWIG_Python_AddErrMesg(mesg, 1);
+ } else {
+ return 0;
+ }
+}
+
+SWIGRUNTIMEINLINE const char *
+PySwigObject_GetDesc(PyObject *self)
+{
+ PySwigObject *v = (PySwigObject *)self;
+ swig_type_info *ty = v ? v->ty : 0;
+ return ty ? ty->str : (char*)"";
+}
+
+SWIGRUNTIME void
+SWIG_Python_TypeError(const char *type, PyObject *obj)
+{
+ if (type) {
+#if defined(SWIG_COBJECT_TYPES)
+ if (obj && PySwigObject_Check(obj)) {
+ const char *otype = (const char *) PySwigObject_GetDesc(obj);
+ if (otype) {
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%s)' is received",
+ type, otype);
+ return;
+ }
+ } else
+#endif
+ {
+ const char *otype = (obj ? obj->ob_type->tp_name : 0);
+ if (otype) {
+ PyObject *str = PyObject_Str(obj);
+ const char *cstr = str ? PyString_AsString(str) : 0;
+ if (cstr) {
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received",
+ type, otype, cstr);
+ } else {
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received",
+ type, otype);
+ }
+ Py_XDECREF(str);
+ return;
+ }
+ }
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected", type);
+ } else {
+ PyErr_Format(PyExc_TypeError, "unexpected type is received");
+ }
+}
+
+
+/* Convert a pointer value, signal an exception on a type mismatch */
+SWIGRUNTIME void *
+SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) {
+ void *result;
+ if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) {
+ PyErr_Clear();
+ if (flags & SWIG_POINTER_EXCEPTION) {
+ SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj);
+ SWIG_Python_ArgFail(argnum);
+ }
+ }
+ return result;
+}
+
+
+#ifdef __cplusplus
+#if 0
+{ /* cc-mode */
+#endif
+}
+#endif
+
+
+
+#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0)
+
+#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else
+
+
+
+/* -------- TYPES TABLE (BEGIN) -------- */
+
+#define SWIGTYPE_p_char swig_types[0]
+#define SWIGTYPE_p_gsl_complex swig_types[1]
+static swig_type_info *swig_types[3];
+static swig_module_info swig_module = {swig_types, 2, 0, 0, 0, 0};
+#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
+#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
+
+/* -------- TYPES TABLE (END) -------- */
+
+#if (PY_VERSION_HEX <= 0x02000000)
+# if !defined(SWIG_PYTHON_CLASSIC)
+# error "This python version requires swig to be run with the '-classic' option"
+# endif
+#endif
+
+/*-----------------------------------------------
+ @(target):= _ttest.so
+ ------------------------------------------------*/
+#define SWIG_init init_ttest
+
+#define SWIG_name "_ttest"
+
+#define SWIGVERSION 0x010331
+#define SWIG_VERSION SWIGVERSION
+
+
+#define SWIG_as_voidptr(a) (void *)((const void *)(a))
+#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a))
+
+
+#define SWIG_FILE_WITH_INIT
+#include "ttest.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+SWIGINTERN PyObject *_wrap_testtimer(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+
+ if (!PyArg_ParseTuple(args,(char *)":testtimer")) SWIG_fail;
+ testtimer();
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+static PyMethodDef SwigMethods[] = {
+ { (char *)"testtimer", _wrap_testtimer, METH_VARARGS, NULL},
+ { NULL, NULL, 0, NULL }
+};
+
+
+/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
+
+static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_gsl_complex = {"_p_gsl_complex", "gsl_complex *|msl_complex_t *", 0, 0, (void*)0, 0};
+
+static swig_type_info *swig_type_initial[] = {
+ &_swigt__p_char,
+ &_swigt__p_gsl_complex,
+};
+
+static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_gsl_complex[] = { {&_swigt__p_gsl_complex, 0, 0, 0},{0, 0, 0, 0}};
+
+static swig_cast_info *swig_cast_initial[] = {
+ _swigc__p_char,
+ _swigc__p_gsl_complex,
+};
+
+
+/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
+
+static swig_const_info swig_const_table[] = {
+{0, 0, 0, 0.0, 0, 0}};
+
+#ifdef __cplusplus
+}
+#endif
+/* -----------------------------------------------------------------------------
+ * Type initialization:
+ * This problem is tough by the requirement that no dynamic
+ * memory is used. Also, since swig_type_info structures store pointers to
+ * swig_cast_info structures and swig_cast_info structures store pointers back
+ * to swig_type_info structures, we need some lookup code at initialization.
+ * The idea is that swig generates all the structures that are needed.
+ * The runtime then collects these partially filled structures.
+ * The SWIG_InitializeModule function takes these initial arrays out of
+ * swig_module, and does all the lookup, filling in the swig_module.types
+ * array with the correct data and linking the correct swig_cast_info
+ * structures together.
+ *
+ * The generated swig_type_info structures are assigned staticly to an initial
+ * array. We just loop through that array, and handle each type individually.
+ * First we lookup if this type has been already loaded, and if so, use the
+ * loaded structure instead of the generated one. Then we have to fill in the
+ * cast linked list. The cast data is initially stored in something like a
+ * two-dimensional array. Each row corresponds to a type (there are the same
+ * number of rows as there are in the swig_type_initial array). Each entry in
+ * a column is one of the swig_cast_info structures for that type.
+ * The cast_initial array is actually an array of arrays, because each row has
+ * a variable number of columns. So to actually build the cast linked list,
+ * we find the array of casts associated with the type, and loop through it
+ * adding the casts to the list. The one last trick we need to do is making
+ * sure the type pointer in the swig_cast_info struct is correct.
+ *
+ * First off, we lookup the cast->type name to see if it is already loaded.
+ * There are three cases to handle:
+ * 1) If the cast->type has already been loaded AND the type we are adding
+ * casting info to has not been loaded (it is in this module), THEN we
+ * replace the cast->type pointer with the type pointer that has already
+ * been loaded.
+ * 2) If BOTH types (the one we are adding casting info to, and the
+ * cast->type) are loaded, THEN the cast info has already been loaded by
+ * the previous module so we just ignore it.
+ * 3) Finally, if cast->type has not already been loaded, then we add that
+ * swig_cast_info to the linked list (because the cast->type) pointer will
+ * be correct.
+ * ----------------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* c-mode */
+#endif
+#endif
+
+#if 0
+#define SWIGRUNTIME_DEBUG
+#endif
+
+
+SWIGRUNTIME void
+SWIG_InitializeModule(void *clientdata) {
+ size_t i;
+ swig_module_info *module_head, *iter;
+ int found;
+
+ clientdata = clientdata;
+
+ /* check to see if the circular list has been setup, if not, set it up */
+ if (swig_module.next==0) {
+ /* Initialize the swig_module */
+ swig_module.type_initial = swig_type_initial;
+ swig_module.cast_initial = swig_cast_initial;
+ swig_module.next = &swig_module;
+ }
+
+ /* Try and load any already created modules */
+ module_head = SWIG_GetModule(clientdata);
+ if (!module_head) {
+ /* This is the first module loaded for this interpreter */
+ /* so set the swig module into the interpreter */
+ SWIG_SetModule(clientdata, &swig_module);
+ module_head = &swig_module;
+ } else {
+ /* the interpreter has loaded a SWIG module, but has it loaded this one? */
+ found=0;
+ iter=module_head;
+ do {
+ if (iter==&swig_module) {
+ found=1;
+ break;
+ }
+ iter=iter->next;
+ } while (iter!= module_head);
+
+ /* if the is found in the list, then all is done and we may leave */
+ if (found) return;
+ /* otherwise we must add out module into the list */
+ swig_module.next = module_head->next;
+ module_head->next = &swig_module;
+ }
+
+ /* Now work on filling in swig_module.types */
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: size %d\n", swig_module.size);
+#endif
+ for (i = 0; i < swig_module.size; ++i) {
+ swig_type_info *type = 0;
+ swig_type_info *ret;
+ swig_cast_info *cast;
+
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
+#endif
+
+ /* if there is another module already loaded */
+ if (swig_module.next != &swig_module) {
+ type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name);
+ }
+ if (type) {
+ /* Overwrite clientdata field */
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: found type %s\n", type->name);
+#endif
+ if (swig_module.type_initial[i]->clientdata) {
+ type->clientdata = swig_module.type_initial[i]->clientdata;
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name);
+#endif
+ }
+ } else {
+ type = swig_module.type_initial[i];
+ }
+
+ /* Insert casting types */
+ cast = swig_module.cast_initial[i];
+ while (cast->type) {
+ /* Don't need to add information already in the list */
+ ret = 0;
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: look cast %s\n", cast->type->name);
+#endif
+ if (swig_module.next != &swig_module) {
+ ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name);
+#ifdef SWIGRUNTIME_DEBUG
+ if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name);
+#endif
+ }
+ if (ret) {
+ if (type == swig_module.type_initial[i]) {
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: skip old type %s\n", ret->name);
+#endif
+ cast->type = ret;
+ ret = 0;
+ } else {
+ /* Check for casting already in the list */
+ swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type);
+#ifdef SWIGRUNTIME_DEBUG
+ if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name);
+#endif
+ if (!ocast) ret = 0;
+ }
+ }
+
+ if (!ret) {
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name);
+#endif
+ if (type->cast) {
+ type->cast->prev = cast;
+ cast->next = type->cast;
+ }
+ type->cast = cast;
+ }
+ cast++;
+ }
+ /* Set entry in modules->types array equal to the type */
+ swig_module.types[i] = type;
+ }
+ swig_module.types[i] = 0;
+
+#ifdef SWIGRUNTIME_DEBUG
+ printf("**** SWIG_InitializeModule: Cast List ******\n");
+ for (i = 0; i < swig_module.size; ++i) {
+ int j = 0;
+ swig_cast_info *cast = swig_module.cast_initial[i];
+ printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
+ while (cast->type) {
+ printf("SWIG_InitializeModule: cast type %s\n", cast->type->name);
+ cast++;
+ ++j;
+ }
+ printf("---- Total casts: %d\n",j);
+ }
+ printf("**** SWIG_InitializeModule: Cast List ******\n");
+#endif
+}
+
+/* This function will propagate the clientdata field of type to
+* any new swig_type_info structures that have been added into the list
+* of equivalent types. It is like calling
+* SWIG_TypeClientData(type, clientdata) a second time.
+*/
+SWIGRUNTIME void
+SWIG_PropagateClientData(void) {
+ size_t i;
+ swig_cast_info *equiv;
+ static int init_run = 0;
+
+ if (init_run) return;
+ init_run = 1;
+
+ for (i = 0; i < swig_module.size; i++) {
+ if (swig_module.types[i]->clientdata) {
+ equiv = swig_module.types[i]->cast;
+ while (equiv) {
+ if (!equiv->converter) {
+ if (equiv->type && !equiv->type->clientdata)
+ SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata);
+ }
+ equiv = equiv->next;
+ }
+ }
+ }
+}
+
+#ifdef __cplusplus
+#if 0
+{
+ /* c-mode */
+#endif
+}
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* Python-specific SWIG API */
+#define SWIG_newvarlink() SWIG_Python_newvarlink()
+#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr)
+#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants)
+
+ /* -----------------------------------------------------------------------------
+ * global variable support code.
+ * ----------------------------------------------------------------------------- */
+
+ typedef struct swig_globalvar {
+ char *name; /* Name of global variable */
+ PyObject *(*get_attr)(void); /* Return the current value */
+ int (*set_attr)(PyObject *); /* Set the value */
+ struct swig_globalvar *next;
+ } swig_globalvar;
+
+ typedef struct swig_varlinkobject {
+ PyObject_HEAD
+ swig_globalvar *vars;
+ } swig_varlinkobject;
+
+ SWIGINTERN PyObject *
+ swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) {
+ return PyString_FromString("<Swig global variables>");
+ }
+
+ SWIGINTERN PyObject *
+ swig_varlink_str(swig_varlinkobject *v) {
+ PyObject *str = PyString_FromString("(");
+ swig_globalvar *var;
+ for (var = v->vars; var; var=var->next) {
+ PyString_ConcatAndDel(&str,PyString_FromString(var->name));
+ if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", "));
+ }
+ PyString_ConcatAndDel(&str,PyString_FromString(")"));
+ return str;
+ }
+
+ SWIGINTERN int
+ swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) {
+ PyObject *str = swig_varlink_str(v);
+ fprintf(fp,"Swig global variables ");
+ fprintf(fp,"%s\n", PyString_AsString(str));
+ Py_DECREF(str);
+ return 0;
+ }
+
+ SWIGINTERN void
+ swig_varlink_dealloc(swig_varlinkobject *v) {
+ swig_globalvar *var = v->vars;
+ while (var) {
+ swig_globalvar *n = var->next;
+ free(var->name);
+ free(var);
+ var = n;
+ }
+ }
+
+ SWIGINTERN PyObject *
+ swig_varlink_getattr(swig_varlinkobject *v, char *n) {
+ PyObject *res = NULL;
+ swig_globalvar *var = v->vars;
+ while (var) {
+ if (strcmp(var->name,n) == 0) {
+ res = (*var->get_attr)();
+ break;
+ }
+ var = var->next;
+ }
+ if (res == NULL && !PyErr_Occurred()) {
+ PyErr_SetString(PyExc_NameError,"Unknown C global variable");
+ }
+ return res;
+ }
+
+ SWIGINTERN int
+ swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) {
+ int res = 1;
+ swig_globalvar *var = v->vars;
+ while (var) {
+ if (strcmp(var->name,n) == 0) {
+ res = (*var->set_attr)(p);
+ break;
+ }
+ var = var->next;
+ }
+ if (res == 1 && !PyErr_Occurred()) {
+ PyErr_SetString(PyExc_NameError,"Unknown C global variable");
+ }
+ return res;
+ }
+
+ SWIGINTERN PyTypeObject*
+ swig_varlink_type(void) {
+ static char varlink__doc__[] = "Swig var link object";
+ static PyTypeObject varlink_type;
+ static int type_init = 0;
+ if (!type_init) {
+ const PyTypeObject tmp
+ = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* Number of items in variable part (ob_size) */
+ (char *)"swigvarlink", /* Type name (tp_name) */
+ sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */
+ 0, /* Itemsize (tp_itemsize) */
+ (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */
+ (printfunc) swig_varlink_print, /* Print (tp_print) */
+ (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */
+ (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */
+ 0, /* tp_compare */
+ (reprfunc) swig_varlink_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)swig_varlink_str, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ 0, /* tp_flags */
+ varlink__doc__, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+#if PY_VERSION_HEX >= 0x02020000
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
+#endif
+#if PY_VERSION_HEX >= 0x02030000
+ 0, /* tp_del */
+#endif
+#ifdef COUNT_ALLOCS
+ 0,0,0,0 /* tp_alloc -> tp_next */
+#endif
+ };
+ varlink_type = tmp;
+ varlink_type.ob_type = &PyType_Type;
+ type_init = 1;
+ }
+ return &varlink_type;
+ }
+
+ /* Create a variable linking object for use later */
+ SWIGINTERN PyObject *
+ SWIG_Python_newvarlink(void) {
+ swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type());
+ if (result) {
+ result->vars = 0;
+ }
+ return ((PyObject*) result);
+ }
+
+ SWIGINTERN void
+ SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
+ swig_varlinkobject *v = (swig_varlinkobject *) p;
+ swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
+ if (gv) {
+ size_t size = strlen(name)+1;
+ gv->name = (char *)malloc(size);
+ if (gv->name) {
+ strncpy(gv->name,name,size);
+ gv->get_attr = get_attr;
+ gv->set_attr = set_attr;
+ gv->next = v->vars;
+ }
+ }
+ v->vars = gv;
+ }
+
+ SWIGINTERN PyObject *
+ SWIG_globals(void) {
+ static PyObject *_SWIG_globals = 0;
+ if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink();
+ return _SWIG_globals;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * constants/methods manipulation
+ * ----------------------------------------------------------------------------- */
+
+ /* Install Constants */
+ SWIGINTERN void
+ SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) {
+ PyObject *obj = 0;
+ size_t i;
+ for (i = 0; constants[i].type; ++i) {
+ switch(constants[i].type) {
+ case SWIG_PY_POINTER:
+ obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0);
+ break;
+ case SWIG_PY_BINARY:
+ obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype));
+ break;
+ default:
+ obj = 0;
+ break;
+ }
+ if (obj) {
+ PyDict_SetItemString(d, constants[i].name, obj);
+ Py_DECREF(obj);
+ }
+ }
+ }
+
+ /* -----------------------------------------------------------------------------*/
+ /* Fix SwigMethods to carry the callback ptrs when needed */
+ /* -----------------------------------------------------------------------------*/
+
+ SWIGINTERN void
+ SWIG_Python_FixMethods(PyMethodDef *methods,
+ swig_const_info *const_table,
+ swig_type_info **types,
+ swig_type_info **types_initial) {
+ size_t i;
+ for (i = 0; methods[i].ml_name; ++i) {
+ const char *c = methods[i].ml_doc;
+ if (c && (c = strstr(c, "swig_ptr: "))) {
+ int j;
+ swig_const_info *ci = 0;
+ const char *name = c + 10;
+ for (j = 0; const_table[j].type; ++j) {
+ if (strncmp(const_table[j].name, name,
+ strlen(const_table[j].name)) == 0) {
+ ci = &(const_table[j]);
+ break;
+ }
+ }
+ if (ci) {
+ size_t shift = (ci->ptype) - types;
+ swig_type_info *ty = types_initial[shift];
+ size_t ldoc = (c - methods[i].ml_doc);
+ size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
+ char *ndoc = (char*)malloc(ldoc + lptr + 10);
+ if (ndoc) {
+ char *buff = ndoc;
+ void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
+ if (ptr) {
+ strncpy(buff, methods[i].ml_doc, ldoc);
+ buff += ldoc;
+ strncpy(buff, "swig_ptr: ", 10);
+ buff += 10;
+ SWIG_PackVoidPtr(buff, ptr, ty->name, lptr);
+ methods[i].ml_doc = ndoc;
+ }
+ }
+ }
+ }
+ }
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+/* -----------------------------------------------------------------------------*
+ * Partial Init method
+ * -----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C"
+#endif
+SWIGEXPORT void SWIG_init(void) {
+ PyObject *m, *d;
+
+ /* Fix SwigMethods to carry the callback ptrs when needed */
+ SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial);
+
+ m = Py_InitModule((char *) SWIG_name, SwigMethods);
+ d = PyModule_GetDict(m);
+
+ SWIG_InitializeModule(0);
+ SWIG_InstallConstants(d,swig_const_table);
+
+
+}
+
diff --git a/common/Util/ControlStream.py b/common/Util/ControlStream.py
new file mode 100644
index 0000000..ac7035f
--- /dev/null
+++ b/common/Util/ControlStream.py
@@ -0,0 +1,225 @@
+import sys
+import types
+import time
+
+import common.Config as Config
+
+import os
+
+from common.Util import NoteDB
+from common.Util.CSoundNote import CSoundNote
+from common.Util.CSoundClient import new_csound_client
+
+from Jam import Block
+
+class TamTamOStream:
+ def __init__(self, file):
+ self.file = file
+
+ def note_add(self, note):
+ l = ['note_add', note.id, note.page, note.track,
+ note.cs.onset,
+ note.cs.pitch,
+ note.cs.amplitude,
+ note.cs.pan,
+ note.cs.duration,
+ note.cs.trackId,
+ note.cs.instrumentId,
+ note.cs.attack,
+ note.cs.decay,
+ note.cs.reverbSend,
+ note.cs.filterType,
+ note.cs.filterCutoff,
+ int(note.cs.tied),
+ note.cs.mode]
+
+ self.file.write( " ".join([str(i) for i in l]))
+ self.file.write('\n')
+
+ def page_add(self, pid, page):
+ l = [ 'page_add', str(pid), str(page.beats), str(page.color), str(page.instruments) ]
+ self.file.write( " ".join([str(i) for i in l]))
+ self.file.write('\n')
+
+ def track_vol(self, vols):
+ self.file.write('track_vol ')
+ self.file.write(" ".join([str(t) for t in vols]))
+ self.file.write('\n')
+
+ def master_vol(self, volume):
+ self.file.write('master_vol ')
+ self.file.write(str(volume))
+ self.file.write('\n')
+
+ def tempo(self, tempo):
+ self.file.write('tempo ')
+ self.file.write(str(tempo))
+ self.file.write('\n')
+
+ def block_add( self, typeStr, active, centerX, centerY, child, data ):
+ l = [ "block_add", typeStr, str(active), str(centerX), str(centerY), str(child), str(data) ]
+ self.file.write( " ".join([str(i) for i in l]))
+ self.file.write('\n')
+
+ def desktop_store( self, filename, id ):
+ self.file.write( "desktop_store %d\n" % id )
+ try:
+ file = open( filename, "r" )
+ for line in file:
+ self.file.write( line )
+ file.close()
+ except:
+ if Config.DEBUG > 3: print "ERROR:: desktop_store could not open file: " + filename
+ self.file.write( "desktop_store END\n" )
+
+ def desktop_set( self, id ):
+ self.file.write( "desktop_set %d\n" % id )
+
+class TamTamTable:
+
+ def __init__(self, noteDB = None, jam = None ):
+ self.noteDB = noteDB
+ self.jam = jam
+ self.csnd = new_csound_client()
+ self.pid = {} #stream_pid : local_pid
+
+ def parseTable(self):
+ return {
+ 'note_set':self.note_set,
+ 'note_add':self.note_add,
+ 'page_add':self.page_add,
+ 'page_set':self.page_set,
+ 'track_vol':self.track_vol,
+ 'master_vol':self.master_vol,
+ 'tempo':self.tempo,
+ 'block_add':self.block_add,
+ 'desktop_store':self.desktop_store,
+ 'desktop_set':self.desktop_set,
+ 'sleep':self.sleep,
+ 'quit':self.quit}
+
+ def parseFile(self, ifile):
+ table = self.parseTable()
+ self.file = ifile
+ for l in self.file:
+ #print "---", l
+ cmdlist = l.split()
+ if len(cmdlist) > 0:
+ if cmdlist[0] not in table:
+ print 'ERROR: skipping command %s not found in parse table' % cmdlist[0]
+ else:
+ table[cmdlist[0]](cmdlist[1:])
+
+ def note_add(self, argv):
+ if Config.DEBUG > 3: print 'note_add', argv
+
+ nid = int(argv[0])
+ page = self.pid[int(argv[1])]
+ track = int(argv[2])
+ cs = CSoundNote(
+ int(argv[3]),
+ int(argv[4]),
+ float(argv[5]),
+ float(argv[6]),
+ float(argv[7]),
+ int(argv[8]),
+ int(argv[9]),
+ float(argv[10]),
+ float(argv[11]),
+ float(argv[12]),
+ float(argv[13]),
+ float(argv[14]),
+ bool(argv[15]),
+ argv[16])
+
+ self.noteDB.addNote( -1, page, track, cs )
+
+ def note_set(self, argv):
+ print 'note_set', argv
+
+ def page_add(self, argv):
+ if Config.DEBUG > 3: print 'page_add', argv
+ pid = int (argv[0])
+ beats = int (argv[1])
+ color = int( argv[2] )
+ insts = ""
+ for str in argv[3:]:
+ insts += str
+ print pid, insts
+ instruments = eval( insts )
+ if len( self.noteDB.tune ):
+ after = self.noteDB.tune[-1]
+ else:
+ after = False
+ self.pid[pid] = self.noteDB.addPage(-1, NoteDB.Page(beats,color,instruments), after)
+
+ def page_set(self, argv):
+ print 'page_set', argv
+
+ def track_vol(self, argv):
+ self.tracks_volume = []
+ for i in range(len(argv)):
+ self.tracks_volume.append(float(argv[i]))
+
+ def master_vol(self, argv):
+ self.masterVolume = eval( argv[0] )
+
+ def tempo(self, argv):
+ self.tempo = eval( argv[0] )
+
+ def block_add( self, argv ):
+ blockClass = Block.StrToClass[argv[0]]
+ active = eval( argv[1] )
+ x = int( argv[2] )
+ y = int( argv[3] )
+ child = eval( argv[4] )
+ data = ""
+ for str in argv[5:]:
+ data += str
+ data = eval( data )
+
+ if blockClass == Block.Drum:
+ data["page"] = self.pid[ data["page"] ]
+ elif blockClass == Block.Loop:
+ data["id"] = self.pid[ data["id"] ]
+ self.jam.updateLoopImage( data["id"] )
+
+ if child:
+ block = blockClass( self.jam.getDesktop(), data )
+ self.lastBlock.addChild( block )
+ else:
+ block = self.jam.getDesktop().addBlock( blockClass, data, ( x, y ) )
+
+ block.setPlaced( True )
+
+ if blockClass == Block.Instrument and active:
+ self.jam.getDesktop().activateInstrument( block )
+
+ self.lastBlock = block
+
+ def desktop_store( self, argv ):
+ filename = self.jam.getDesktopScratchFile( int( argv[0] ) )
+ #try:
+ if os.path.isfile( filename ):
+ os.remove( filename )
+
+ file = open( filename, "w" )
+ for line in self.file:
+ if line == "desktop_store END\n":
+ break
+ file.write( line )
+ file.close
+ #except:
+ # if Config.DEBUG > 3: print "ERROR:: desktop_store could not open file: " + filename
+
+ def desktop_set( self, argv ):
+ self.jam.setDesktop( int( argv[0] ), True )
+
+ def sleep(self, argv):
+ t = float(argv[0])
+ print 'sleeping for %i seconds' % t
+ time.sleep(t)
+ def quit(self, argv):
+ print 'quitting...'
+ sys.exit(0)
+
diff --git a/common/Util/Credits.py b/common/Util/Credits.py
new file mode 100644
index 0000000..c8d2644
--- /dev/null
+++ b/common/Util/Credits.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+import pygtk
+pygtk.require( '2.0' )
+import gtk
+
+class Credits( gtk.Window ):
+ def __init__(self , handleCreditsCloseCallback , pos):
+ gtk.Window.__init__( self, gtk.WINDOW_TOPLEVEL )
+ self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
+ self.connect('destroy' , self.destroy)
+ #self.set_decorated(False)
+ self.handleCreditsCloseCallback = handleCreditsCloseCallback
+ self.move(pos[0] , pos[1])
+
+ self.vbox = gtk.VBox()
+ self.tb = gtk.TextBuffer()
+ self.tb.set_text('miniTamTam\n\nby\n\nOlivier Bélanger\nJames Bergstra\nEric Lamothe\nNathanaël Lécaudé\nAdrian Martin\nJean Piché\nSean Wood\n\nThanks to\n\nBarry Vercoe\nVictor Lazzarini\nMarco Pesenti Gritti\nSimon Schampijer\nPeter Kirn\n\nUniversité de Montréal 2006')
+ self.tw = gtk.TextView(buffer = self.tb)
+ self.tw.set_editable(False)
+ self.tw.set_cursor_visible(False)
+ #self.tw.set_right_margin(10)
+ #self.tw.set_left_margin(10)
+ self.tw.set_justification(gtk.JUSTIFY_CENTER)
+ self.vbox.add(self.tw)
+
+ self.closeButton = gtk.Button(label='X')
+ self.closeButton.connect('clicked' , self.destroy)
+ self.vbox.add(self.closeButton)
+ self.add(self.vbox)
+ self.show_all()
+
+ def destroy(self, widget):
+ self.handleCreditsCloseCallback(False)
+ self.hide_all()
+
+
+if __name__ == '__main__':
+ credits = Credits()
+ gtk.main() \ No newline at end of file
diff --git a/common/Util/InstrumentDB.py b/common/Util/InstrumentDB.py
new file mode 100644
index 0000000..ca1e0ef
--- /dev/null
+++ b/common/Util/InstrumentDB.py
@@ -0,0 +1,143 @@
+#!/bin/env python
+import os
+
+##############
+## SOUNDS
+##############
+
+class Instrument:
+ def __init__(self, id):
+ self.id = id
+
+ # build an Instrument instance from argument list
+ def loadFromArgs( self, name, csoundInstrumentName, register, loopStart,
+ loopEnd, crossDur, wav, img, labels ):
+ self.name = name
+ self.csoundInstrumentName = csoundInstrumentName
+ self.register = register
+ self.loopStart = loopStart
+ self.loopEnd = loopEnd
+ self.crossDur = crossDur
+ self.wav = wav
+ self.img = img
+ self.labels = labels
+
+ # build an Instrument instance by parsing a file
+ def loadFromPath(self, path ):
+ f = file(path, 'r')
+ magic = f.readline()[:-1]
+ if (magic != 'TamTam idf v1'):
+ raise 'given file has wrong header'
+ self.name = f.readline()
+ self.csoundInstrumentName = f.readline()
+ self.register = f.readline()
+ self.loopStart = float( f.readline())
+ self.loopEnd = float( f.readline())
+ self.crossDur = float( f.readline())
+ self.wav = f.readline()
+ self.img = f.readline()
+ self.labels = f.readline().split()
+ f.close()
+
+class InstrumentDB:
+
+ # initialize an empty InstrumentDB instance
+ def __init__(self):
+ self.labelSet = {'All':set([])} # <key> -> all instruments labelled by <key>
+ self.inst = [] # all instruments
+ self.instNamed = {} # <name> -> instrument with that name
+ self.kit = [] # all kits. kits are lists of 13 instruments
+ self.kitNamed = {} # <name> -> kit with that name
+
+ # TEMP? add instrument from args
+ def addInstrumentFromArgs( self, name, csoundInstrumentName, register, loopStart,
+ loopEnd, crossDur, wav, img, labels ):
+ i = Instrument(len(self.inst))
+ self.inst += [ i ]
+ i.loadFromArgs( name, csoundInstrumentName, register, loopStart, loopEnd, crossDur, wav, img, labels )
+ #print 'labelSet... ', self.labelSet
+ self.labelSet['All'].add(i)
+ for l in i.labels:
+ if l not in self.labelSet:
+ self.labelSet[l] = set([])
+ self.labelSet[l].add( i )
+
+
+ # add an instrument to the DB by reading from an instrument definition file
+ def addInstrument( self, path ):
+ i = Instrument(len(self.inst))
+ self.inst += [ i ]
+ i.loadFromPath( path )
+ self.instNamed[ i.name ] = i
+ #print 'labelSet... ', self.labelSet
+ self.labelSet['All'].add(i)
+ for l in i.labels:
+ if l not in self.labelSet:
+ self.labelSet[l] = set([])
+ self.labelSet[l].add( i )
+
+ # add a kit by reading from a kit definition file
+ def addKit( self, path ):
+ strlist = file(path, 'r').readline().split()
+ if len(strlist) != 14:
+ raise 'kit length != 13'
+ for str in strlist[1:]:
+ if str not in self.inst_named:
+ raise 'invalid instrument'
+ kit = [ self.instNamed[name] for name in strlist ]
+ self.kit += [ kit ]
+
+ # try to load each file in a given folder as an instrument def. file
+ def scanInstrumentDir( self, path ):
+ dirlist = os.listdir( path )
+ for fpath in dirlist:
+ try :
+ self.addInstrument( path + fpath )
+ except :
+ print 'ERROR: scanning instrument path %s: file %s invalid' % (path, fpath)
+
+ # try to load each file in a given folder as a kit def. file
+ def scanKitDir( self, path ):
+ dirlist = os.listdir( path )
+ for fpath in dirlist:
+ try :
+ self.addKit( fpath )
+ except :
+ print 'ERROR: scanning kit path %s: file %s invalid' % (path, fpath)
+
+ def getLabels( self ):
+ return self.labelSet.keys()
+
+ def getSet( self, label ):
+ return self.labelSet[label]
+
+ def getInstrument( self, id ):
+ return self.inst[id]
+
+ def debug_summarize(self):
+ for i in self.inst:
+ print i.id, i.name
+
+ for l in self.labelSet:
+ print l, [ i.name for i in self.labelSet[l]]
+
+
+db_instance = None
+def getRef():
+ global db_instance
+ if (None == db_instance):
+ db_instance = InstrumentDB()
+ return db_instance
+
+
+if __name__ == "__main__":
+ i1 = getRef()
+ i2 = getRef()
+
+ print i1, i2
+
+ import sys
+ i1.scanInstrumentDir( sys.argv[1] )
+
+ i1.debug_summarize()
+
diff --git a/common/Util/InstrumentPanel.py b/common/Util/InstrumentPanel.py
new file mode 100644
index 0000000..8cac210
--- /dev/null
+++ b/common/Util/InstrumentPanel.py
@@ -0,0 +1,379 @@
+#!/usr/bin/env python
+
+import pygtk
+pygtk.require( '2.0' )
+import gtk
+
+import time
+
+import common.Config as Config
+from common.Util.ThemeWidgets import *
+Tooltips = Config.Tooltips
+
+class InstrumentPanel( gtk.EventBox ):
+ def __init__(self,setInstrument = None, playInstrument = None, enterMode = False, micRec = None, synthRec = None, rowLen = 8, _instDic = None, force_load = True ):
+ gtk.EventBox.__init__(self)
+
+ self.setInstrument = setInstrument
+ self.playInstrument = playInstrument
+ self.micRec = micRec
+ self.synthRec = synthRec
+ self.rowLen = rowLen
+ self.enterMode = enterMode
+
+ self.instDic = _instDic
+
+ self.loaded = False
+ self.loadData = {}
+ self.loadStage = [0,0,0]
+ if force_load: self.load()
+
+ def configure( self, setInstrument = None, playInstrument = None, enterMode = False, micRec = None, synthRec = None, rowLen = 8 ):
+
+ self.setInstrument = setInstrument
+ self.playInstrument = playInstrument
+ self.enterMode = enterMode
+ self.micRec = micRec
+
+ if self.rowLen != rowLen:
+ self.rowLen = rowLen
+ self.prepareInstrumentTable( self.category )
+ else:
+ self.rowLen = rowLen
+
+ def load( self, timeout = -1 ):
+ if self.loaded: return True
+ if Config.DEBUG > 4: print "InstrumentPanel load", self.loadStage
+
+ if self.loadStage[0] == 0:
+ color = gtk.gdk.color_parse(Config.PANEL_BCK_COLOR)
+ self.modify_bg(gtk.STATE_NORMAL, color)
+ self.loadStage[0] = 1
+ if timeout >= 0 and time.time() > timeout: return False
+
+ if self.loadStage[0] == 1:
+ self.tooltips = gtk.Tooltips()
+ self.loadStage[0] = 2
+ if timeout >= 0 and time.time() > timeout: return False
+
+ if self.loadStage[0] == 2:
+ self.instTable = None
+ self.recstate = False
+ self.lastInstrumentWidget = None
+
+ self.mainVBox = gtk.VBox()
+ self.loadStage[0] = 3
+ if timeout >= 0 and time.time() > timeout: return False
+
+ if self.loadStage[0] == 3:
+ if not self.loadInstrumentList( timeout, self.loadStage ):
+ return False
+ self.loadStage[0] = 4
+ if timeout >= 0 and time.time() > timeout: return False
+
+ if self.loadStage[0] == 4:
+ if not self.loadToolbar( timeout, self.loadStage ):
+ return False
+ self.loadStage[0] = 5
+ if timeout >= 0 and time.time() > timeout: return False
+
+ if self.loadStage[0] == 5:
+ if self.instDic == None:
+ self.instDic = {}
+ self.loadStage[0] = 5.1
+ else:
+ self.loadStage[0] = 6
+
+ if self.loadStage[0] == 5.1:
+ if not self.loadInstDic( self.instDic, timeout, self.loadStage ):
+ return False
+ self.loadStage[0] = 6
+ if timeout >= 0 and time.time() > timeout: return False
+
+ if self.loadStage[0] == 6:
+ self.loadInstrumentViewport()
+ self.loadStage[0] = 7
+ if timeout >= 0 and time.time() > timeout: return False
+
+ if self.loadStage[0] == 7:
+ self.prepareInstrumentTable()
+ self.loadStage[0] = 8
+ if timeout >= 0 and time.time() > timeout: return False
+
+ self.add(self.mainVBox)
+ self.show_all()
+
+ self.loaded = True
+ return True
+
+ def loadInstrumentList( self, timeout = -1, loadStage = [0,0,0] ):
+
+ if loadStage[1] == 0:
+ self.instrumentList = { "all": [], "all.enterMode": [], "percussions.enterMode": [], "lab": [], "mic": [], "kit": [] }
+ for category in Config.CATEGORIES:
+ self.instrumentList[category] = []
+ loadStage[1] = 1
+ if timeout >= 0 and time.time() > timeout: return False
+
+ if loadStage[1] == 1:
+ keys = Config.INSTRUMENTS.keys()
+ for i in range(loadStage[2], len(keys)):
+ key = keys[i]
+ instrument = Config.INSTRUMENTS[key]
+ if key[0:4] != 'drum' and key[0:4] != 'guid' and key[0:3] != 'mic' and key[0:3] != 'lab':
+ self.instrumentList["all"].append( key )
+ if key[0:4] != 'drum' and key[0:4] != 'guid' and key[0:3] != 'mic' and key[0:3] != 'lab':
+ self.instrumentList["all.enterMode"].append( key )
+ if key[0:4] != 'drum' and key[0:4] != 'guid':
+ self.instrumentList[instrument.category].append( key )
+ if instrument.category == "percussions":
+ self.instrumentList["percussions.enterMode"].append( key )
+ if instrument.category == "kit":
+ self.instrumentList["kit"].append( key )
+ loadStage[2] += 1
+ if timeout >= 0 and time.time() > timeout: return False
+
+ loadStage[1] = 2
+ loadStage[2] = 0
+
+ self.instrumentList["mic"].sort()
+ self.instrumentList["lab"].sort()
+
+ self.instrumentList["all"] += self.instrumentList["kit"] + self.instrumentList["mic"] + self.instrumentList["lab"]
+ self.instrumentList["all.enterMode"] += self.instrumentList["mic"] + self.instrumentList["lab"]
+ self.instrumentList["percussions"] += self.instrumentList["kit"]
+ self.instrumentList["people"] += self.instrumentList["mic"]
+ self.instrumentList["keyboard"] += self.instrumentList["lab"]
+
+ loadStage[1] = 0
+ return True
+
+ def loadToolbar( self, timeout = -1, loadStage = [0,0,0] ):
+ if loadStage[1] == 0:
+ self.loadData["toolbarBox"] = gtk.HBox()
+ self.firstTbBtn = None
+ self.loadStage[1] = 1
+ if timeout >= 0 and time.time() > timeout: return False
+
+ for i in range(loadStage[1]-1, len(Config.CATEGORIES)):
+ category = Config.CATEGORIES[i]
+ if loadStage[2] == 0:
+ self.loadData["btnBox"] = RoundVBox(fillcolor = Config.CATEGORY_BCK_COLOR, bordercolor = Config.PANEL_BCK_COLOR, radius = Config.PANEL_RADIUS)
+ self.loadData["btnBox"].set_border_width(Config.PANEL_SPACING)
+ loadStage[2] = 1
+ if timeout >= 0 and time.time() > timeout: return False
+
+ if loadStage[2] == 1:
+ self.loadData["btn"] = ImageRadioButton(self.firstTbBtn,Config.IMAGE_ROOT + category + '.png', Config.IMAGE_ROOT + category + 'sel.png', Config.IMAGE_ROOT + category + 'sel.png')
+ loadStage[2] = 2
+ if timeout >= 0 and time.time() > timeout: return False
+
+ if self.firstTbBtn == None:
+ self.firstTbBtn = self.loadData["btn"]
+ self.loadData["btn"].connect('clicked',self.handleToolbarBtnPress,category)
+ self.loadData["btnBox"].add(self.loadData["btn"])
+ self.loadData["toolbarBox"].pack_start(self.loadData["btnBox"],True,True)
+
+ loadStage[2] = 0
+ loadStage[1] += 1
+ if timeout >= 0 and time.time() > timeout: return False
+
+ self.mainVBox.pack_start(self.loadData["toolbarBox"],False,False)
+
+ self.loadData.pop("btn")
+ self.loadData.pop("btnBox")
+ self.loadData.pop("toolbarBox")
+ loadStage[1] = 0
+ return True
+
+ def loadInstDic( self, instDic, timeout = -1, loadStage = [0,0,0] ):
+
+ if loadStage[1] == 0:
+ self.firstInstButton = None
+ self.loadData["len"] = len(self.instrumentList['all'])
+ loadStage[1] = 1
+ if timeout >= 0 and time.time() > timeout: return False
+
+
+ for i in range( loadStage[1]-1, self.loadData["len"] ):
+ instrument = self.instrumentList["all"][i]
+ if loadStage[2] == 0:
+ self.loadData["instBox"] = RoundVBox(fillcolor = Config.INST_BCK_COLOR, bordercolor = Config.INSTRUMENT_GRID_COLOR, radius = Config.PANEL_RADIUS)
+ self.loadData["instBox"].set_border_width(Config.PANEL_SPACING)
+ loadStage[2] = 1
+ if timeout >= 0 and time.time() > timeout: return False
+
+ if loadStage[2] == 1:
+ try:
+ self.loadData["instButton"] = ImageRadioButton(self.firstInstButton, Config.IMAGE_ROOT + instrument + '.png' , Config.IMAGE_ROOT + instrument + 'sel.png', Config.IMAGE_ROOT + instrument + 'sel.png')
+ except:
+ self.loadData["instButton"] = ImageRadioButton(self.firstInstButton, Config.IMAGE_ROOT + 'generic.png' , Config.IMAGE_ROOT + 'genericsel.png', Config.IMAGE_ROOT + 'genericsel.png')
+ loadStage[2] = 2
+ if timeout >= 0 and time.time() > timeout: return False
+
+ if loadStage[2] == 2:
+ self.loadData["instButton"].clickedHandler = self.loadData["instButton"].connect('clicked',self.handleInstrumentButtonClick, instrument)
+ self.loadData["instButton"].connect('enter',self.handleInstrumentButtonEnter, instrument)
+ loadStage[2] = 3
+ if timeout >= 0 and time.time() > timeout: return False
+
+ self.loadData["instBox"].pack_start(self.loadData["instButton"],False,False)
+ instDic[instrument] = self.loadData["instBox"]
+ if self.firstInstButton == None:
+ self.firstInstButton = self.loadData["instButton"]
+ loadStage[2] = 0
+ if timeout >= 0 and time.time() > timeout: return False
+
+ loadStage[1] += 1
+
+ self.loadData.pop("instBox")
+ self.loadData.pop("instButton")
+ self.loadData.pop("len")
+ loadStage[1] = 0
+ return True
+
+ def loadInstrumentViewport( self ):
+ self.instrumentBox = RoundHBox(fillcolor = Config.INSTRUMENT_GRID_COLOR, bordercolor = Config.PANEL_BCK_COLOR, radius = Config.PANEL_RADIUS)
+
+ self.scrollWin = gtk.ScrolledWindow()
+ self.scrollWin.set_policy(gtk.POLICY_NEVER,gtk.POLICY_AUTOMATIC)
+
+ self.tableEventBox = gtk.EventBox()
+ color = gtk.gdk.color_parse(Config.INSTRUMENT_GRID_COLOR)
+ self.tableEventBox.modify_bg(gtk.STATE_NORMAL, color)
+
+ self.scrollWin.add_with_viewport(self.tableEventBox)
+ self.tableEventBox.get_parent().set_shadow_type( gtk.SHADOW_NONE )
+ self.instrumentBox.pack_start(self.scrollWin,True,True,0)
+ self.mainVBox.pack_start(self.instrumentBox)
+ self.show_all()
+
+ def prepareInstrumentTable(self,category = 'all'):
+
+ self.category = category
+
+ if self.enterMode:
+ if category == "all": category = "all.enterMode"
+ elif category == "percussions": category = "percussions.enterMode"
+
+ if self.instTable != None:
+ for child in self.instTable.get_children()[:]:
+ self.instTable.remove(child)
+ self.tableEventBox.remove(self.instTable)
+ self.instTable.destroy()
+
+ instrumentNum = len(self.instrumentList[category])
+ instruments = self.instrumentList[category]
+
+ cols = self.rowLen
+ if instrumentNum < cols:
+ cols = instrumentNum
+ rows = (instrumentNum // cols)
+ if instrumentNum % cols is not 0: #S'il y a un reste
+ rows = rows + 1
+
+ self.instTable = gtk.Table(rows,cols,True)
+ self.instTable.set_row_spacings(0)
+ self.instTable.set_col_spacings(0)
+
+ for row in range(rows):
+ for col in range(cols):
+ if row*cols+col >= instrumentNum:
+ break
+ instBox = self.instDic[instruments[row*cols+col]]
+ self.instTable.attach(instBox, col, col+1, row, row+1, gtk.SHRINK, gtk.SHRINK, 0, 0)
+
+ self.tableEventBox.add(self.instTable)
+ self.instTable.show_all()
+
+ def selectFirstCat(self):
+ self.firstTbBtn.set_active(True)
+
+ def handleToolbarBtnPress(self, widget, category):
+ if widget.get_active():
+ self.prepareInstrumentTable(category)
+
+ def handleInstrumentButtonClick(self,widget,instrument):
+ if widget.get_active() is True and self.recstate == False:
+ if self.setInstrument:
+ widget.event( gtk.gdk.Event( gtk.gdk.LEAVE_NOTIFY ) ) # fake the leave event
+ self.setInstrument(instrument)
+ if self.playInstrument: self.playInstrument(instrument)
+ if self.enterMode:
+ pass #Close the window
+
+ def handleInstrumentButtonEnter(self,widget,instrument):
+ if self.enterMode and self.playInstrument:
+ self.playInstrument(instrument)
+
+ def handleMicRecButtonClick(self,widget,mic):
+ self.recstate = False
+ self.setInstrument(mic)
+ if self.micRec: self.micRec(mic)
+
+ def handleRecButtonPress(self,widget,btn):
+ self.recstate = True
+ btn.set_active(True)
+
+ def set_activeInstrument(self,instrument, state):
+ if len(self.instDic) > 0:
+ for key in self.instDic:
+ if key == instrument:
+ btn = self.instDic[key].get_children()[0]
+ btn.handler_block(btn.clickedHandler)
+ btn.set_active(state)
+ btn.handler_unblock(btn.clickedHandler)
+
+
+class DrumPanel( gtk.EventBox ):
+ def __init__(self, setDrum = None):
+ gtk.EventBox.__init__(self)
+ color = gtk.gdk.color_parse(Config.PANEL_BCK_COLOR)
+ self.modify_bg(gtk.STATE_NORMAL, color)
+
+ self.setDrum = setDrum
+ self.instrumentList = []
+ keys = Config.INSTRUMENTS.keys()
+ for key in Config.INSTRUMENTS.keys():
+ if Config.INSTRUMENTS[key].category == "kit":
+ self.instrumentList.append( key )
+ self.instrumentList.sort()
+ self.drawDrums()
+
+ def drawDrums(self):
+ firstBtn = None
+ btnBox = RoundHBox(fillcolor = '#6F947B', bordercolor = Config.PANEL_BCK_COLOR, radius = Config.PANEL_RADIUS)
+ btnBox.set_border_width(Config.PANEL_SPACING)
+ self.drums = {}
+ for drumkit in self.instrumentList:
+ instBox = RoundVBox(fillcolor = Config.INST_BCK_COLOR, bordercolor = Config.PANEL_COLOR, radius = Config.PANEL_RADIUS)
+ instBox.set_border_width(Config.PANEL_SPACING)
+ self.drums[drumkit] = ImageRadioButton(firstBtn, Config.IMAGE_ROOT + drumkit + '.png' , Config.IMAGE_ROOT + drumkit + 'sel.png', Config.IMAGE_ROOT + drumkit + 'sel.png')
+ self.drums[drumkit].clickedHandler = self.drums[drumkit].connect('clicked',self.setDrums,drumkit)
+ if firstBtn == None:
+ firstBtn = self.drums[drumkit]
+ instBox.pack_start(self.drums[drumkit], False, False, 0)
+ btnBox.pack_start(instBox, False, False, 0)
+ self.add(btnBox)
+ self.show_all()
+
+ def setDrums(self,widget,data):
+ if widget.get_active():
+ if self.setDrum:
+ widget.event( gtk.gdk.Event( gtk.gdk.LEAVE_NOTIFY ) ) # fake the leave event
+ self.setDrum(data)
+
+ def set_activeInstrument( self, instrument, state ):
+ if instrument in self.instrumentList:
+ btn = self.drums[instrument]
+ btn.handler_block(btn.clickedHandler)
+ btn.set_active(state)
+ btn.handler_unblock(btn.clickedHandler)
+
+if __name__ == "__main__":
+ win = gtk.Window()
+ wc = DrumPanel(None)
+ win.add(wc)
+ win.show()
+ #start the gtk event loop
+ gtk.main()
diff --git a/common/Util/Instrument_.py b/common/Util/Instrument_.py
new file mode 100644
index 0000000..5bc74b3
--- /dev/null
+++ b/common/Util/Instrument_.py
@@ -0,0 +1,392 @@
+#!/bin/env python
+import os
+
+##############
+## SOUNDS
+##############
+
+#INSTRUMENTS ( csound table, csound instrument, register, instrumentClass, category )
+CSOUND_INSTRUMENT = {'inst_free' : 5000, 'inst_tied' : 5001, 'inst_simp': 5011, 'inst_perc': 5021}
+
+SOUND_ROOT = os.getenv("HOME") + '/cvs/tamtam/snd'
+KIT_ROOT = SOUND_ROOT + "/drum"
+INST_ROOT = SOUND_ROOT + "/inst"
+
+INST = {}
+inst_load_dynamic = 0
+class Instrument:
+ REGISTER = {'low': 0, 'mid':1, 'high':2, 'punch':3}
+ def __init__( self, name, csoundInstrumentName, registerName, category, loopStart, loopEnd, crossDur, wav, img ):
+ self.name = name
+ self.instrumentId = len(INST)
+ self.csoundInstrumentName = csoundInstrumentName
+ self.csoundInstrumentId = CSOUND_INSTRUMENT[csoundInstrumentName]
+ self.register = registerName
+ self.category = category
+ self.loopStart = loopStart
+ self.loopEnd = loopEnd
+ self.crossDur = crossDur
+ self.wav = wav
+ self.img = img
+
+ if None == self.wav: self.wav = os.getenv('HOME') + 'cvs/tamtam/Resources/Sounds/' + name
+ if None == self.img: self.wav = os.getenv('HOME') + 'cvs/tamtam/Resources/Images/' + name
+
+ INST[name] = self
+
+if inst_load_dynamic:
+ for I in os.listdir(INST_ROOT):
+ print 'inst:', I
+else:
+ Instrument( 'mic1', 'inst_tied', 'mid', 'mic', .01, .99, .01, None, None)
+ Instrument( 'mic2', 'inst_tied', 'mid', 'mic', .01, .99, .01, None, None)
+ Instrument( "mic3", 'inst_tied', 'mid', 'mic', .01, .99, .01, None, None)
+ Instrument( "mic4", 'inst_tied', 'mid', 'mic', .01, .99, .01, None, None)
+ Instrument( "lab1", 'inst_simp', 'mid', 'lab', 0, 0, 0, None, None)
+ Instrument( "lab2", 'inst_simp', 'mid', 'lab', 0, 0, 0, None, None)
+ Instrument( "lab3", 'inst_simp', 'mid', 'lab', 0, 0, 0, None, None)
+ Instrument( "lab4", 'inst_simp', 'mid', 'lab', 0, 0, 0, None, None)
+ Instrument( "lab5", 'inst_simp', 'mid', 'lab', 0, 0, 0, None, None)
+ Instrument( "lab6", 'inst_simp', 'mid', 'lab', 0, 0, 0, None, None)
+ Instrument( "ounk", 'inst_simp', 'mid', 'animals', 0, 0, 0 , None, None)
+ Instrument( "gam", 'inst_tied', 'high', 'percussions', .69388, .7536, .02922 , None, None)
+ Instrument( "guit", 'inst_tied', 'mid', 'strings', .08592, .75126, .33571 , None, None)
+ Instrument( "koto", 'inst_tied', 'high', 'strings', .56523, .70075, .05954 , None, None)
+ Instrument( "clarinette", 'inst_tied', 'mid', 'winds', .57905, .73319, .04934 , None, None)
+ Instrument( "flute", 'inst_tied', 'mid', 'winds', .47169, .53693, .02481 , None, None)
+ Instrument( "drum1hatpedal", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum1hatshoulder", 'inst_simp', 'high', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum1hardride", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum1ridebell", 'inst_simp', 'high', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum1snare", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum1snaresidestick", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum1crash", 'inst_simp', 'punch', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum1splash", 'inst_simp', 'punch', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum1tom", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum1floortom", 'inst_simp', 'low', 'drum', 0, 0, 0, None, None)
+ Instrument( "drum1chine", 'inst_simp', 'punch', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum1kick", 'inst_simp', 'low', 'drum', 0, 0, 0 , None, None)
+ Instrument( "piano", 'inst_tied', 'mid', 'keyboard', 2.39418, 2.53339, .01323 , None, None)
+ Instrument( "dog", 'inst_simp', 'mid', 'animals', 0, 0, 0 , None, None)
+ Instrument( "duck", 'inst_simp', 'mid', 'animals', 0, 0, 0 , None, None)
+ Instrument( "drum2darbukadoom", 'inst_simp', 'low', 'drum', 0, 0 ,0 , None, None)
+ Instrument( "drum2darbukapied", 'inst_simp', 'low', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum2darbukapiedsoft", 'inst_simp', 'low', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum2hatflanger", 'inst_simp', 'punch', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum2darbukatak", 'inst_simp', 'punch', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum2darbukafinger", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum2darbukaroll", 'inst_simp', 'high', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum2darbukaslap", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum2hatpied", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum2tambourinepied", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum2hatpied2", 'inst_simp', 'high', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum2tambourinepiedsoft", 'inst_simp', 'high', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum3cowbell", 'inst_simp', 'high', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum3cowbelltip", 'inst_simp', 'mid', 'drum', 0, 0, 0, None, None)
+ Instrument( "drum3cup", 'inst_simp', 'high', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum3djembelow", 'inst_simp', 'low', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum3djembemid", 'inst_simp', 'high', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum3djembesidestick", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum3djembeslap", 'inst_simp', 'low', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum3djembestickmid", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum3metalstand", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum3pedalperc", 'inst_simp', 'low', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum3rainstick", 'inst_simp', 'punch', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum3tambourinehigh", 'inst_simp', 'punch', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum3tambourinelow", 'inst_simp', 'punch', 'drum', 0, 0, 0 , None, None)
+ Instrument( "harmonica", 'inst_tied', 'mid', 'winds', .1531, .19188, .01792 , None, None)
+ Instrument( "alarm", 'inst_tied', 'mid', 'concret', .02, .19133, .01 , None, None)
+ Instrument( "bird", 'inst_tied', 'mid', 'animals', .1, 1, .05 , None, None)
+ Instrument( "cat", 'inst_simp', 'mid', 'animals', 0, 0, 0 , None, None)
+ Instrument( "duck2", 'inst_simp', 'mid', 'animals', 0, 0, 0 , None, None)
+ Instrument( "bottle", 'inst_tied', 'mid', 'concret', .20532, .41064, .05292 , None, None)
+ Instrument( "clang", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "ow", 'inst_simp', 'mid', 'people', 0, 0, 0 , None, None)
+ Instrument( "sheep", 'inst_simp', 'mid', 'animals', 0, 0, 0 , None, None)
+ Instrument( "water", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "zap", 'inst_tied', 'mid', 'electronic', .299, .7323, .09895 , None, None)
+ Instrument( "trumpet", 'inst_tied', 'mid', 'winds', .39934, .45537, .02729, None, None)
+ Instrument( "bubbles", 'inst_tied', 'mid', 'concret', 0.02, 1.177, 0.02, None, None)
+ Instrument( "marimba", 'inst_tied', 'mid', 'percussions', .26545, .33098, .03087, None, None)
+ Instrument( "triangle", 'inst_tied', 'mid', 'percussions', 1.21002, 1.31805, .01268, None, None)
+ Instrument( "laugh", 'inst_simp', 'mid', 'people', 0, 0, 0 , None, None)
+ Instrument( "voix", 'inst_tied', 'mid', 'people', .89608, .96092, .02343 , None, None)
+ Instrument( "cling", 'inst_tied', 'mid', 'electronic', .09096, .7878, .18026 , None, None)
+ Instrument( "byke", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "door", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "basse", 'inst_tied', 'mid', 'strings', .58455, .67433, .03638 , None, None)
+ Instrument( "acguit", 'inst_tied', 'mid', 'strings', .58503, .8667, .13699 , None, None)
+ Instrument( "diceinst", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "didjeridu", 'inst_tied', 'low', 'winds', .55669, 1.73704, .09178 , None, None)
+ Instrument( "harmonium", 'inst_tied', 'mid', 'keyboard', .04674, .41073, .18384 , None, None)
+ Instrument( "horse", 'inst_simp', 'mid', 'animals', 0, 0, 0 , None, None)
+ Instrument( "kalimba", 'inst_tied', 'mid', 'percussions', .20751, .30161, .04658 , None, None)
+ Instrument( "mando", 'inst_tied', 'mid', 'strings', .50167, .54401, .01984 , None, None)
+ Instrument( "ocarina", 'inst_tied', 'mid', 'winds', .06612, .19033, .01776 , None, None)
+ Instrument( "rhodes", 'inst_tied', 'mid', 'keyboard', .65013, .71429, .02205 , None, None)
+ Instrument( "saxo", 'inst_tied', 'mid', 'winds', .53722, .6583, .05264 , None, None)
+ Instrument( "shenai", 'inst_tied', 'mid', 'winds', .29003, .33072, .00634 , None, None)
+ Instrument( "sitar", 'inst_tied', 'mid', 'strings', .63187, .67882, .01654 , None, None)
+ Instrument( "tuba", 'inst_tied', 'low', 'winds', .51063, .58384, .035 , None, None)
+ Instrument( "violin", 'inst_tied', 'mid', 'strings', .105, .30656, .028 , None, None)
+ Instrument( "guidice1", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "guidice2", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "guidice3", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "guidice4", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "guidice5", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "guidice6", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "guidice7", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "guidice8", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "guidice9", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "guidice10", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "drum4afrofeet", 'inst_simp', 'low', 'drum', 0, 0 ,0 , None, None)
+ Instrument( "drum4fingersn", 'inst_simp', 'high', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum4mutecuic", 'inst_simp', 'punch', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum4stompbass", 'inst_simp', 'punch', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum4tambouri", 'inst_simp', 'high', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum4tr707clap", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum4tr707open", 'inst_simp', 'punch', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum4tr808closed", 'inst_simp', 'high', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum4tr808sn", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum4tr909bass", 'inst_simp', 'low', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum4tr909kick", 'inst_simp', 'low', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum4tr909sn", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum5timablesslap", 'inst_simp', 'low', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum5congagraveouvert", 'inst_simp', 'low', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum5timablesaiguslap", 'inst_simp', 'low', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum5congagraveferme", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum5guiroretour", 'inst_simp', 'punch', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum5vibraslap", 'inst_simp', 'punch', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum5congaaiguouvert", 'inst_simp', 'mid', 'drum', 0, 0 ,0 , None, None)
+ Instrument( "drum5quicamedium", 'inst_simp', 'punch', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum5quicaaigu", 'inst_simp', 'mid', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum5agogograve", 'inst_simp', 'high', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum5bongoaiguouvert", 'inst_simp', 'high', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum5agogoaigu", 'inst_simp', 'high', 'drum', 0, 0, 0 , None, None)
+ Instrument( "drum5bongograveouvert", 'inst_simp', 'high', 'drum', 0, 0, 0 , None, None)
+ Instrument( "camera", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "car", 'inst_tied', 'mid', 'concret', .67, 1.05761, .01 , None, None)
+ Instrument( "chimes", 'inst_tied', 'mid', 'percussions', .09, 2.97633, .01 , None, None)
+ Instrument( "crash", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "guit2", 'inst_tied', 'mid', 'strings', .33, 1.1583, .02 , None, None)
+ Instrument( "plane", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+ Instrument( "slap", 'inst_simp', 'mid', 'concret', 0, 0, 0 , None, None)
+INST_byId = {}
+for i in INST:
+ INST_byId[ INST[i].instrumentId] = INST[i]
+
+KIT_ELEMENT = 24 * [0]
+for i in range(0,13):
+ KIT_ELEMENT += 2 * [i]
+
+KIT = {}
+drum_load_dynamic = 0
+if drum_load_dynamic:
+ for D in os.listdir(KIT_ROOT):
+ print 'drum:',D
+else:
+ KIT = {
+ 'drum1kit' : [ 'drum1kick', 'drum1floortom', 'drum1tom',
+ 'drum1chine', 'drum1splash', 'drum1crash',
+ 'drum1snaresidestick', 'drum1snaresidestick', 'drum1snare',
+ 'drum1ridebell', 'drum1hardride', 'drum1hatshoulder',
+ 'drum1hatpedal'],
+ 'drum2kit' : [ "drum2darbukadoom", "drum2darbukapied", "drum2darbukapiedsoft",
+ "drum2hatflanger", "drum2darbukatak", "drum2darbukatak",
+ "drum2darbukafinger", "drum2darbukaroll", "drum2darbukaslap",
+ "drum2hatpied", "drum2tambourinepied", "drum2hatpied2",
+ "drum2tambourinepiedsoft"],
+ 'drum3kit' : [ "drum3djembelow", "drum3pedalperc", "drum3djembeslap",
+ "drum3tambourinehigh", "drum3tambourinelow", "drum3rainstick",
+ "drum3djembemid", "drum3djembesidestick", "drum3djembestickmid",
+ "drum3cowbell", "drum3cowbelltip", "drum3cup",
+ "drum3metalstand"],
+ 'drum4kit' : [ "drum4afrofeet", "drum4tr909kick", "drum4tr909bass",
+ "drum4stompbass", "drum4tr707open", "drum4mutecuic",
+ "drum4tr808sn", "drum4tr707clap", "drum4tr909sn",
+ "drum4tambouri", "drum4fingersn", "drum4fingersn",
+ "drum4tr808closed" ],
+ 'drum5kit' : [ "drum5timablesslap", "drum5timablesaiguslap", "drum5congagraveouvert",
+ "drum5quicamedium", "drum5guiroretour", "drum5vibraslap",
+ "drum5congagraveferme", "drum5quicaaigu", "drum5congaaiguouvert",
+ "drum5agogoaigu", "drum5bongograveouvert", "drum5agogograve",
+ "drum5bongoaiguouvert" ]
+ }
+
+for name in KIT:
+ KIT[name] = [ INST[e] for e in KIT[name] ]
+
+if 0:
+ _nextInstrumentId = [0]
+ INSTRUMENTS = {}
+ write_instrument_config = 0
+ hard_coded_instruments = 0
+ if hard_coded_instruments:
+ def _addInstrument( name, csoundInstrumentId, instrumentRegister, soundClass, category, loopStart, loopEnd, crossDur, kit = None ):
+ if write_instrument_config:
+ if (kit == None):
+ blah = file('snd/'+name+'.snd', 'w')
+ print >>blah, (csoundInstrumentId, instrumentRegister, soundClass, category, loopStart, loopEnd, crossDur)
+ blah.close()
+ else:
+ sys.exit(1)
+
+ INSTRUMENTS[name] = Instrument( name, _nextInstrumentId[0], csoundInstrumentId, instrumentRegister, soundClass, category, loopStart, loopEnd, crossDur, kit )
+ _nextInstrumentId[0] += 1
+
+ DRUM1KIT = { 24 : INSTRUMENTS["drum1kick"],
+ 26 : INSTRUMENTS["drum1floortom"],
+ 28 : INSTRUMENTS["drum1tom"],
+ 30 : INSTRUMENTS["drum1chine"],
+ 32 : INSTRUMENTS["drum1splash"],
+ 34 : INSTRUMENTS["drum1crash"],
+ 36 : INSTRUMENTS["drum1snaresidestick"],
+ 38 : INSTRUMENTS["drum1snaresidestick"],
+ 40 : INSTRUMENTS["drum1snare"],
+ 42 : INSTRUMENTS["drum1ridebell"],
+ 44 : INSTRUMENTS["drum1hardride"],
+ 46 : INSTRUMENTS["drum1hatshoulder"],
+ 48 : INSTRUMENTS["drum1hatpedal"] }
+
+ DRUM2KIT = { 24 : INSTRUMENTS["drum2darbukadoom"],
+ 26 : INSTRUMENTS["drum2darbukapied"],
+ 28 : INSTRUMENTS["drum2darbukapiedsoft"],
+ 30 : INSTRUMENTS["drum2hatflanger"],
+ 32 : INSTRUMENTS["drum2darbukatak"],
+ 34 : INSTRUMENTS["drum2darbukatak"],
+ 36 : INSTRUMENTS["drum2darbukafinger"],
+ 38 : INSTRUMENTS["drum2darbukaroll"],
+ 40 : INSTRUMENTS["drum2darbukaslap"],
+ 42 : INSTRUMENTS["drum2hatpied"],
+ 44 : INSTRUMENTS["drum2tambourinepied"],
+ 46 : INSTRUMENTS["drum2hatpied2"],
+ 48 : INSTRUMENTS["drum2tambourinepiedsoft"] }
+
+ DRUM3KIT = { 24 : INSTRUMENTS["drum3djembelow"],
+ 26 : INSTRUMENTS["drum3pedalperc"],
+ 28 : INSTRUMENTS["drum3djembeslap"],
+ 30 : INSTRUMENTS["drum3tambourinehigh"],
+ 32 : INSTRUMENTS["drum3tambourinelow"],
+ 34 : INSTRUMENTS["drum3rainstick"],
+ 36 : INSTRUMENTS["drum3djembemid"],
+ 38 : INSTRUMENTS["drum3djembesidestick"],
+ 40 : INSTRUMENTS["drum3djembestickmid"],
+ 42 : INSTRUMENTS["drum3cowbell"],
+ 44 : INSTRUMENTS["drum3cowbelltip"],
+ 46 : INSTRUMENTS["drum3cup"],
+ 48 : INSTRUMENTS["drum3metalstand"] }
+
+ DRUM4KIT = { 24 : INSTRUMENTS["drum4afrofeet"],
+ 26 : INSTRUMENTS["drum4tr909kick"],
+ 28 : INSTRUMENTS["drum4tr909bass"],
+ 30 : INSTRUMENTS["drum4stompbass"],
+ 32 : INSTRUMENTS["drum4tr707open"],
+ 34 : INSTRUMENTS["drum4mutecuic"],
+ 36 : INSTRUMENTS["drum4tr808sn"],
+ 38 : INSTRUMENTS["drum4tr707clap"],
+ 40 : INSTRUMENTS["drum4tr909sn"],
+ 42 : INSTRUMENTS["drum4tambouri"],
+ 44 : INSTRUMENTS["drum4fingersn"],
+ 46 : INSTRUMENTS["drum4fingersn"],
+ 48 : INSTRUMENTS["drum4tr808closed"] }
+
+ DRUM5KIT = { 24 : INSTRUMENTS["drum5timablesslap"],
+ 26 : INSTRUMENTS["drum5timablesaiguslap"],
+ 28 : INSTRUMENTS["drum5congagraveouvert"],
+ 30 : INSTRUMENTS["drum5quicamedium"],
+ 32 : INSTRUMENTS["drum5guiroretour"],
+ 34 : INSTRUMENTS["drum5vibraslap"],
+ 36 : INSTRUMENTS["drum5congagraveferme"],
+ 38 : INSTRUMENTS["drum5quicaaigu"],
+ 40 : INSTRUMENTS["drum5congaaiguouvert"],
+ 42 : INSTRUMENTS["drum5agogoaigu"],
+ 44 : INSTRUMENTS["drum5bongograveouvert"],
+ 46 : INSTRUMENTS["drum5agogograve"],
+ 48 : INSTRUMENTS["drum5bongoaiguouvert"] }
+
+ _addInstrument( "drum1kit", 0, 0, 0, "kit", 0, 0, 0, DRUM1KIT )
+ _addInstrument( "drum2kit", 0, 0, 0, "kit", 0, 0, 0, DRUM2KIT )
+ _addInstrument( "drum3kit", 0, 0, 0, "kit", 0, 0, 0, DRUM3KIT )
+ _addInstrument( "drum4kit", 0, 0, 0, "kit", 0, 0, 0, DRUM4KIT )
+ _addInstrument( "drum5kit", 0, 0, 0, "kit", 0, 0, 0, DRUM5KIT )
+
+ else:
+
+ sndlist = os.listdir('snd/')
+ #print sndlist
+ sndpaths = [p for p in sndlist if p[-4:] == '.snd']
+
+ #load the normal instruments
+ for sndpath in sndpaths:
+ name = sndpath[0:-4]
+ sndfile = file('snd/'+sndpath, 'r')
+ line = sndfile.readline()
+ #print sndpath, line
+ tup = eval(line)
+ if len(tup) == 7:
+ csoundInstrumentId, instrumentRegister, soundClass, category, loopStart, loopEnd, crossDur = tup
+ INSTRUMENTS[name] = Instrument( name, _nextInstrumentId[0],
+ csoundInstrumentId, instrumentRegister, soundClass,
+ category, loopStart, loopEnd, crossDur, None, None, None )
+ else:
+ print 'loading a gooddmammn img and wav thing!'
+ csoundInstrumentId, instrumentRegister, soundClass, category, loopStart, loopEnd, crossDur, wav, img = tup
+ INSTRUMENTS[name] = Instrument( name, _nextInstrumentId[0],
+ csoundInstrumentId, instrumentRegister, soundClass,
+ category, loopStart, loopEnd, crossDur, None , wav, img)
+ _nextInstrumentId[0] += 1
+ sndfile.close()
+
+ #load the kits
+ if 0:
+ kitpaths = [p for p in sndlist if p[-4:] == '.kit'] #don't use these for now..
+ for kitpath in kitpaths:
+ kitidx = int( kitpath[4] )
+ print kitpath, kitidx
+ exec "DRUM%iKIT = {} ; curkit = DRUM%iKIT" % (kitidx,kitidx)
+ name = kitpath[0:-4]
+ kitfile = file('snd/'+ kitpath, 'r')
+ line = kitfile.readline()
+ print kitpath, line
+
+ keyval = eval(line)
+ for kv in keyval:
+ curkit[kv[0]] = INSTRUMENTS[kv[1]]
+
+ #csoundInstrumentId, instrumentRegister, soundClass, category, loopStart, loopEnd, crossDur = eval( line )
+ INSTRUMENTS[name] = Instrument( name, _nextInstrumentId[0], 0, 0, 0, "kit", 0, 0, 0, curkit)
+ _nextInstrumentId[0] += 1
+ kitfile.close()
+
+ else:
+ def _addInstrument( name, csoundInstrumentId, instrumentRegister, soundClass, category, loopStart, loopEnd, crossDur, kit = None ):
+ blah = file('snd/' + name + '.kit', 'w')
+ print >>blah, [(k, kit[k].name) for k in kit.keys()]
+ blah.close()
+ INSTRUMENTS[name] = Instrument( name, _nextInstrumentId[0], csoundInstrumentId, instrumentRegister, soundClass, category, loopStart, loopEnd, crossDur, kit )
+ _nextInstrumentId[0] += 1
+ print INSTRUMENTS[name]
+
+
+ _addInstrument( "drum1kit", 0, 0, 0, "kit", 0, 0, 0, DRUM1KIT )
+ _addInstrument( "drum2kit", 0, 0, 0, "kit", 0, 0, 0, DRUM2KIT )
+ _addInstrument( "drum3kit", 0, 0, 0, "kit", 0, 0, 0, DRUM3KIT )
+ _addInstrument( "drum4kit", 0, 0, 0, "kit", 0, 0, 0, DRUM4KIT )
+ _addInstrument( "drum5kit", 0, 0, 0, "kit", 0, 0, 0, DRUM5KIT )
+
+ #import sys
+ #sys.exit(0)
+
+ INSTRUMENTSID = {}
+ for i in INSTRUMENTS:
+ INSTRUMENTSID[INSTRUMENTS[i].instrumentId] = INSTRUMENTS[i]
+
+
+ #DRUMKITS = ['drum1kit', 'drum2kit', 'drum3kit', 'drum4kit']
+ #DRUMSINSTRUMENTSDICT = [DRUM1KIT, DRUM2KIT, DRUM3KIT, DRUM4KIT]
+
+ RECORDABLE_INSTRUMENTS = set( [ "mic1", "mic2", "mic3", "mic4" ] )
+ RECORDABLE_INSTRUMENT_CSOUND_IDS = { "mic1" : 7,
+ "mic2" : 8,
+ "mic3" : 9,
+ "mic4" : 10 }
diff --git a/common/Util/KeyboardWindow.py b/common/Util/KeyboardWindow.py
new file mode 100644
index 0000000..507276b
--- /dev/null
+++ b/common/Util/KeyboardWindow.py
@@ -0,0 +1,181 @@
+#!/usr/bin/env python
+import pygtk
+pygtk.require( '2.0' )
+import gtk
+import random
+from common.Util.ThemeWidgets import keyButton
+import common.Config as Config
+KEY_MAP_PIANO = Config.KEY_MAP_PIANO
+
+class KeyboardWindow(gtk.Window):
+ def __init__(self, size = None, pos = 0, popup = False):
+ if popup is False:
+ gtk.Window.__init__(self , gtk.WINDOW_TOPLEVEL)
+ else:
+ gtk.Window.__init__(self , gtk.WINDOW_POPUP)
+ color = gtk.gdk.color_parse("#000000")
+ self.modify_bg(gtk.STATE_NORMAL, color)
+ self.set_decorated(False)
+
+ self.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.ENTER_NOTIFY_MASK | gtk.gdk.KEY_PRESS_MASK)
+ self.connect("key-press-event",self.handle_keypress)
+ self.connect("key-release-event",self.handle_keyrelease)
+ self.connect("button-press-event",self.handle_mousePress)
+ self.connect("button-release-event",self.handle_mouseRelease)
+ self.connect("enter-notify-event",self.handle_enter)
+
+ self.size = size
+ self.pos = pos
+ self.popup = popup
+ self.set_pos(self.pos)
+
+ if self.size == None:
+ self.pixel_space = 15
+ self.height = 45
+ else:
+ self.pixel_space = size
+ self.height = 3 * size
+
+ self.draw()
+
+ def draw(self):
+ self.rows = {}
+ self.rows[1] = [(49,1), (10,3), (11,3), (12,3), (13,3), (14,3), (15,3), (16,3), (17,3), (18,3), (19,3), (20,3), (21,5)]
+ self.rows[2] = [(23,3), (24,3), (25,3), (26,3), (27,3), (28,3), (29,3), (30,3), (31,3), (32,3), (33,3), (34,3), (35,4)]
+ self.rows[3] = [(37,4), (38,3), (39,3), (40,3), (41,3), (42,3), (43,3), (44,3), (45,3), (46,3), (47,3), (48,3), (51,3)]
+ self.rows[4] = [(50,6), (52,3), (53,3), (54,3), (55,3), (56,3), (57,3), (58,3), (59,3), (60,3), (61,3), (62,5)]
+ self.rows[5] = [(216,1),(133,4),(64,4), (65,25), (108,4), (134,4,), (113,3)]
+
+ self.right_section = [(22,7),(36,(7,7)),(111,3),(219,3),(116,3),(114,3)]
+
+ self.btn_dic = {}
+
+ mainvbox = gtk.VBox()
+ mainhbox = gtk.HBox()
+
+ #Main keyboard section
+ vbox = gtk.VBox()
+ for row in [1,2,3,4,5]:
+ hbox = gtk.HBox()
+ for key in self.rows[row]:
+ self.btn_dic[key[0]] = keyButton(self.pixel_space * key[1], self.height, [0,0,0], [0.5,0.5,0.5])
+ hbox.pack_start(self.btn_dic[key[0]], padding = self.pixel_space//2)
+ vbox.pack_start(hbox, padding = self.pixel_space//2)
+ mainhbox.pack_start(vbox)
+
+ #Right part of the keyboard
+ right_vbox = gtk.VBox()
+ right_tophbox = gtk.HBox()
+ right_lowhbox = gtk.HBox()
+
+ self.btn_dic[self.right_section[0][0]] = keyButton(self.pixel_space * self.right_section[0][1], self.height, [0,0,0], [0.5,0.5,0.5])
+ self.btn_dic[self.right_section[1][0]] = keyButton(self.pixel_space * self.right_section[1][1][0], self.pixel_space * self.right_section[1][1][1], [0,0,0], [0.5,0.5,0.5])
+ self.btn_dic[self.right_section[2][0]] = keyButton(self.pixel_space * self.right_section[2][1], self.height, [0,0,0], [0.5,0.5,0.5])
+ self.btn_dic[self.right_section[3][0]] = keyButton(self.pixel_space * self.right_section[3][1], self.height, [0,0,0], [0.5,0.5,0.5])
+ self.btn_dic[self.right_section[4][0]] = keyButton(self.pixel_space * self.right_section[4][1], self.height, [0,0,0], [0.5,0.5,0.5])
+ self.btn_dic[self.right_section[5][0]] = keyButton(self.pixel_space * self.right_section[5][1], self.height, [0,0,0], [0.5,0.5,0.5])
+
+ right_vbox.pack_start(self.btn_dic[self.right_section[0][0]], padding = self.pixel_space//2)
+ right_vbox.pack_start(self.btn_dic[self.right_section[1][0]], padding = self.pixel_space//2)
+ right_tophbox.pack_start(self.btn_dic[self.right_section[2][0]], padding = self.pixel_space//2)
+ right_tophbox.pack_start(self.btn_dic[self.right_section[3][0]], padding = self.pixel_space//2)
+ right_lowhbox.pack_start(self.btn_dic[self.right_section[4][0]], padding = self.pixel_space//2)
+ right_lowhbox.pack_start(self.btn_dic[self.right_section[5][0]], padding = self.pixel_space//2)
+ right_vbox.pack_start(right_tophbox, padding = self.pixel_space//2)
+ right_vbox.pack_start(right_lowhbox, padding = self.pixel_space//2)
+
+ #Mouse buttons
+ mouse_hbox = gtk.HBox()
+ self.btn_dic["left_mouse"] = keyButton(self.pixel_space * 6, self.pixel_space * 2, [0,0,0], [0.5,0.5,0.5])
+ self.btn_dic["right_mouse"] = keyButton(self.pixel_space * 6, self.pixel_space * 2, [0,0,0], [0.5,0.5,0.5])
+ mouse_hbox.pack_start(self.btn_dic["left_mouse"], True, True, self.pixel_space//2)
+ mouse_hbox.pack_end(self.btn_dic["right_mouse"], True, True, self.pixel_space//2)
+
+
+ #Enter and Leave connections
+ for key in self.btn_dic:
+ self.btn_dic[key].connect("enter",self.handle_mouseEnter)
+ self.btn_dic[key].connect("leave",self.handle_mouseLeave)
+
+ mainhbox.pack_start(right_vbox)
+ mainvbox.pack_start(mainhbox)
+ mainvbox.pack_start(mouse_hbox, padding = self.pixel_space//2)
+
+ self.add(mainvbox)
+
+ def set_pos(self,_pos = 0):
+ width = self.get_screen().get_width()
+ height = self.get_screen().get_height()
+ win_width = self.get_size()[0]
+ win_height = self.get_size()[1]
+
+ self.pos = _pos
+
+ pos = [0,0]
+ pos[0] = (0, 0)
+ pos[1] = (width - win_width, height - win_height)
+ self.move(pos[self.pos][0],pos[self.pos][1])
+
+ def color_piano(self):
+ for key in KEY_MAP_PIANO:
+ self.btn_dic[key].set_fillcolor(1,1,1)
+
+
+ def handle_keypress(self,widget,event):
+ if event.hardware_keycode == 9: # Hide the keyboard with escape Key
+ self.hide_all()
+ elif event.hardware_keycode == 216: # Send a fake mouse event
+ self.btn_dic["left_mouse"].set_fillcolor(random.random(),random.random(),random.random())
+ elif event.hardware_keycode == 133: # Send a fake mouse event
+ self.btn_dic["right_mouse"].set_fillcolor(random.random(),random.random(),random.random())
+ else:
+ if self.btn_dic.has_key(event.hardware_keycode):
+ self.btn_dic[event.hardware_keycode].set_fillcolor(random.random(),random.random(),random.random())
+
+ def handle_keyrelease(self,widget,event):
+ if KEY_MAP_PIANO.has_key(event.hardware_keycode):
+ self.btn_dic[event.hardware_keycode].set_fillcolor(1,1,1)
+ else:
+ if self.btn_dic.has_key(event.hardware_keycode):
+ self.btn_dic[event.hardware_keycode].set_fillcolor(0,0,0)
+ if event.hardware_keycode == 216 or event.hardware_keycode == 133:
+ self.btn_dic["left_mouse"].set_fillcolor(0,0,0)
+ self.btn_dic["right_mouse"].set_fillcolor(0,0,0)
+
+
+ def handle_mousePress(self,widget,event):
+ if event.button == 1:
+ self.btn_dic["left_mouse"].set_fillcolor(random.random(),random.random(),random.random())
+ elif event.button == 3:
+ self.btn_dic["right_mouse"].set_fillcolor(random.random(),random.random(),random.random())
+
+ def handle_mouseRelease(self,widget,event):
+ if event.button == 1:
+ self.btn_dic["left_mouse"].set_fillcolor(0,0,0)
+ elif event.button == 3:
+ self.btn_dic["right_mouse"].set_fillcolor(0,0,0)
+
+ def handle_mouseEnter(self,widget,event = None):
+ widget.set_strokecolor(1,1,1)
+
+ def handle_mouseLeave(self,widget,event = None):
+ widget.set_strokecolor(0.5,0.5,0.5)
+
+ def handle_enter(self,widget,event):
+ if self.popup is False:
+ return
+ if self.pos == 0:
+ self.set_pos(1)
+ else:
+ self.set_pos(0)
+
+ def close(self,widget,event = None):
+ self.hide_all()
+
+
+
+if __name__ == "__main__":
+ win = KeyboardWindow()
+ win.connect("destroy",gtk.main_quit)
+ win.show_all()
+ gtk.main() \ No newline at end of file
diff --git a/common/Util/LoopSettings.py b/common/Util/LoopSettings.py
new file mode 100644
index 0000000..e866861
--- /dev/null
+++ b/common/Util/LoopSettings.py
@@ -0,0 +1,230 @@
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+import os
+from common.Util.ThemeWidgets import *
+import common.Config as Config
+import commands
+Tooltips = Config.Tooltips()
+
+class LoopSettings( gtk.VBox ):
+ def __init__( self, popup, playFunction, setChannelFunction, doneLoopSettingsPopup ):
+ gtk.VBox.__init__( self )
+ self.tooltips = gtk.Tooltips()
+ self.popup = popup
+ self.playFunction = playFunction
+ self.setChannel = setChannelFunction
+ self.doneLoopSettingsPopup = doneLoopSettingsPopup
+ self.loopedSound = False
+ self.soundLength = 1.00
+ self.start = 0
+ self.end = 1.00
+ self.dur = 0.01
+ self.register = 0
+ self.ok = True
+
+ self.settingsBox = gtk.HBox()
+ self.pack_start(self.settingsBox)
+
+ self.fixed = gtk.Fixed()
+ self.settingsBox.pack_start(self.fixed)
+
+ self.mainBox = gtk.VBox()
+
+ self.controlsBox = gtk.HBox()
+
+ self.GUI = {}
+
+ nameBox = gtk.VBox()
+ self.nameEntry = gtk.Entry()
+ self.nameEntry.set_text("name_of_the_sound")
+ nameBox.pack_start(self.nameEntry)
+ self.mainBox.pack_start(nameBox, False, False, 5)
+
+ loopedBox = gtk.HBox()
+ loopedLabel = gtk.Label("Looped sound: ")
+ loopedBox.pack_start(loopedLabel)
+ loopedToggle = ImageToggleButton(Config.IMAGE_ROOT+"checkOff.svg",Config.IMAGE_ROOT+"checkOn.svg")
+ loopedToggle.connect('button-press-event', self.handleLooped )
+ loopedBox.pack_start(loopedToggle)
+ self.mainBox.pack_start(loopedBox, False, False, 5)
+
+ categoryBox = gtk.HBox()
+ categoryMenu = gtk.MenuBar()
+ cmenu = gtk.Menu()
+ for cat in Config.CATEGORIES:
+ if cat != 'all':
+ entry = gtk.MenuItem(cat)
+ cmenu.append(entry)
+ entry.connect("activate", self.handleCategory, cat)
+ entry.show()
+ self.categoryButton = gtk.Button("Category")
+ self.categoryButton.connect_object("event", self.categoryBtnPress, cmenu)
+ categoryBox.pack_end(self.categoryButton)
+ #self.mainBox.pack_start(categoryBox, False, False, 5)
+
+ registerBox = gtk.HBox()
+ registerMenu = gtk.MenuBar()
+ rmenu = gtk.Menu()
+ self.registerList = ['LOW', 'MID', 'HIGH', 'PUNCH']
+ for reg in self.registerList:
+ entry = gtk.MenuItem(reg)
+ rmenu.append(entry)
+ entry.connect("activate", self.handleRegister, self.registerList.index(reg))
+ entry.show()
+ self.registerButton = gtk.Button("Register")
+ self.registerButton.connect_object("event", self.registerBtnPress, rmenu)
+ registerBox.pack_end(self.registerButton)
+ self.mainBox.pack_start(registerBox, False, False, 5)
+
+ startBox = gtk.VBox()
+ self.startAdjust = gtk.Adjustment( 0.01, 0, 1., .001, .001, 0)
+ self.GUI['startSlider'] = ImageVScale( Config.TAM_TAM_ROOT + "/Resources/Images/sliderEditVolume.png", self.startAdjust, 7 )
+ self.startAdjust.connect("value-changed", self.handleStart)
+ self.GUI['startSlider'].set_inverted(True)
+ self.GUI['startSlider'].set_size_request(50, 200)
+ self.startEntry = gtk.Entry()
+ self.startEntry.set_width_chars(5)
+ self.handleStart( self.startAdjust )
+ startBox.pack_start(self.GUI['startSlider'], True, True, 5)
+ startBox.pack_start(self.startEntry, True, True, 5)
+ self.controlsBox.pack_start(startBox)
+
+ endBox = gtk.VBox()
+ self.endAdjust = gtk.Adjustment( 0.9, 0, 1, .001, .001, 0)
+ self.GUI['endSlider'] = ImageVScale( Config.TAM_TAM_ROOT + "/Resources/Images/sliderEditVolume.png", self.endAdjust, 7 )
+ self.endAdjust.connect("value-changed", self.handleEnd)
+ self.GUI['endSlider'].set_inverted(True)
+ self.GUI['endSlider'].set_size_request(50, 200)
+ self.endEntry = gtk.Entry()
+ self.endEntry.set_width_chars(5)
+ self.handleEnd( self.endAdjust )
+ endBox.pack_start(self.GUI['endSlider'], True, True, 5)
+ endBox.pack_start(self.endEntry, True, True, 5)
+ self.controlsBox.pack_start(endBox)
+
+ durBox = gtk.VBox()
+ self.durAdjust = gtk.Adjustment( 0.01, 0, 0.2, .001, .001, 0)
+ self.GUI['durSlider'] = ImageVScale( Config.TAM_TAM_ROOT + "/Resources/Images/sliderEditVolume.png", self.durAdjust, 7 )
+ self.durAdjust.connect("value-changed", self.handleDur)
+ self.GUI['durSlider'].set_inverted(True)
+ self.GUI['durSlider'].set_size_request(50, 200)
+ self.durEntry = gtk.Entry()
+ self.durEntry.set_width_chars(5)
+ self.handleDur( self.durAdjust )
+ durBox.pack_start(self.GUI['durSlider'], True, True, 5)
+ durBox.pack_start(self.durEntry, True, True, 5)
+ self.controlsBox.pack_start(durBox)
+
+ self.mainBox.pack_start(self.controlsBox, False, False, 5)
+
+ previewBox = gtk.VBox()
+ self.playStopButton = ImageToggleButton(Config.IMAGE_ROOT + 'miniplay.png', Config.IMAGE_ROOT + 'stop.png')
+ self.playStopButton.connect('button-press-event' , self.handlePlayButton)
+ previewBox.pack_start(self.playStopButton)
+ self.mainBox.pack_start(previewBox, False, False, 5)
+
+ checkBox = gtk.VBox()
+ checkButton = ImageButton(Config.IMAGE_ROOT + 'check.png')
+ checkButton.connect('clicked' , self.handleCheck)
+ checkBox.pack_start(checkButton)
+ self.mainBox.pack_start(checkBox, False, False, 5)
+
+ self.fixed.put( self.mainBox, 0, 0 )
+
+ self.show_all()
+
+ def handleCheck(self, widget):
+ ofile = open(Config.PREF_DIR + "/sounds_settings", 'a')
+ name = self.nameEntry.get_text()
+ if self.loopedSound:
+ tied = str(Config.INST_TIED)
+ else:
+ tied = str(Config.INST_SIMP)
+ register = str(self.register)
+ melo = 'melo'
+ category = 'mysounds'
+ start = str(self.start)
+ end = str(self.end)
+ dur = str(self.dur)
+
+ ofile.write(name + ' ' + tied + ' ' + register + ' ' + melo + ' ' + category + ' ' + start + ' ' + end + ' ' + dur + '\n')
+
+ ofile.close()
+ (s,o) = commands.getstatusoutput('cp ' + Config.SNDS_DIR + '/' + self.oldName + ' ' + Config.SNDS_DIR + '/' + name)
+ self.doneLoopSettingsPopup()
+
+ def set_name(self, name):
+ self.oldName = name
+ self.nameEntry.set_text('_' + name)
+
+ def set_values(self, soundLength):
+ self.soundLength = soundLength
+ self.handleStart(self.GUI['startSlider'])
+ self.handleEnd(self.GUI['endSlider'])
+
+ def handleLooped(self, widget, data=None):
+ if widget.get_active() == True:
+ self.loopedSound = False
+ else:
+ self.loopedSound = True
+
+ def categoryBtnPress(self, widget, event):
+ if event.type == gtk.gdk.BUTTON_PRESS:
+ widget.popup(None, None, None, event.button, event.time)
+ return True
+ return False
+
+ def handleCategory(self, widget, category):
+ self.category = category
+ self.categoryButton.set_label(self.category)
+
+ def registerBtnPress(self, widget, event):
+ if event.type == gtk.gdk.BUTTON_PRESS:
+ widget.popup(None, None, None, event.button, event.time)
+ return True
+ return False
+
+ def handleRegister(self, widget, register):
+ self.register = register
+ self.registerButton.set_label(self.registerList[self.register])
+
+ def handleStart(self, widget, data=None):
+ self.startSlider = self.startAdjust.value
+ self.start = self.startSlider * self.soundLength
+ if self.start > self.end:
+ self.start = self.end
+ self.startEntry.set_text(str(self.start))
+ self.setChannel('lstart', self.start)
+
+ def handleEnd(self, widget, data=None):
+ self.endSlider = self.endAdjust.value
+ self.end = self.endSlider * self.soundLength
+ if self.end < self.start:
+ self.end = self.start
+ self.endEntry.set_text(str(self.end))
+ self.setChannel('lend', self.end)
+
+ def handleDur(self, widget, data=None):
+ self.dur = self.durAdjust.value
+ self.durEntry.set_text(str(self.dur))
+ self.setChannel('ldur', self.dur)
+
+ def handlePlayButton(self, widget, data=None):
+ print widget.get_active()
+ if self.ok:
+ self.playFunction(widget.get_active(), self.loopedSound)
+ if self.loopedSound == False and widget.get_active() == False:
+ self.timeoutStop = gobject.timeout_add(int(self.soundLength * 1000)+500, self.playButtonState)
+
+ def setButtonState(self):
+ self.ok = False
+ self.playStopButton.set_active(False)
+ self.ok = True
+
+ def playButtonState(self):
+ self.ok = False
+ self.playStopButton.set_active(False)
+ gobject.source_remove(self.timeoutStop)
+ self.ok = True
diff --git a/common/Util/Network.py b/common/Util/Network.py
new file mode 100644
index 0000000..8e20a04
--- /dev/null
+++ b/common/Util/Network.py
@@ -0,0 +1,569 @@
+
+#===========================================================================
+# Networking Module
+#
+# - to force host mode create an empty file named "FORCE_HOST" in the base
+# TamTam directory
+# - to force peer mode create a file named "FORCE_PEER" with a single line
+# containing the IP of the host to connect to
+#
+# !! the host must be running before the peers start up !!
+#---------------------------------------------------------------------------
+
+import os
+import socket
+import select
+import threading
+import xdrlib
+import random
+
+import time
+import gtk
+import gobject
+import common.Config as Config
+
+PORT = 24420
+LISTENER_PORT = PORT-1
+WAIT_PORT = PORT-2
+
+BACKLOG = 5 # allow a backlog of N new connections
+MAX_SIZE = 1024 # max message size to receive in one go
+
+MD_OFFLINE = 0
+MD_HOST = 1
+MD_PEER = 2
+MD_WAIT = 3
+
+# enumerate message types
+# format: ("NAME", <message size>)
+# <message size> specified in bytes
+# special:
+# -1 == dynamic, first byte of data containes size
+# -2 == dynamic, first uint32 of data contains size
+message_enum = [
+("HT_LATENCY_REPLY", 4), # reply to latency test
+("HT_SYNC_REPLY", 8), # reply to sync test
+("HT_TEMPO_UPDATE", 4), # reply to sync test
+
+("PR_LATENCY_QUERY", 4), # test latency
+("PR_SYNC_QUERY", 4), # test sync
+("PR_TEMPO_QUERY", 0), # test sync
+("PR_REQUEST_TEMPO_CHANGE", 4), # request tempo change
+
+("MAX_MSG_ID", 0)
+]
+
+# Initialize message ids and MSG_NAME/MSG_SIZE arrays
+MSG_NAME = [""]
+MSG_SIZE = [0]
+i = 1
+for m in message_enum:
+ exec "%s = %d" % (m[0],i)
+ MSG_NAME.append(m[0])
+ MSG_SIZE.append(m[1])
+ i += 1
+del message_enum # clear memory
+if MAX_MSG_ID > 256:
+ print "Network:: MAX_MSG_ID exeeds limit of 256!"
+
+
+class Listener( threading.Thread ):
+
+ def __init__( self, owner, listenerSocket, inputSockets, outputSockets, exceptSockets ):
+ threading.Thread.__init__(self)
+ self.owner = owner
+ self.listenerSocket = listenerSocket
+ self.inputSockets = inputSockets # note that these are array pointers that match
+ self.outputSockets = outputSockets # those of the Network and should not be reset
+ self.exceptSockets = exceptSockets #
+
+ def run(self):
+ while 1: # rely on the owner to kill us when necessary
+ try:
+ inputReady, outputReady, exceptReady = select.select( self.inputSockets, self.outputSockets, self.exceptSockets )
+ if self.listenerSocket in inputReady:
+ data, s = self.listenerSocket.recvfrom(MAX_SIZE)
+ if data == "REFRESH":
+ continue
+ if data == "CLEAR":
+ self.owner._clearSockets()
+ continue
+ else:
+ break # exit thread
+ gtk.gdk.threads_enter()
+ self.owner._processSockets( inputReady, outputReady, exceptReady )
+ gtk.gdk.threads_leave()
+ except socket.error, (value, message):
+ print "Listener:: socket error: " + message
+ gtk.gdk.threads_leave()
+ break
+
+class Connection:
+
+ def __init__( self, sock, address ):
+ self.socket = sock
+ self.address = address
+ self.recvBuf = ""
+ self.waitingForData = 0
+ self.message = 0
+
+class Network:
+
+ def __init__( self, mode = MD_OFFLINE, hostaddress = None ):
+
+ # check for forced networking
+ if os.path.isfile("FORCE_HOST"):
+ mode = MD_HOST
+ elif os.path.isfile("FORCE_PEER"):
+ f = open("FORCE_PEER")
+ l = f.read(16)
+ print l
+ f.close()
+ mode = MD_PEER
+ hostaddress = (l,PORT)
+
+ # prepare message handlers
+ self.processMessage = {}
+ for i in range(1,MAX_MSG_ID):
+ self.processMessage[i] = []
+
+ self.statusWatcher = []
+
+ # data packing classes
+ self.packer = xdrlib.Packer()
+ self.unpacker = xdrlib.Unpacker("")
+
+ self.mode = -1
+ self.listener = None
+ self._fromListener = False
+ try:
+ self.listenerSocket = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
+ self.listenerSocket.bind( ("localhost", LISTENER_PORT) )
+ except socket.error, (value,message):
+ print "Network:: FAILED to open listenerSocket: " + message
+ mode = MD_OFFLINE
+
+ self.inputSockets = [ self.listenerSocket ] # NOTE that these array pointers are passed into
+ self.outputSockets = [] # the Listener and should not be reset
+ self.exceptSockets = [] #
+ self.connection = {} # dict of connections indexed by socket
+
+ self.latencyQueryHandler = {}
+ self.latencyQueryStart = {}
+
+ self.connectMessage( HT_LATENCY_REPLY, self.processHT_LATENCY_REPLY )
+ self.connectMessage( PR_LATENCY_QUERY, self.processPR_LATENCY_QUERY )
+
+ self.setMode( mode, hostaddress )
+
+ def shutdown( self ):
+ if Config.DEBUG > 1: print "Network:: shutting down!"
+
+ if self.listener:
+ self.listenerSocket.sendto( "EXIT", ("localhost",LISTENER_PORT) )
+ time.sleep(0.01) # get off the cpu so the listerer thread has a chance to clear.. IS THERE A BETTER WAY TO DO THIS?
+
+ if self.mode == MD_HOST:
+ for s in self.inputSockets:
+ s.close()
+ elif self.mode == MD_PEER:
+ self.socket.close()
+ self.hostAddress = None
+
+ def setMode( self, mode, hostaddress = None ):
+
+ # cleanup old mode
+ if Config.DEBUG > 1: print "Network:: cleaning up old connections"
+
+ if self._fromListener:
+ self._clearSockets()
+ elif self.listener: # make the listener wake so sockets can close properly
+ self.listenerSocket.sendto( "CLEAR", ("localhost",LISTENER_PORT) )
+ time.sleep(0.01) # get off the cpu so the listerer thread has a chance to clear.. IS THERE A BETTER WAY TO DO THIS?
+
+ self.hostAddress = None
+
+ # initialize new mode
+ self.mode = mode
+ if self.mode == MD_HOST:
+ if Config.DEBUG > 1: print "Network:: initializing network, host mode"
+ try:
+ self.socket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+ address = ("",PORT)
+ self.connection[self.socket] = Connection( self.socket, address )
+ self.socket.bind(address)
+ self.socket.listen(BACKLOG)
+ self.inputSockets.append(self.socket)
+ if not self._fromListener and self.listener:
+ self.listenerSocket.sendto( "REFRESH", ("localhost", LISTENER_PORT) )
+ elif not self.listener:
+ self.listener = Listener( self, self.listenerSocket, self.inputSockets, self.outputSockets, self.exceptSockets )
+ self.listener.start()
+ except socket.error, (value, message):
+ if self.socket:
+ self.socket.close()
+ self.connection.pop(self.socket)
+ print "Network:: FAILED to open socket: " + message
+ self.mode = MD_OFFLINE
+ if self.listener:
+ self.listenerSocket.sendto( "EXIT", ("localhost", LISTENER_PORT) )
+ self.listener = None
+
+ elif self.mode == MD_PEER:
+ if Config.DEBUG > 1: print "Network:: initializing network, client mode: " + hostaddress[0]
+ self.hostAddress = hostaddress
+ try:
+ self.socket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+ self.connection[self.socket] = Connection( self.socket, self.hostAddress )
+ self.socket.connect(self.hostAddress)
+ self.inputSockets.append(self.socket)
+ if not self._fromListener and self.listener:
+ self.listenerSocket.sendto( "REFRESH", ("localhost", LISTENER_PORT) )
+ elif not self.listener:
+ self.listener = Listener( self, self.listenerSocket, self.inputSockets, self.outputSockets, self.exceptSockets )
+ self.listener.start()
+ except socket.error, (value, message):
+ if self.socket:
+ self.socket.close()
+ self.connection.pop(self.socket)
+ print "Network:: FAILED to open socket: " + message
+ self.mode = MD_OFFLINE
+ self.hostAddress = None
+ if self.listener:
+ self.listenerSocket.sendto( "EXIT", ("localhost", LISTENER_PORT) )
+ self.listener = None
+
+ elif self.mode == MD_WAIT:
+ if Config.DEBUG > 1: print "Network:: initializing network, wait mode"
+ try:
+ self.socket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+ address = ("",WAIT_PORT)
+ self.connection[self.socket] = Connection( self.socket, address )
+ self.socket.bind(address)
+ self.socket.listen(BACKLOG)
+ self.inputSockets.append(self.socket)
+ if not self._fromListener and self.listener:
+ self.listenerSocket.sendto( "REFRESH", ("localhost", LISTENER_PORT) )
+ elif not self.listener:
+ self.listener = Listener( self, self.listenerSocket, self.inputSockets, self.outputSockets, self.exceptSockets )
+ self.listener.start()
+ except socket.error, (value, message):
+ if self.socket:
+ self.socket.close()
+ self.connection.pop(self.socket)
+ print "Network:: FAILED to open socket: " + message
+ self.mode = MD_OFFLINE
+ if self.listener:
+ self.listenerSocket.sendto( "EXIT", ("localhost", LISTENER_PORT) )
+ self.listener = None
+
+ else:
+ if Config.DEBUG > 1: print "Network:: offline"
+ if self.listener:
+ self.listenerSocket.sendto( "EXIT", ("localhost", LISTENER_PORT) )
+ self.listener = None
+
+ for watcher in self.statusWatcher:
+ watcher( self.mode )
+
+ def _clearSockets( self ):
+ for s in self.inputSockets:
+ if s != self.listenerSocket:
+ self.inputSockets.remove(s)
+ self.connection.pop(s)
+ s.close()
+ for s in self.outputSockets:
+ self.outputSockets.remove(s)
+ s.close()
+ for s in self.exceptSockets:
+ self.exceptSockets.remove(s)
+ s.close()
+
+
+ def introducePeer( self, ip ):
+ if Config.DEBUG > 1: print "Network:: introducing self to peer " + ip
+ try:
+ poke = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
+ poke.setblocking(0)
+ except socket.error, (value, message):
+ print "Network::introducePeer:: FAILED to open socket: " + message
+ return
+ if poke.connect_ex( (ip, WAIT_PORT) ): # failed to connect
+ gobject.timeout_add( 500, self._pokePeer, poke, ip, 0 )
+ else: # connected
+ if Config.DEBUG > 1: print "Netwtork:: introduction succeeded"
+ poke.close()
+
+ def _pokePeer( self, poke, ip, retry ):
+ if poke.connect_ex( (ip, WAIT_PORT) ): # failed to connect
+ if retry > 120: # give up
+ print "Network::introducePeer:: peer failed to respond after 60 seconds, giving up!"
+ else:
+ gobject.timeout_add( 500, self._pokePeer, poke, ip, retry+1 )
+ else: # connected
+ if Config.DEBUG > 1: print "Netwtork:: introduction succeeded"
+ poke.close()
+
+ return False
+
+
+ def addPeer( self, peer, address ):
+ if Config.DEBUG > 1: print "Network:: adding peer: %s" % address[0]
+ self.connection[peer] = Connection( peer, address )
+ self.inputSockets.append( peer )
+ self.listenerSocket.sendto( "REFRESH", ("localhost", LISTENER_PORT) )
+ #self.listener.updateSockets( self.inputSockets, self.outputSockets, self.exceptSockets )
+
+ def removePeer( self, peer ):
+ if Config.DEBUG > 1: print "Network:: removing peer: %s" % self.connection[peer].address[0]
+ self.connection.pop(peer)
+ self.inputSockets.remove(peer)
+ self.listenerSocket.sendto( "REFRESH", ("localhost", LISTENER_PORT) )
+ #self.listener.updateSockets( self.inputSockets, self.outputSockets, self.exceptSockets )
+
+ # register a status watcher, format: func( self, status, args )
+ def addWatcher( self, func ):
+ self.statusWatcher.append( func )
+
+ def removeWatcher( self, func ):
+ self.statusWatcher.remove( func )
+
+ # connect a message handler, format: func( self, sock, message, data )
+ def connectMessage( self, message, func ):
+ self.processMessage[message].append(func)
+
+ def connectMessageAfter( self, message, func, after ):
+ try:
+ ind = self.processMessage[message].index(after)
+ self.processMessage[message].insert(ind+1,func)
+ except:
+ print "Network::connectMessageAfter:: function not registered: " + str(after)
+
+ def connectMessageBefore( self, message, func, before ):
+ try:
+ ind = self.processMessage[message].index(before)
+ self.processMessage[message].insert(ind,func)
+ except:
+ print "Network::connectMessageBefore:: function not registered: " + str(before)
+
+ def disconnectMessage( self, message, func ):
+ try:
+ self.processMessage[message].remove(func)
+ except:
+ print "Network::disconnectMessage:: function not registered: " + str(func)
+
+ def isOffline( self ):
+ if self.mode == MD_OFFLINE: return True
+ return False
+
+ def isOnline( self ):
+ if self.mode != MD_OFFLINE: return True
+ return False
+
+ def isHost( self ):
+ if self.mode == MD_HOST: return True
+ return False
+
+ def isPeer( self ):
+ if self.mode == MD_PEER: return True
+ return False
+
+ def isWaiting( self ):
+ if self.mode == MD_WAIT: return True
+ return False
+
+
+ #-----------------------------------------------------------------------
+ # Message Senders
+
+ # basic send function
+ # - message type will be automatically inserted before the data
+ # - message size will be automatically inserted if applicable
+ # - to is only defined in HOST mode
+ def send( self, message, data = "", to = None ):
+ if self.mode == MD_OFFLINE:
+ return
+
+ length = len(data)
+ size = MSG_SIZE[message]
+
+ if size >= 0:
+ if length != size:
+ print "Network:: message wrong length! Got %d expected %d: %s" % (len(data), MSG_SIZE[message], MSG_NAME[message])
+ return
+ msg = chr(message) + data
+ elif size == -1:
+ if length > 255:
+ print "Network:: oversized message! Got %d, max size 255: %s" % (length, MSG_NAME[message])
+ return
+ msg = chr(message) + chr(length) + data
+ else: # size == -2
+ self.packer.pack_uint(size)
+ msg = chr(message) + self.packer.get_buffer() + data
+ self.packer.reset()
+
+ if self.mode == MD_PEER:
+ try:
+ self.socket.send( msg )
+ #print "Network:: sent %d bytes: %s" % (len(msg),msg)
+ except socket.error, (value, errmsg):
+ print "Network:: FAILED to send message (%s) to %s: %s" % (MSG_NAME[message], self.hostAddress[0], errmsg)
+ # TODO something intelligent
+ else: # MD_HOST
+ try:
+ to.send( msg )
+ #print "Network:: sent %d bytes: %s" % (len(msg),msg)
+ except socket.error, (value, errmsg):
+ print "Network:: FAILED to send message (%s) to %s: %s" % (MSG_NAME[message], self.connection[to].address[0], errmsg)
+ # TODO something intelligent
+
+
+ def sendAll( self, message, data = "" ):
+ if self.mode != MD_HOST:
+ return
+
+ length = len(data)
+ size = MSG_SIZE[message]
+
+ if size >= 0:
+ if length != size:
+ print "Network:: message wrong length! Got %d expected %d: %s" % (MSG_SIZE[message], len(data), MSG_NAME[message])
+ return
+ msg = chr(message) + data
+ elif size == -1:
+ if length > 255:
+ print "Network:: oversized message! Size %d, max size 255: %s" % (length, MSG_NAME[message])
+ return
+ msg = chr(message) + chr(length) + data
+ else: # size == -2
+ self.packer.pack_uint(size)
+ msg = chr(message) + self.packer.get_buffer() + data
+ self.packer.reset()
+
+ for sock in self.connection:
+ if sock == self.socket:
+ continue
+ try:
+ sock.send( msg )
+ except socket.error, (value, errmsg):
+ print "Network:: FAILED to send message (%s) to %s: %s" % (MSG_NAME[message], self.connection[sock].address[0], errmsg)
+ # TODO something intelligent
+
+ def sendLatencyQuery( self, handler ):
+ if self.mode != MD_PEER:
+ return
+
+ self.packer.pack_float(random.random())
+ hash = self.packer.get_buffer()
+ self.packer.reset()
+ self.latencyQueryHandler[hash] = handler
+ self.latencyQueryStart[hash] = time.time()
+ self.send(PR_LATENCY_QUERY,hash)
+
+ #-----------------------------------------------------------------------
+ # Message Handlers
+
+ def _processSockets( self, inputReady, outputReady, exceptReady ):
+
+ self._fromListener = True
+
+ if self.mode == MD_HOST:
+
+ for s in inputReady:
+ if s == self.socket:
+ # accept new connections
+ try:
+ peer, address = self.socket.accept()
+ self.addPeer( peer, address )
+ except socket.error, (value, message):
+ print "Network:: error accepting connection: " + message
+
+ else:
+ try:
+ data = s.recv(MAX_SIZE)
+ #print "Network:: recv %d bytes: %s" % (len(data), data)
+ if not len(data): # no data to read, socket must be closed
+ self.removePeer(s)
+ else:
+ self.processStream( s, data )
+ except socket.error, (value, message):
+ print "Network:: error reading data: " + message
+
+ elif self.mode == MD_PEER:
+
+ for s in inputReady:
+ try:
+ data = s.recv(MAX_SIZE)
+ if not len(data): # no data to read, socket must be closed
+ self.setMode( MD_OFFLINE )
+ else:
+ #print "Network:: recv %d bytes: %s" % (len(data), data)
+ self.processStream( s, data )
+ except socket.error, (value, message):
+ print "Network:: error reading data: " + message
+
+ else: # MD_WAIT
+
+ for s in inputReady:
+ try:
+ peer, address = self.socket.accept()
+ self.setMode( MD_PEER, (address[0], PORT) )
+ except socket.error, (value, message):
+ print "Network:: error accepting connection: " + message
+
+ self._fromListener = False
+
+
+ def processStream( self, sock, newData = "" ):
+ con = self.connection[sock]
+ con.recvBuf += newData
+
+ if con.waitingForData == -1: # message size in char
+ con.waitingForData = ord(con.recvBuf[0])
+ con.recvBuf = con.recvBuf[1:]
+
+ elif con.waitingForData == -2: # message size in uint
+ if len(con.recvBuf) >= 4:
+ self.unpacker.reset(con.recvBuf[0:4])
+ con.waitingForData = self.unpacker.unpack_uint()
+ con.recvBuf = con.recvBuf[4:]
+ else:
+ return # wait for more data
+
+ elif con.waitingForData:
+ if len(con.recvBuf) >= con.waitingForData:
+ data = con.recvBuf[0:con.waitingForData]
+ con.recvBuf = con.recvBuf[con.waitingForData:]
+ con.waitingForData = 0
+ for func in self.processMessage[con.message]:
+ gobject.idle_add( func, sock, con.message, data )
+ else:
+ return # wait for more data
+
+ else:
+ con.message = ord(con.recvBuf[0])
+ if MSG_SIZE[con.message] == 0:
+ con.recvBuf = con.recvBuf[1:]
+ for func in self.processMessage[con.message]:
+ gobject.idle_add( func, sock, con.message, "" )
+ else:
+ con.waitingForData = MSG_SIZE[con.message]
+ con.recvBuf = con.recvBuf[1:]
+
+ if len(con.recvBuf):
+ self.processStream( sock )
+
+ #-- HOST handlers ------------------------------------------------------
+ def processPR_LATENCY_QUERY( self, sock, message, data ):
+ self.send( HT_LATENCY_REPLY, data, sock )
+
+ #-- PEER handlers ------------------------------------------------------
+ def processHT_LATENCY_REPLY( self, sock, message, data ):
+ t = time.time()
+ latency = t - self.latencyQueryStart[data]
+ #print "got latency reply %d" % (latency*1000)
+ self.latencyQueryHandler[data]( latency )
+ self.latencyQueryHandler.pop(data)
+ self.latencyQueryStart.pop(data)
+
+
diff --git a/common/Util/NoteDB.py b/common/Util/NoteDB.py
new file mode 100644
index 0000000..e62ca32
--- /dev/null
+++ b/common/Util/NoteDB.py
@@ -0,0 +1,811 @@
+
+import common.Config as Config
+
+class PARAMETER:
+ PAGE_BEATS, \
+ PAGE_COLOR, \
+ ONSET, \
+ PITCH, \
+ AMPLITUDE, \
+ DURATION, \
+ INSTRUMENT, \
+ PAN, \
+ REVERB, \
+ ATTACK, \
+ DECAY, \
+ FILTERTYPE, \
+ FILTERCUTOFF, \
+ INSTRUMENT2 \
+ = range(14) #python-stye enum
+
+class Note:
+ def __init__( self, page, track, id, cs ):
+ self.page = page
+ self.track = track
+ self.id = id
+ self.cs = cs
+
+ self.csStack = []
+
+ def pushState( self ):
+ self.csStack.append( self.cs.clone() )
+
+ def popState( self ):
+ self.cs = self.csStack.pop()
+
+class Page:
+ def __init__( self, beats, color = 0, instruments = False, local = True ): # , tempo, insruments, color = 0 ):
+ self.beats = beats
+ self.ticks = beats*Config.TICKS_PER_BEAT
+
+ self.color = color
+
+ if not instruments:
+ self.instruments = [ Config.INSTRUMENTS["kalimba"].instrumentId for i in range(Config.NUMBER_OF_TRACKS-1) ] + [ Config.INSTRUMENTS["drum1kit"].instrumentId ]
+ else:
+ self.instruments = instruments[:]
+
+ self.local = local # page local/global?
+
+ self.nextNoteId = 0 # first note will be 1
+
+ def genId( self ):
+ self.nextNoteId += 1
+ if self.nextNoteId == 65536: # short
+ print "note id overflow!"
+ # TODO think of how to handle this!?
+ return self.nextNoteId
+
+ def setLocal( self, local ):
+ self.local = local
+
+class PageListener:
+ def notifyPageAdd( self, id, at ):
+ pass
+
+ def notifyPageDelete( self, which, safe ):
+ pass
+
+ def notifyPageDuplicate( self, new, at ):
+ pass
+
+ def notifyPageMove( self, which, low, high ):
+ pass
+
+ def notifyPageUpdate( self, which, parameter, value ):
+ pass
+
+class NoteListener:
+ def notifyNoteAdd( self, page, track, id ):
+ pass
+ def notifyNoteDelete( self, page, track, id ):
+ pass
+ def notifyNoteUpdate( self, page, track, id, parameter, value ):
+ pass
+
+class NoteDB:
+ def __init__( self ):
+ self.noteD = {} # bins containing all the notes by page, track, and id
+ # structure self.noteD[pageId][trackIndex][noteId]
+
+ self.noteS = {} # bins containing all the notes by page and track
+ # first sorted by onset then by pitch (for drum hits)
+ # structure self.noteS[pageId][trackIndex][noteIndex]
+
+ self.pages = {} # dict of Pages indexed by pageId
+
+ self.tune = [] # list of pageIds ordered by tune
+
+ #self.beatsBefore = {} # count of beats on previous pages indexed by page id
+
+ self.listeners = [] # complete list of listeners
+ self.pageListeners = [] # list of listeners who want page notifications
+ self.noteListeners = [] # list of listeners who want note notifications
+ self.parasiteList = {} # dict of parasites indexed by listener
+
+ self.parasiteD = {} # bin of parasites indexed by listener
+ self.parasiteS = {} # parasites sorted as in self.noteS,
+
+ self.nextId = 0 # base id, first page will be 1
+
+ self.clipboard = [] # stores copied cs notes
+ self.clipboardArea = [] # stores the limits and tracks for each page in the clipboard
+
+ def dumpToStream( self, ostream, localOnly = False ):
+ for pid in self.tune:
+ if not localOnly or self.pages[pid].local:
+ ostream.page_add(pid, self.pages[pid])
+ for note in self.getNotesByPage( pid ):
+ ostream.note_add( note )
+
+ #-- private --------------------------------------------
+ def _genId( self ):
+ self.nextId += 1
+ if self.nextId == 65536: # short
+ print "page id overflow!"
+ # TODO think of how to handle this!?
+ return self.nextId
+
+ #=======================================================
+ # Page Functions
+
+ def addPage( self, pid, page, after = False ):
+ pid = self._newPage( pid, page )
+ at = self._insertPage( pid, after )
+
+ #self._updateBeatsBefore( at )
+
+ for l in self.pageListeners:
+ l.notifyPageAdd( pid, at )
+
+ return pid
+
+ def deletePages( self, which, instruments = False ):
+ beats = self.pages[self.tune[0]].beats
+
+ low = 999999
+ ind = -1
+ for id in which:
+ ind = self.tune.index(id)
+ if ind < low: low = ind
+
+ for t in range(Config.NUMBER_OF_TRACKS):
+ for n in self.noteD[id][t].keys():
+ self.deleteNote( id, t, n )
+
+ #del self.beatsBefore[id]
+
+ del self.noteD[id]
+ del self.noteS[id]
+ del self.parasiteD[id]
+ del self.parasiteS[id]
+ del self.pages[id]
+
+ at = self.tune.index( id )
+ self.tune.pop(at)
+
+ if not len(self.tune):
+ self.addPage( -1, Page(beats, instruments = instruments) ) # always have at least one page
+ safe = self.tune[0]
+ #self._updateBeatsBefore(0)
+ else:
+ safe = self.tune[max(ind-1,0)]
+ #self._updateBeatsBefore(low)
+
+ for l in self.pageListeners:
+ l.notifyPageDelete( which, safe )
+
+ def duplicatePages( self, which, after = False ):
+ sorted = []
+ if after: first = self.tune.index(after)+1
+ else: first = 0
+
+ i = j = 0
+ while i < len(self.tune) and j < len(which):
+ if self.tune[i] in which:
+ sorted.append(self.tune[i])
+ j += 1
+ i += 1
+
+ new = {}
+ for cp in sorted:
+ id = self._newPage( -1, Page(self.pages[cp].beats,self.pages[cp].color,self.pages[cp].instruments) )
+ self._insertPage( id, after )
+ after = id
+ new[cp] = id
+
+ #self._updateBeatsBefore( first )
+
+ for l in self.pageListeners:
+ l.notifyPageDuplicate( new, first )
+
+ for cp in sorted:
+ for t in range(Config.NUMBER_OF_TRACKS):
+ for n in self.noteD[cp][t].keys():
+ self.duplicateNote( cp, t, n, new[cp], t, 0 )
+
+ return new
+
+ def movePages( self, which, after = False ):
+ sorted = []
+ if after: at = self.tune.index(after)+1
+ else: at = 0
+ low = high = at
+
+ i = j = 0
+ while i < len(self.tune):
+ if self.tune[i] in which:
+ sorted.append(self.tune[i])
+ self.tune.pop(i)
+ if i < low: low = i
+ if i > high: high = i
+ if i < at: at -= 1
+ j += 1
+ else:
+ i += 1
+
+ self.tune = self.tune[:at] + sorted + self.tune[at:]
+
+ #self._updateBeatsBefore( low )
+
+ for l in self.pageListeners:
+ l.notifyPageMove( sorted, low, high )
+
+ def updatePage( self, page, parameter, value ):
+ if parameter == PARAMETER.PAGE_BEATS:
+ ticks = value*Config.TICKS_PER_BEAT
+ if self.pages[page].beats > value: # crop some notes
+ dstream = []
+ ustream = []
+ for track in range(Config.NUMBER_OF_TRACKS):
+ dsub = []
+ usub = []
+ for note in self.getNotesByTrack(page, track):
+ if ticks <= note.cs.onset:
+ dsub.append( note.id )
+ elif ticks < note.cs.onset + note.cs.duration:
+ usub.append( note.id )
+ usub.append( ticks - note.cs.onset )
+ if len(dsub):
+ dstream += [ page, track, len(dsub) ] + dsub
+ if len(usub):
+ ustream += [ page, track, PARAMETER.DURATION, len(usub)//2 ] + usub
+ if len(dstream):
+ self.deleteNotes( dstream + [-1] )
+ if len(ustream):
+ self.updateNotes( ustream + [-1] )
+
+ self.pages[page].beats = value
+ self.pages[page].ticks = ticks
+ #self._updateBeatsBefore(self.tune.index(page))
+ elif parameter == PARAMETER.PAGE_COLOR:
+ self.pages[page].color = value
+
+ for l in self.pageListeners:
+ l.notifyPageUpdate( page, parameter, value )
+
+ # stream format:
+ # parameter id
+ # number of following pages (N)
+ # page id
+ # value
+ def updatePages( self, stream ):
+ i = [-1]
+ parameter = self._readstream(stream,i)
+ N = self._readstream(stream,i)
+ for j in range(N):
+ page = self._readstream(stream,i)
+ val = self._readstream(stream,i)
+ self.updatePage( page, parameter, val )
+
+ def getInstruments(self, pages):
+ dict = {}
+ for page in pages:
+ list = []
+ for track in range(Config.NUMBER_OF_TRACKS):
+ list.append(Config.INSTRUMENTSID[self.pages[page].instruments[track]].name)
+ dict[page] = list[:]
+ return dict
+
+ #-- private --------------------------------------------
+ def _newPage( self, pid, page ):
+ if pid == -1 : pid = self._genId()
+ self.pages[pid] = page
+ self.noteD[pid] = [ {} for i in range(Config.NUMBER_OF_TRACKS) ]
+ self.noteS[pid] = [ [] for i in range(Config.NUMBER_OF_TRACKS) ]
+ self.parasiteD[pid] = [ {} for i in range(Config.NUMBER_OF_TRACKS) ]
+ self.parasiteS[pid] = [ {} for i in range(Config.NUMBER_OF_TRACKS) ]
+ for i in range(Config.NUMBER_OF_TRACKS):
+ for par in self.parasiteList.keys():
+ self.parasiteD[pid][i][par] = {}
+ self.parasiteS[pid][i][par] = []
+ return pid
+
+ def _insertPage( self, pid, after ):
+ if not after: at = 0
+ else: at = self.tune.index(after)+1
+ self.tune.insert( at, pid )
+
+ return at
+
+ #def _updateBeatsBefore( self, ind ):
+ # if ind == 0: beats = 0
+ # else: beats = self.beatsBefore[self.tune[ind-1]] + self.pages[self.tune[ind-1]].beats
+ # for i in range(ind, len(self.tune)):
+ # self.beatsBefore[self.tune[ind]] = beats
+ # beats += self.pages[self.tune[ind]].beats
+
+
+
+ #=======================================================
+ # Track Functions
+
+ def setInstrument( self, pages, track, instrumentId ):
+ stream = []
+ for page in pages:
+ self.pages[page].instruments[track] = instrumentId
+ notes = self.getNotesByTrack( page, track )
+ sub = []
+ for note in notes:
+ sub.append( note.id )
+ sub.append( instrumentId )
+ if len(sub):
+ stream += [ page, track, PARAMETER.INSTRUMENT, len(sub)//2 ] + sub
+ if len(stream):
+ self.updateNotes( stream + [-1] )
+
+ def setInstrument2( self, pages, track, instrumentId ):
+ stream = []
+ for page in pages:
+ #self.pages[page].instruments[track] = instrumentId
+ notes = self.getNotesByTrack( page, track )
+ sub = []
+ for note in notes:
+ sub.append( note.id )
+ sub.append( instrumentId )
+ if len(sub):
+ stream += [ page, track, PARAMETER.INSTRUMENT2, len(sub)//2 ] + sub
+ if len(stream):
+ self.updateNotes( stream + [-1] )
+
+ #=======================================================
+ # Note Functions
+
+ def addNote( self, nid, page, track, cs, hint = False ):
+ if nid == -1: nid = self.pages[page].genId()
+ n = self.noteD[page][track][nid] = Note( page, track, nid, cs )
+
+ if not hint: at = 0
+ else: at = hint[0]
+ while at > 0:
+ onset = self.noteS[page][track][at-1].cs.onset
+ if onset <= cs.onset:
+ if onset <= cs.onset: break
+ elif self.noteS[page][track][at-1].cs.pitch <= cs.pitch: break
+ at -= 1
+ last = len(self.noteS[page][track])
+ while at < last:
+ onset = self.noteS[page][track][at].cs.onset
+ if onset >= cs.onset:
+ if onset > cs.onset: break
+ elif self.noteS[page][track][at].cs.pitch > cs.pitch: break
+ at += 1
+
+ self.noteS[page][track].insert( at, n )
+
+ for par in self.parasiteList.keys():
+ parasite = self.parasiteList[par]( self, par, n )
+ self.parasiteD[page][track][par][nid] = parasite.attach() # give parasites the option of return something other than themselves
+ self.parasiteS[page][track][par].insert( at, parasite.attach() )
+
+ if hint: hint[0] = at + 1 # assume the next note will fall after this one
+
+ for l in self.noteListeners:
+ l.notifyNoteAdd( page, track, nid )
+
+ return nid
+
+ # stream format:
+ # page id
+ # track index
+ # number of following notes (N)
+ # cs pointer
+ # ... up to N
+ # page id or -1 to exit
+ def addNotes( self, stream ):
+ new = {}
+ i = [-1]
+ p = self._readstream(stream,i)
+ while p != -1:
+ if p not in new:
+ new[p] = [ [] for x in range(Config.NUMBER_OF_TRACKS) ]
+ t = self._readstream(stream,i)
+ N = self._readstream(stream,i)
+ hint = [0]
+ for j in range(N):
+ new[p][t].append( self.addNote( -1, p, t, self._readstream(stream,i), hint ) )
+ p = self._readstream(stream,i)
+
+ return new
+
+ def deleteNote( self, page, track, id ):
+ ind = self.noteS[page][track].index( self.noteD[page][track][id] )
+
+ for par in self.parasiteList.keys():
+ self.parasiteD[page][track][par][id].destroy()
+ self.parasiteS[page][track][par].pop(ind)
+ del self.parasiteD[page][track][par][id]
+
+ self.noteS[page][track].pop(ind)
+ del self.noteD[page][track][id]
+
+ for l in self.noteListeners:
+ l.notifyNoteDelete( page, track, id )
+
+ # stream format:
+ # page id
+ # track index
+ # number of following notes (N)
+ # note id
+ # ... up to N
+ # page id or -1 to exit
+ def deleteNotes( self, stream ):
+ i = [-1]
+ p = self._readstream(stream,i)
+ while p != -1:
+ t = self._readstream(stream,i)
+ N = self._readstream(stream,i)
+ for j in range(N):
+ self.deleteNote( p, t, self._readstream(stream,i) )
+ p = self._readstream(stream,i)
+
+ def deleteNotesByTrack( self, pages, tracks ):
+ for p in pages:
+ for t in tracks:
+ notes = self.noteS[p][t][:]
+ for n in notes:
+ self.deleteNote( p, t, n.id )
+
+ def duplicateNote( self, page, track, id, toPage, toTrack, offset ):
+ cs = self.noteD[page][track][id].cs.clone()
+ cs.trackId = toTrack
+ cs.pageId = toPage
+ cs.onset += offset
+ ticks = self.pages[toPage].ticks
+ if cs.onset >= ticks: return False # off the end of the page
+ if cs.onset + cs.duration > ticks:
+ cs.duration = ticks - cs.onset
+
+ return self.addNote( -1, toPage, toTrack, cs )
+
+ # stream format:
+ # page id
+ # track index
+ # toPage id
+ # toTrack index
+ # offset
+ # number of following notes (N)
+ # note id
+ # ... up to N
+ # page id or -1 to exit
+ def duplicateNotes( self, stream ):
+ i = [-1]
+ p = self._readstream(stream,i)
+ while p != -1:
+ t = self._readstream(stream,i)
+ toP = self._readstream(stream,i)
+ toT = self._readstream(stream,i)
+ offset = self._readstream(stream,i)
+ N = self._readstream(stream,i)
+ for j in range(N):
+ self.duplicateNote( p, t, self._readstream(stream,i), toP, toT, offset )
+ p = self._readstream(stream,i)
+
+
+ def updateNote( self, page, track, id, parameter, value ):
+ if parameter == PARAMETER.ONSET:
+ self.noteD[page][track][id].cs.onset = value
+ self._resortNote( page, track, id )
+ elif parameter == PARAMETER.PITCH:
+ self.noteD[page][track][id].cs.pitch= value
+ self._resortNote( page, track, id )
+ elif parameter == PARAMETER.AMPLITUDE:
+ self.noteD[page][track][id].cs.amplitude = value
+ elif parameter == PARAMETER.DURATION:
+ self.noteD[page][track][id].cs.duration = value
+ elif parameter == PARAMETER.INSTRUMENT:
+ self.noteD[page][track][id].cs.instrumentId = value
+ elif parameter == PARAMETER.PAN:
+ self.noteD[page][track][id].cs.pan = value
+ elif parameter == PARAMETER.REVERB:
+ self.noteD[page][track][id].cs.reverbSend = value
+ elif parameter == PARAMETER.ATTACK:
+ self.noteD[page][track][id].cs.attack = value
+ elif parameter == PARAMETER.DECAY:
+ self.noteD[page][track][id].cs.decay = value
+ elif parameter == PARAMETER.FILTERTYPE:
+ self.noteD[page][track][id].cs.filterType = value
+ elif parameter == PARAMETER.FILTERCUTOFF:
+ self.noteD[page][track][id].cs.filterCutoff = value
+ elif parameter == PARAMETER.INSTRUMENT2:
+ self.noteD[page][track][id].cs.instrumentId2 = value
+
+ for par in self.parasiteList.keys():
+ self.parasiteD[page][track][par][id].updateParameter( parameter, value )
+
+ for l in self.noteListeners:
+ l.notifyNoteUpdate( page, track, id, parameter, value )
+
+ # stream format:
+ # page id
+ # track index
+ # parameter id
+ # number of following notes (N)
+ # note id
+ # value
+ # ... up to N
+ # page id or -1 to exit
+ def updateNotes( self, stream ):
+ i = [-1]
+ p = self._readstream(stream,i)
+ while p != -1:
+ t = self._readstream(stream,i)
+ param = self._readstream(stream,i)
+ N = self._readstream(stream,i)
+ for j in range(N):
+ self.updateNote( p, t, self._readstream(stream,i), param, self._readstream(stream,i) )
+ p = self._readstream(stream,i)
+
+ #-- private --------------------------------------------
+ def _readstream( self, stream, i ):
+ i[0] += 1
+ return stream[i[0]]
+
+ def _resortNote( self, page, track, id ):
+ ins = out = self.noteS[page][track].index(self.noteD[page][track][id])
+ cs = self.noteD[page][track][id].cs
+ while ins > 0: # check backward
+ onset = self.noteS[page][track][ins-1].cs.onset
+ if onset <= cs.onset:
+ if onset <= cs.onset: break
+ elif self.noteS[page][track][ins-1].cs.pitch <= cs.pitch: break
+ ins -= 1
+ if ins == out: # check forward
+ ins += 1
+ last = len(self.noteS[page][track])
+ while ins < last:
+ onset = self.noteS[page][track][ins].cs.onset
+ if onset >= cs.onset:
+ if onset > cs.onset: break
+ elif self.noteS[page][track][ins].cs.pitch > cs.pitch: break
+ ins += 1
+
+ if ins != out: # resort
+ if ins > out: ins -= 1
+ n = self.noteS[page][track].pop( out )
+ self.noteS[page][track].insert( ins, n )
+ for par in self.parasiteList.keys():
+ p = self.parasiteS[page][track][par].pop( out )
+ self.parasiteS[page][track][par].insert( ins, p )
+
+
+ #=======================================================
+ # Clipboard Functions
+
+ # stream format:
+ # page id
+ # track index
+ # number of following notes (N)
+ # note id
+ # ... up to N
+ # page id or -1 to exit
+ def notesToClipboard( self, stream ):
+ self.clipboard = []
+ self.clipboardArea = []
+ i = [-1]
+ pages = []
+ p = self._readstream(stream,i)
+ while p != -1:
+ if p not in pages:
+ page = [ [] for x in range(Config.NUMBER_OF_TRACKS) ]
+ pageArea = { "limit": [ 99999, 0 ],
+ "tracks": [ 0 for x in range(Config.NUMBER_OF_TRACKS) ] }
+ pages.append(p)
+ self.clipboard.append(page)
+ self.clipboardArea.append(pageArea)
+ else:
+ ind = pages.index(p)
+ page = self.clipboard[ind]
+ pageArea = self.clipboardArea[ind]
+ t = self._readstream(stream,i)
+ pageArea["tracks"][t] = 1
+ N = self._readstream(stream,i)
+ for j in range(N):
+ cs = self.noteD[p][t][self._readstream(stream,i)].cs.clone()
+ if cs.onset < pageArea["limit"][0]: pageArea["limit"][0] = cs.onset
+ if cs.onset + cs.duration > pageArea["limit"][1]: pageArea["limit"][1] = cs.onset + cs.duration
+ page[t].append( cs )
+ p = self._readstream(stream,i)
+
+ return self.clipboardArea
+
+ def tracksToClipboard( self, pages, tracks ):
+ self.clipboard = []
+ self.clipboardOrigin = [ 0, 0 ]
+ self.clipboardArea = []
+ for p in pages:
+ page = [ [] for x in range(Config.NUMBER_OF_TRACKS) ]
+ pageArea = { "limit": [ 0, 99999 ],
+ "tracks": [ 0 for x in range(Config.NUMBER_OF_TRACKS) ] }
+ self.clipboard.append(page)
+ self.clipboardArea.append(pageArea)
+ for t in tracks:
+ pageArea["tracks"][t] = 1
+ for id in self.noteD[p][t]:
+ cs = self.noteD[p][t][id].cs.clone()
+ page[t].append( cs )
+
+ return self.clipboardArea
+
+ # trackMap = { X: Y, W: Z, ... }; X,W are track indices, Y,Z are clipboard indices
+ # instrumentMap = { X: Y, W: Z, ... }; X,W are track indices, Y,Z are instrument ids
+ def pasteClipboard( self, pages, offset, trackMap, instrumentMap = {} ):
+ if not len(self.clipboard): return
+
+ deleteStream = []
+ updateStream = []
+ addStream = []
+
+ pp = 0
+ ppMax = len(self.clipboard)
+ for p in pages:
+ ticks = self.pages[p].ticks
+ area = self.clipboardArea[pp]
+ area["limit"][0] += offset
+ area["limit"][1] += offset
+ for t in trackMap.keys():
+ if not area["tracks"][trackMap[t]]: continue
+ if instrumentMap.has_key(t):
+ updateInstrument = True
+ instrumentId = instrumentMap[t]
+ else:
+ updateInstrument = False
+ tdeleteStream = []
+ tupdateOStream = []
+ tupdateDStream = []
+ taddStream = []
+ # clear area
+ for n in self.noteS[p][t]:
+ start = n.cs.onset
+ end = start + n.cs.duration
+ if area["limit"][0] <= start < area["limit"][1]: start = area["limit"][1]
+ if area["limit"][0] < end <= area["limit"][1]: end = area["limit"][0]
+ if start < area["limit"][0] and end > area["limit"][1]: end = area["limit"][0]
+ if end <= start:
+ tdeleteStream.append( n.id )
+ elif start != n.cs.onset:
+ tupdateDStream += [ n.id, end - start ]
+ tupdateOStream += [ n.id, start ]
+ elif end != start + n.cs.duration:
+ tupdateDStream += [ n.id, end - start ]
+ if len(tdeleteStream):
+ deleteStream += [ p, t, len(tdeleteStream) ] + tdeleteStream
+ if len(tupdateOStream):
+ updateStream += [ p, t, PARAMETER.ONSET, len(tupdateOStream)//2 ] + tupdateOStream
+ if len(tupdateDStream):
+ updateStream += [ p, t, PARAMETER.DURATION, len(tupdateDStream)//2 ] + tupdateDStream
+ # paste notes
+ for cs in self.clipboard[pp][trackMap[t]]:
+ newcs = cs.clone()
+ newcs.onset += offset
+ if newcs.onset >= ticks: continue
+ if newcs.onset + newcs.duration > ticks:
+ newcs.duration = ticks - newcs.onset
+ newcs.pageId = p
+ newcs.trackId = t
+ if updateInstrument:
+ newcs.instrumentId = instrumentId
+ # TODO update any other parameters?
+ taddStream.append( newcs )
+ if len(taddStream):
+ addStream += [ p, t, len(taddStream) ] + taddStream
+
+ pp += 1
+ if pp == ppMax: pp -= ppMax
+
+
+
+ if len(deleteStream):
+ self.deleteNotes( deleteStream + [-1] )
+ if len(updateStream):
+ self.updateNotes( updateStream + [-1] )
+ if len(addStream):
+ return self.addNotes( addStream + [-1] )
+
+ return None
+
+ def getClipboardArea( self, ind ):
+ N = len(self.clipboardArea)
+ while ind >= N: ind -= N
+ return self.clipboardArea[ind]
+
+ #=======================================================
+ # Listener Functions
+
+ def addListener( self, listener, parasite = None, page = False, note = False ):
+ if listener in self.listeners:
+ return # only one listener per object
+
+ if parasite:
+ self.parasiteList[listener] = parasite
+ self._addParasite( listener, parasite )
+
+ if page: self.pageListeners.append( listener )
+ if note: self.noteListeners.append( listener )
+ self.listeners.append( listener )
+
+ def deleteListener( self, listener ):
+ self.listeners.remove( listener )
+ if listener in self.pageListeners:
+ self.pageListeners.remove( listener )
+ if listener in self.noteListeners:
+ self.noteListeners.remove( listener )
+ if self.parasites.has_key( listener ):
+ self._deleteParasite( listener )
+ del self.parasiteList[listener]
+
+ #-- private --------------------------------------------
+ def _addParasite( self, listener, parasite ):
+ for p in self.tune:
+ for t in range(Config.NUMBER_OF_TRACKS):
+ self.parasiteD[p][t][listener] = {}
+ self.parasiteS[p][t][listener] = []
+ for n in self.noteD[p][t].keys():
+ parasite( self, listener, self.noteD[p][t][n] )
+ self.parasiteD[p][t][listener][n] = parasite.attach() # give parasites the option of returning something other than themselves
+ self.parasiteS[p][t][listener].insert( self.noteS[p][t].index( self.noteD[p][t][n]), parasite.attach() )
+
+ def _deleteParasite( self, listener ):
+ for p in self.tune:
+ for t in range(Config.NUMBER_OF_TRACKS):
+ for n in self.notes[p][t].keys():
+ self.parasiteD[p][t][listener][n].destroy()
+ del self.parasiteD[p][t][listener]
+ del self.parasiteS[p][t][listener]
+
+ #=======================================================
+ # Get Functions
+
+ def getPageCount( self ):
+ return len(self.pages)
+
+ def getTune( self ):
+ return self.tune
+
+ def getPage( self, page ):
+ return self.pages[page]
+
+ def getPageByIndex( self, ind ):
+ return self.tune[ind]
+
+ def getPageIndex( self, page ):
+ return self.tune.index(page)
+
+ # Not sure if this is useful!
+ #def getBeatsBeforePage( self, page ):
+ # return self.beatsBefore[page]
+
+ def getNote( self, page, track, id, listener = None ):
+ if listener:
+ return self.parasiteD[page][track][listener][id]
+ return self.noteD[page][track][id]
+
+ def getNotesByPage( self, page, listener = None ):
+ notes = []
+ if listener:
+ for i in range(Config.NUMBER_OF_TRACKS):
+ notes.extend( self.parasiteS[page][i][listener] )
+ else:
+ for i in range(Config.NUMBER_OF_TRACKS):
+ notes.extend( self.noteS[page][i] )
+ return notes
+
+
+ def getNotesByTrack( self, page, track, listener = None ):
+ if listener:
+ return self.parasiteS[page][track][listener]
+ else:
+ return self.noteS[page][track]
+
+ def getNotes(self, listener = None ):
+ notes = []
+ for p in self.pages:
+ notes.extend( self.getNotesByPage(p, listener ) )
+ return notes
+
+
+ def getCSNotesByPage( self, page ):
+ return map( lambda n: n.cs, self.getNotesByPage( page ) )
+
+ def getCSNotesByTrack( self, page, track ):
+ return map( lambda n: n.cs, self.getNotesByTrack( page, track ) )
diff --git a/common/Util/NoteLooper.py b/common/Util/NoteLooper.py
new file mode 100644
index 0000000..be6f0b6
--- /dev/null
+++ b/common/Util/NoteLooper.py
@@ -0,0 +1,199 @@
+import pickle
+import time
+import bisect
+
+import pygtk
+pygtk.require( '2.0' )
+import gtk
+import gobject
+
+import common.Config as Config
+from common.Util.CSoundNote import CSoundNote #maybe not actually used, but dependence is there. All notes are assumed to be CSoundNotes
+from common.Generation.GenerationConstants import GenerationConstants
+
+#------------------------------------------------------------------------------
+# A base class used to play a collection of Events at their respective onsets
+#------------------------------------------------------------------------------
+class NoteLooper_DONTUSE:
+
+ #PRIVATE
+ DRIFT = 0.01 #careful about changing this... coordinate with instrument 5777
+
+ #PUBLIC
+
+ def __init__( self, range_sec, ticks_per_sec ):
+ self.ticks_per_sec = ticks_per_sec # ticks last this long
+ self.secs_per_tick = 1.0 / ticks_per_sec # precomputed inverse
+ self.range_sec = range_sec # notes are checked-for, this many seconds in advance
+
+ self.duration = 0 # number of ticks in playback loop
+ self.loops = 0 # number of elapsed loops
+ self.notes = [] # sorted list of (onset, noteptr, cache)
+
+ self.time0 = time.time() + 1000000 # the real time at which tick == 0 (sometimes retro-active)
+
+ #self.time_start # remember to call NoteLooper.startTime
+ # at the same time as you call
+ # CSoundClient.startTime()
+ def setTick( self, tick ):
+ time_time = time.time()
+ self.time0 = time_time - tick * self.secs_per_tick
+ self.loops = tick // self.duration
+ self.hIdx = bisect.bisect_left(self.notes, tick - self.duration * self.loops )
+
+ def setRate( self, ticks_per_sec):
+ if ticks_per_sec != self.ticks_per_sec:
+ secs_per_tick = 1.0 / ticks_per_sec
+
+ time_time = time.time()
+ curtick = self.getTick( time_time, False )
+ curticktime = curtick * self.secs_per_tick + self.time0
+
+ self.ticks_per_sec = ticks_per_sec
+ self.secs_per_tick = secs_per_tick
+ self.time0 = curticktime - curtick * secs_per_tick
+ self.notes = [ (o,n,'',z) for (o,n,c,z) in self.notes ] #clear cache
+ self.loops = 0
+
+ def setDuration( self, duration ):
+ self.time0 += self.loops * self.duration * self.secs_per_tick
+ self.loops = 0
+ self.duration = duration
+
+ def getTick(self, t, domod): #t is for time
+ if domod :
+ return ( int( ( t - self.time0 ) * self.ticks_per_sec ) ) % self.duration
+ else :
+ return ( int( ( t - self.time0 ) * self.ticks_per_sec ) )
+
+ def next( self ) :
+ time_time = time.time()
+ #tickhorizon is tick where we'll be after range_sec
+ tickhorizon = self.getTick( self.range_sec + time_time, False )
+ time0_time = self.time0 - self.time_start + self.DRIFT
+
+ if tickhorizon < 0 : return []
+ if len(self.notes) == 0 : return []
+
+ def cache_cmd(secs_per_tick, amplitude, pitch, inst, trackId, duration, tied, fullDuration, overlap, attack, decay, reverbSend, filterType, filterCutoff, pan ):
+ if inst[0:4] == 'drum':
+ if pitch in GenerationConstants.DRUMPITCH:
+ key = GenerationConstants.DRUMPITCH[ pitch ]
+ else:
+ key = pitch
+
+ if inst == 'drum1kit':
+ inst = Config.DRUM1INSTRUMENTS[ key ]
+ if inst == 'drum2kit':
+ inst = Config.DRUM2INSTRUMENTS[ key ]
+ if inst == 'drum3kit':
+ inst = Config.DRUM3INSTRUMENTS[ key ]
+ pitch = 1
+
+ else:
+ pitch = GenerationConstants.TRANSPOSE[ pitch - 24 ]
+
+ # condition for tied notes
+ if Config.INSTRUMENTS[ inst ].csoundInstrumentId == 101 and tied and fullDuration:
+ duration= -1.0
+ # condition for overlaped notes
+ if Config.INSTRUMENTS[ inst ].csoundInstrumentId == 102 and overlap:
+ duration += 1.0
+
+ attack = max( 0.002, duration * attack)
+ decay = max( 0.002, duration * decay)
+
+ rval = Config.PLAY_NOTE_COMMAND_MINUS_DELAY % \
+ ( Config.INSTRUMENTS[ inst ].csoundInstrumentId,
+ trackId,
+ '%f', #delay,
+ duration,
+ pitch,
+ reverbSend,
+ amplitude,
+ pan,
+ Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[ inst ].instrumentId,
+ attack,
+ decay,
+ filterType, filterCutoff )
+ return rval
+
+ def getText(i, secs_per_tick, time_offset):
+ (onset,note,cache,z) = self.notes[i]
+ if cache == '' or note.nchanges != z :
+ self.notes[i] = \
+ (
+ onset,
+ note,
+ cache_cmd(
+ secs_per_tick,
+ note.amplitude, # * track-level mixer rate
+ note.pitch,
+ note.instrumentFlag,
+ note.trackId,
+ note.duration * self.secs_per_tick,
+ note.tied,
+ note.fullDuration,
+ note.overlap,
+ note.attack,
+ note.decay,
+ note.reverbSend,
+ note.filterType,
+ note.filterCutoff,
+ note.pan),
+ note.nchanges
+ )
+ rval = self.notes[i][2] % float(onset * self.secs_per_tick + time_offset)
+ return rval
+
+ prev_secs = (self.loops * self.duration) * self.secs_per_tick
+ rval = []
+ while self.notes[self.hIdx][0] + self.loops * self.duration < tickhorizon:
+ rval.append ( getText(self.hIdx, self.secs_per_tick, prev_secs + time0_time ) )
+ self.hIdx += 1
+ if self.hIdx == len(self.notes):
+ self.hIdx = 0
+ self.loops += 1
+ prev_secs += self.duration * self.secs_per_tick
+
+ return rval
+
+ def insert( self, notes):
+ def insertMany():
+ self.notes += [ ( notes[i][0], notes[i][1], '', 0 ) for i in xrange(len(notes)) ]
+ self.notes.sort()
+ def insertFew():
+ for i in xrange(len(notes)):
+ t = (notes[i][0], notes[i][1],'',0)
+ l = bisect.bisect_left(self.notes, t )
+ self.notes.insert(l, t)
+
+ if len(notes) >= 1:
+ insertMany()
+ else:
+ insertFew()
+ self.hIdx = bisect.bisect_left(self.notes, self.getTick(self.range_sec + time.time(), True))
+
+ def remove(self, note):
+ def removeFew():
+ i = 0
+ while i < len(self.notes):
+ if self.notes[i][1] in note:
+ del self.notes[i]
+ else:
+ i += 1
+
+ def removeMany():
+ self.notes = [t for t in self.notes if t[1] not in note]
+
+ if len(idset) >= 0: #just guessing here, should do some timing tests to see if this is good or no
+ removeMany()
+ else:
+ removeFew()
+ self.hIdx = bisect.bisect_left(self.notes, self.getTick(self.range_sec + time.time(), True))
+
+ def clear(self):
+ self.notes = []
+
+ def startTime(self):
+ self.time_start = time.time()
diff --git a/common/Util/Profiler.py b/common/Util/Profiler.py
new file mode 100644
index 0000000..0019a6c
--- /dev/null
+++ b/common/Util/Profiler.py
@@ -0,0 +1,93 @@
+
+import time
+
+class TaskProfiler( object ):
+ def __init__( self ):
+ self.profiles = {}
+
+ def ProfileBegin( self, profile ):
+ if self.profiles.has_key(profile) == False: self.profiles[profile] = TaskProfile(profile)
+ self.profiles[profile].begin()
+
+ def ProfilePause( self, profile ):
+ if self.profiles.has_key(profile) == False: return False
+ self.profiles[profile].pause()
+
+ def ProfileEnd( self, profile ):
+ if self.profiles.has_key(profile) == False: return False
+ self.profiles[profile].end()
+
+ def Profile(self, profile):
+ if profile in self.profiles:
+ if self.profiles[profile].inProgress:
+ self.profiles[profile].end()
+ else:
+ self.profiles[profile].begin()
+ else:
+ self.profiles[profile] = TaskProfile(profile)
+ self.profiles[profile].begin()
+
+ def ProfilePrint( self, profile ):
+ if self.profiles.has_key(profile) == False: return "Couldn't find profile: " + profile
+ return self.profiles[profile].printoverall()
+
+ def ProfileEndAndPrint( self, profile ):
+ if self.profiles.has_key(profile) == False: return "Couldn't find profile: " + profile
+ self.profiles[profile].end()
+ return self.profiles[profile].printlast()
+
+
+ def PrintAll( self ):
+ str = ""
+ keys = self.profiles.keys()
+ keys.sort()
+ return "\n".join( [self.profiles[k].printoverall() for k in keys] )
+ #for p in self.profiles:
+ #str += "\n" + self.profiles[p].printoverall()
+ #return str
+
+
+class TaskProfile( object ):
+ def __init__( self, name ):
+ self.name = name
+ self.count = 0
+ self.min = 666666666.0 # really high
+ self.max = -1.0 # pretty low
+ self.avg = 0.0
+ self.dt = 0
+ self.inProgress = False
+ self.paused = False
+
+ def begin( self ):
+ if self.inProgress: return False # you fucked up your ProfileBegin and ProfileEnd pairs
+ self.inProgress = True
+ if self.paused:
+ self.paused = False
+ self.startTime += time.time() - self.pauseTime
+ else:
+ self.startTime = time.time()
+
+ def pause( self ):
+ self.pauseTime = time.time()
+ self.inProgress = False
+ self.paused = True
+
+ def end( self ):
+ self.dt = time.time() - self.startTime
+ if self.paused:
+ self.dt = self.pauseTime - self.startTime
+ if self.dt > self.max: self.max = self.dt
+ if self.dt < self.min: self.min = self.dt
+ self.avg = (self.dt + self.avg*self.count)/(self.count+1)
+ self.count += 1
+ self.inProgress = False
+ self.paused = False
+
+ def printlast( self ):
+ return "Profile: " + self.name + " last dt: %f" % (self.dt)
+
+ def printoverall( self ):
+ if self.count == 0: return "Profile: " + self.name + ", no data!"
+ return "Profile: " + self.name + " avg: %f max: %f min: %f count: %d" % (self.avg, self.max, self.min, self.count)
+
+TP = TaskProfiler()
diff --git a/common/Util/Sound.py b/common/Util/Sound.py
new file mode 100644
index 0000000..37edf8f
--- /dev/null
+++ b/common/Util/Sound.py
@@ -0,0 +1,289 @@
+import bisect
+import csnd
+import os
+import socket
+import select
+import sys
+import thread
+import time
+
+from sugar import env
+import common.Config as Config
+
+from common.Util.CSoundNote import CSoundNote #maybe not actually used, but dependence is there. All notes are assumed to be CSoundNotes
+from common.Generation.GenerationConstants import GenerationConstants
+
+class Sound:
+ #TODO: remove
+ def inputMessage(self, txt):
+ self.perf.InputMessage(txt)
+
+ #PRIVATE
+ DRIFT = 0.01 #careful about changing this... coordinate with instrument 5777
+ def loop_work(self, sleeptime):
+ def next( ) :
+ time_time = time.time()
+ #tickhorizon is tick where we'll be after range_sec
+ tickhorizon = self.getTick( self.range_sec + time_time, False )
+ time0_time = self.time0 - self.time_start + self.DRIFT
+
+ if tickhorizon < 0 : return []
+ if len(self.notes) == 0 : return []
+
+ def cache_cmd(secs_per_tick, amplitude, pitch, inst, trackId, duration, tied, fullDuration, overlap, attack, decay, reverbSend, filterType, filterCutoff, pan ):
+ if inst[0:4] == 'drum':
+ if pitch in GenerationConstants.DRUMPITCH:
+ key = GenerationConstants.DRUMPITCH[ pitch ]
+ else:
+ key = pitch
+
+ if inst == 'drum1kit':
+ inst = Config.DRUM1INSTRUMENTS[ key ]
+ if inst == 'drum2kit':
+ inst = Config.DRUM2INSTRUMENTS[ key ]
+ if inst == 'drum3kit':
+ inst = Config.DRUM3INSTRUMENTS[ key ]
+ pitch = 1
+
+ else:
+ pitch = GenerationConstants.TRANSPOSE[ pitch - 24 ]
+
+ # condition for tied notes
+ if Config.INSTRUMENTS[ inst ].csoundInstrumentId == 101 and tied and fullDuration:
+ duration= -1.0
+ # condition for overlaped notes
+ if Config.INSTRUMENTS[ inst ].csoundInstrumentId == 102 and overlap:
+ duration += 1.0
+
+ attack = max( 0.002, duration * attack)
+ decay = max( 0.002, duration * decay)
+
+ rval = Config.PLAY_NOTE_COMMAND_MINUS_DELAY % \
+ ( Config.INSTRUMENTS[ inst ].csoundInstrumentId,
+ trackId,
+ '%f', #delay,
+ duration,
+ pitch,
+ reverbSend,
+ amplitude,
+ pan,
+ Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[ inst ].instrumentId,
+ attack,
+ decay,
+ filterType, filterCutoff )
+ return rval
+
+ def getText(i, secs_per_tick, time_offset):
+ (onset,note,cache,z) = self.notes[i]
+ if cache == '' or note.nchanges != z :
+ self.notes[i] = \
+ (
+ onset,
+ note,
+ cache_cmd(
+ secs_per_tick,
+ note.amplitude, # * track-level mixer rate
+ note.pitch,
+ note.instrumentFlag,
+ note.trackId,
+ note.duration * self.secs_per_tick,
+ note.tied,
+ note.fullDuration,
+ note.overlap,
+ note.attack,
+ note.decay,
+ note.reverbSend,
+ note.filterType,
+ note.filterCutoff,
+ note.pan),
+ note.nchanges
+ )
+ rval = self.notes[i][2] % float(onset * self.secs_per_tick + time_offset)
+ return rval
+
+ prev_secs = (self.loops * self.duration) * self.secs_per_tick
+ rval = []
+ while self.notes[self.hIdx][0] + self.loops * self.duration < tickhorizon:
+ rval.append ( getText(self.hIdx, self.secs_per_tick, prev_secs + time0_time ) )
+ self.hIdx += 1
+ if self.hIdx == len(self.notes):
+ self.hIdx = 0
+ self.loops += 1
+ prev_secs += self.duration * self.secs_per_tick
+
+ return rval
+
+ #thread.start_new_thread( testtimer, (0,) )
+ m = 0.0
+ while self.thread_continue:
+ t0 = time.time()
+ time.sleep(sleeptime)
+ t1 = time.time()
+ if t1 - t0 > 2.0 * sleeptime :
+ print 'critical lagginess: ', t1 - t0
+ if m < t1 - t0:
+ m = t1 - t0
+ print t1, ' timer max = ', m
+ if self.playing :
+ cmds = self.next()
+ for c in cmds:
+ self.perf.InputMessage( c )
+
+ # create the object, and launch the loop thread
+ def __init__(self, orc, range_sec, ticks_per_sec ):
+ self.orc = orc
+ self.up = False
+ self.ticks_per_sec = ticks_per_sec # ticks last this long
+ self.secs_per_tick = 1.0 / ticks_per_sec # precomputed inverse
+ self.range_sec = range_sec # notes are checked-for, this many seconds in advance
+ self.duration = 1 # number of ticks in playback loop
+ self.loops = 0 # number of elapsed loops
+ self.notes = [] # sorted list of (onset, noteptr, cache)
+ self.time0 = time.time() + 1000000 # the real time at which tick == 0 (sometimes retro-active)
+ self.thread_continue = 1
+ self.playing = False
+ #self.thread = thread.start_new_thread( self.loop_work, (0.040,) )
+ self.csound = csnd.Csound()
+
+ # join the loop thread, clean up everything.
+ def uninit(self):
+ #self.thread_continue = 0
+ #self.thread.join()
+ #if self.up :
+ # self.lower()
+ self.csound.Reset()
+ pass
+
+ # (re)start playback and seize the sound device
+ def connect(self):
+ def startTime():
+ if not self.up :
+ debug_print (1, "ERROR: Sound::startTime, performance thread isn't up yet.")
+ return
+ self.perf.InputMessage('i 5999 0.0 60000000')
+ self.time_start = time.time()
+ # if a note event is sent to csound before or simultaneous to this one, then it will not play correctly.
+ # thus we sleep right here, to (ideally) let csound pick up the message.
+ # NB: match this to the constant in the instrument 5777 of the csound orcestra
+ time.sleep(0.1)
+ def load_instruments( ):
+ home_path = env.get_profile_path() + Config.PREF_DIR
+ for instrumentSoundFile in Config.INSTRUMENTS.keys():
+ if instrumentSoundFile[0:3] == 'mic' or instrumentSoundFile[0:3] == 'lab':
+ fileName = home_path + '/' + instrumentSoundFile
+ else:
+ fileName = Config.SOUNDS_DIR + "/" + instrumentSoundFile
+ instrumentId = Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[ instrumentSoundFile ].instrumentId
+ self.load_instruments(instrumentId, fileName)
+ if self.up :
+ debug_print(3, 'Sound::raise() already up.')
+ return
+ self.up = True
+ self.perf = csnd.CsoundPerformanceThread(self.csound)
+ self.csound.Compile( self.orc )
+ self.perf.Play()
+ load_instruments()
+ start_time()
+ debug_print(5, 'Sound::raise succeeded')
+
+ # stop playback and free the sound device
+ def disconnect(self):
+ def unload_instruments():
+ self.perf.InputMessage('i%d 0 0.1 %d' % (Config.INST_FREE, len(Config.INSTRUMENTS)))
+
+ if not self.up :
+ debug_print(3, 'Sound::lower() already down.')
+ return
+ self.up = False
+ unload_instruments()
+ self.perf.Stop()
+ rval = self.perf.Join()
+ self.csound.Reset()
+ debug_print(5, 'Sound::lower() succeeded')
+
+ def micRecording( self, table ):
+ self.perf.InputMessage('i5201 0 5 %d' % table)
+ def load_instrument(self, id, fname):
+ self.perf.InputMessage('f%d 0 0 -1 \"%s\" 0 0 0' % (id, fname ))
+ def load_mic_instrument( self, inst ):
+ home_path = env.get_profile_path() + Config.PREF_DIR
+ fileName = home_path + '/' + inst
+ instrumentId = Config.INSTRUMENT_TABLE_OFFSET + int(fileName[-1]) + 6
+ self.load_instrument(instrumentId, fileName)
+
+ def setMasterVolume(self, volume):
+ self.csound.SetChannel('masterVolume',volume )
+
+ def loop_start(self):
+ self.playing = True
+
+ def loop_stop(self):
+ self.playing = False
+
+ def loop_getTick(self, t, domod): #t is for time
+ if domod :
+ return ( int( ( t - self.time0 ) * self.ticks_per_sec ) ) % self.duration
+ else :
+ return ( int( ( t - self.time0 ) * self.ticks_per_sec ) )
+
+ def loop_setTick( self, tick ):
+ time_time = time.time()
+ self.time0 = time_time - tick * self.secs_per_tick
+ self.loops = tick // self.duration
+ self.hIdx = bisect.bisect_left(self.notes, tick - self.duration * self.loops )
+
+ def loop_setRate( self, ticks_per_sec):
+ if ticks_per_sec != self.ticks_per_sec:
+ secs_per_tick = 1.0 / ticks_per_sec
+
+ time_time = time.time()
+ curtick = self.getTick( time_time, False )
+ curticktime = curtick * self.secs_per_tick + self.time0
+
+ self.ticks_per_sec = ticks_per_sec
+ self.secs_per_tick = secs_per_tick
+ self.time0 = curticktime - curtick * secs_per_tick
+ self.notes = [ (o,n,'',z) for (o,n,c,z) in self.notes ] #clear cache
+ self.loops = 0
+
+ def loop_setDuration( self, duration ):
+ self.time0 += self.loops * self.duration * self.secs_per_tick
+ self.loops = 0
+ self.duration = duration
+
+ def loop_insert( self, notes):
+ def insertMany():
+ self.notes += [ ( notes[i][0], notes[i][1], '', 0 ) for i in xrange(len(notes)) ]
+ self.notes.sort()
+ def insertFew():
+ for i in xrange(len(notes)):
+ t = (notes[i][0], notes[i][1],'',0)
+ l = bisect.bisect_left(self.notes, t )
+ self.notes.insert(l, t)
+
+ if len(notes) >= 1:
+ insertMany()
+ else:
+ insertFew()
+ self.hIdx = bisect.bisect_left(self.notes, self.getTick(self.range_sec + time.time(), True))
+
+ def loop_remove(self, note):
+ def removeFew():
+ i = 0
+ while i < len(self.notes):
+ if self.notes[i][1] in note:
+ del self.notes[i]
+ else:
+ i += 1
+
+ def removeMany():
+ self.notes = [t for t in self.notes if t[1] not in note]
+
+ if len(idset) >= 0: #just guessing here, should do some timing tests to see if this is good or no
+ removeMany()
+ else:
+ removeFew()
+ self.hIdx = bisect.bisect_left(self.notes, self.getTick(self.range_sec + time.time(), True))
+
+ def loop_clear(self):
+ self.notes = []
diff --git a/common/Util/ThemeWidgets.py b/common/Util/ThemeWidgets.py
new file mode 100644
index 0000000..0acc498
--- /dev/null
+++ b/common/Util/ThemeWidgets.py
@@ -0,0 +1,1276 @@
+import pygtk
+pygtk.require( '2.0' )
+import gtk
+
+from sugar.graphics.combobox import ComboBox
+from sugar.graphics.palette import Palette, WidgetInvoker
+
+
+class ITYPE:
+ PIXBUF = 0
+ PIXMAP = 1
+
+class ImageHScale( gtk.HScale ):
+ def __init__( self, image_name, adjustment = None, slider_border = 0, insensitive_name = None, trough_color = "#3D403A", snap = False ):
+ gtk.HScale.__init__( self, adjustment )
+
+ if snap: self.snap = 1/snap
+ else: self.snap = False
+
+ colormap = self.get_colormap()
+ self.troughcolor = colormap.alloc_color( trough_color, True, True )
+
+ img = gtk.Image()
+ img.set_from_file( image_name )
+ self.sliderPixbuf = img.get_pixbuf()
+
+ if insensitive_name == None:
+ self.insensitivePixbuf = None
+ else:
+ img = gtk.Image()
+ img.set_from_file( insensitive_name )
+ self.insensitivePixbuf = img.get_pixbuf()
+
+ name = image_name + "ImageHScale"
+ self.set_name(name)
+
+ rc_str = """
+style "scale_style" {
+ GtkRange::slider_width = %d
+ GtkScale::slider_length = %d
+}
+widget "*%s*" style "scale_style"
+ """ % ( self.sliderPixbuf.get_width(), self.sliderPixbuf.get_height(), name)
+ gtk.rc_parse_string( rc_str )
+
+ self.pixbufWidth = self.sliderPixbuf.get_width()
+ self.pixbufHeight = self.sliderPixbuf.get_height()
+ self.sliderBorder = slider_border
+ self.sliderBorderMUL2 = self.sliderBorder*2
+
+ self.set_draw_value(False)
+
+ self.connect( "expose-event", self.expose )
+ self.connect( "size-allocate", self.size_allocate )
+ self.connect( "button-release-event", self.button_release )
+ adjustment.connect( "changed", self.value_changed )
+ adjustment.connect( "value-changed", self.value_changed )
+
+ def size_allocate( self, widget, allocation ):
+ self.alloc = allocation
+ self.sliderY = self.alloc.height//2 - self.pixbufHeight//2
+ return False
+
+ def set_snap( self, snap ):
+ if snap: self.snap = 1/snap
+ else: self.snap = False
+ self.queue_draw()
+
+ def value_changed( self, adjustment ):
+ if self.snap:
+ val = round(self.snap*self.get_value())/self.snap
+ if val != self.get_value():
+ self.set_value( val )
+ return True
+
+ def expose( self, widget, event ):
+
+ style = self.get_style()
+ gc = style.fg_gc[gtk.STATE_NORMAL]
+
+ gc.foreground = self.troughcolor
+
+ self.window.draw_rectangle( gc, True, self.alloc.x + self.sliderBorder, self.alloc.y + self.alloc.height//2 - 1, self.alloc.width - self.sliderBorderMUL2, 3 )
+
+ val = self.get_value()
+ if self.snap:
+ val = round(self.snap*val)/self.snap
+ adj = self.get_adjustment()
+ if self.get_inverted():
+ sliderX = int((self.alloc.width - self.pixbufWidth)*(adj.upper-val)/(adj.upper - adj.lower))
+ else:
+ sliderX = int((self.alloc.width - self.pixbufWidth)*(val-adj.lower)/(adj.upper - adj.lower))
+
+ if self.insensitivePixbuf != None and self.state == gtk.STATE_INSENSITIVE:
+ self.window.draw_pixbuf( gc, self.insensitivePixbuf, 0, 0, self.alloc.x + sliderX, self.alloc.y + self.sliderY, self.pixbufWidth, self.pixbufHeight, gtk.gdk.RGB_DITHER_NORMAL, 0, 0 )
+ else:
+ self.window.draw_pixbuf( gc, self.sliderPixbuf, 0, 0, self.alloc.x + sliderX, self.alloc.y + self.sliderY, self.pixbufWidth, self.pixbufHeight, gtk.gdk.RGB_DITHER_NORMAL, 0, 0 )
+
+ return True
+
+ def button_release( self, widget, event ):
+
+ if self.snap:
+ self.set_value( round(self.snap*self.get_value())/self.snap )
+
+class ImageVScale( gtk.VScale ):
+ def __init__( self, image_name, adjustment = None, slider_border = 0, insensitive_name = None, trough_color = "#3D403A", snap = False ):
+ gtk.VScale.__init__( self, adjustment )
+
+ if snap: self.snap = 1/snap
+ else: self.snap = False
+
+ colormap = self.get_colormap()
+ self.troughcolor = colormap.alloc_color( trough_color, True, True )
+
+ img = gtk.Image()
+ img.set_from_file( image_name )
+ self.sliderPixbuf = img.get_pixbuf()
+
+ if insensitive_name == None:
+ self.insensitivePixbuf = None
+ else:
+ img = gtk.Image()
+ img.set_from_file( insensitive_name )
+ self.insensitivePixbuf = img.get_pixbuf()
+
+ name = image_name + "ImageVScale"
+ self.set_name(name)
+
+ rc_str = """
+style "scale_style" {
+ GtkRange::slider_width = %d
+ GtkScale::slider_length = %d
+}
+widget "*%s*" style "scale_style"
+ """ % ( self.sliderPixbuf.get_width(), self.sliderPixbuf.get_height(), name)
+ gtk.rc_parse_string( rc_str )
+
+ self.pixbufWidth = self.sliderPixbuf.get_width()
+ self.pixbufHeight = self.sliderPixbuf.get_height()
+ self.sliderBorder = slider_border
+ self.sliderBorderMUL2 = self.sliderBorder*2
+
+ self.set_draw_value(False)
+
+ self.connect( "expose-event", self.expose )
+ self.connect( "size-allocate", self.size_allocate )
+ self.connect( "button-release-event", self.button_release )
+ adjustment.connect( "value-changed", self.value_changed )
+
+ def size_allocate( self, widget, allocation ):
+ self.alloc = allocation
+ self.sliderX = self.alloc.width//2 - self.pixbufWidth//2
+ return False
+
+ def set_snap( self, snap ):
+ if snap: self.snap = 1/snap
+ else: self.snap = False
+ self.queue_draw()
+
+ def value_changed( self, adjustment ):
+ if self.snap:
+ val = round(self.snap*self.get_value())/self.snap
+ if val != self.get_value():
+ self.set_value( val )
+
+ def expose( self, widget, event ):
+
+ style = self.get_style()
+ gc = style.fg_gc[gtk.STATE_NORMAL]
+
+ gc.foreground = self.troughcolor
+
+ self.window.draw_rectangle( gc, True, self.alloc.x + self.alloc.width//2 - 1, self.alloc.y + self.sliderBorder, 3, self.alloc.height - self.sliderBorderMUL2 )
+
+ val = self.get_value()
+ if self.snap:
+ val = round(self.snap*val)/self.snap
+ adj = self.get_adjustment()
+ if self.get_inverted():
+ sliderY = int((self.alloc.height - self.pixbufHeight)*(adj.upper-val)/(adj.upper - adj.lower))
+ else:
+ sliderY = int((self.alloc.height - self.pixbufHeight)*(val-adj.lower)/(adj.upper - adj.lower))
+
+ if self.insensitivePixbuf != None and self.state == gtk.STATE_INSENSITIVE:
+ self.window.draw_pixbuf( gc, self.insensitivePixbuf, 0, 0, self.alloc.x + self.sliderX, self.alloc.y + sliderY, self.pixbufWidth, self.pixbufHeight, gtk.gdk.RGB_DITHER_NORMAL, 0, 0 )
+ else:
+ self.window.draw_pixbuf( gc, self.sliderPixbuf, 0, 0, self.alloc.x + self.sliderX, self.alloc.y + sliderY, self.pixbufWidth, self.pixbufHeight, gtk.gdk.RGB_DITHER_NORMAL, 0, 0 )
+
+ return True
+
+ def button_release( self, widget, event ):
+
+ if self.snap:
+ self.set_value( round(self.snap*self.get_value())/self.snap )
+
+class XYSlider( gtk.EventBox ):
+ def __init__( self, fixed, button, xadjustment, yadjustment, flipX = False, flipY = False ):
+ gtk.EventBox.__init__( self )
+
+ self.fixed = fixed
+ self.button = button
+ self.xadjustment = xadjustment
+ self.yadjustment = yadjustment
+ self.flipX = flipX
+ self.flipY = flipY
+
+ if ( button.get_parent() == None ):
+ fixed.put( button, 0, 0 )
+
+ self.add(fixed)
+
+ self.fWidth = self.fHeight = 1
+ self.bWidth = self.bHeight = 1
+
+ self.add_events(gtk.gdk.POINTER_MOTION_HINT_MASK)
+ self.connect( "size-allocate", lambda w,a:self.updateAlloc() )
+ self.connect( "button-press-event", self.handlePress )
+ self.connect( "button-release-event", self.handleRelease )
+ self.connect( "motion-notify-event", self.handleMotion )
+ self.button.connect( "size-allocate", lambda w,a: self.updateButton() )
+ self.button.connect( "button-press-event", self.handleButtonPress )
+ self.button.connect( "button-release-event", self.handleButtonRelease )
+ self.button.add_events(gtk.gdk.BUTTON_MOTION_MASK|gtk.gdk.POINTER_MOTION_HINT_MASK)
+ self.button.connect( "motion-notify-event", self.handleMotion )
+ self.xadjustment.connect( "changed", lambda a1: self.updateAdjustemnt("x") )
+ self.xadjustment.connect( "value-changed", lambda a1: self.updateLoc() )
+ self.yadjustment.connect( "changed", lambda a1: self.updateAdjustment("y") )
+ self.yadjustment.connect( "value-changed", lambda a1: self.updateLoc() )
+
+ self.updateAdjustment("x")
+ self.updateAdjustment("y")
+ self.updateButton()
+
+ def updateAlloc( self ):
+ alloc = self.fixed.get_allocation()
+ if self.fWidth != alloc.width or self.fHeight != alloc.height:
+ self.fWidth = alloc.width
+ self.fHeight = alloc.height
+ self.width = self.fWidth - self.bWidth
+ self.height = self.fHeight - self.bHeight
+ self.updateLoc()
+
+ def updateButton( self ):
+ alloc = self.button.get_allocation()
+ if self.bWidth != alloc.width or self.bHeight != alloc.height:
+ self.bWidth = alloc.width
+ self.bHeight = alloc.height
+ self.bWidthDIV2 = alloc.width//2
+ self.bHeightDIV2 = alloc.height//2
+ self.width = self.fWidth - self.bWidth
+ self.height = self.fHeight - self.bHeight
+ self.updateLoc()
+
+ def updateAdjustment( self, which ):
+ if which == "x": self.xRange = int(self.xadjustment.upper - self.xadjustment.lower)
+ else: self.yRange = int(self.yadjustment.upper - self.yadjustment.lower)
+
+ def updateLoc( self ):
+ if self.flipX: self.x = (self.width*int(self.xadjustment.upper - self.xadjustment.value))//self.xRange
+ else: self.x = (self.width*int(self.xadjustment.value - self.xadjustment.lower))//self.xRange
+ if self.flipY: self.y = (self.height*int(self.yadjustment.upper - self.yadjustment.value))//self.yRange
+ else: self.y = (self.height*int(self.yadjustment.value - self.yadjustment.lower))//self.yRange
+
+ self.fixed.move( self.button, self.x, self.y )
+
+ def handlePress( self, w, event ):
+ self.clickOffset = (0,0)
+ self.updatePointer( int(event.x), int(event.y) )
+ self.button.set_active(True)
+
+ def handleRelease( self, w, event ):
+ self.button.set_active(False)
+ return True
+
+ def handleButtonPress( self, w, event ):
+ self.clickOffset = ( event.x - self.bWidthDIV2, event.y - self.bHeightDIV2 )
+ self.button.set_active(True)
+
+ def handleButtonRelease( self, w, event ):
+ self.button.set_active(False)
+ return True # block event propagation
+
+ def handleMotion( self, w, event ):
+ x, y, state = self.window.get_pointer()
+ self.updatePointer( int(x - self.clickOffset[0]), int(y - self.clickOffset[1]) )
+ return True
+
+ def updatePointer( self, x, y ):
+ x -= self.bWidthDIV2
+ y -= self.bHeightDIV2
+ if x < 0: x = 0
+ elif x > self.width: x = self.width
+ if y < 0: y = 0
+ elif y > self.height: y = self.height
+ if self.flipX: xvalue = self.xadjustment.lower+(self.xRange*(self.width - x))//self.width
+ else: xvalue = self.xadjustment.lower+(self.xRange*x)//self.width
+ if xvalue != self.xadjustment.value: self.xadjustment.set_value(xvalue)
+ if self.flipY: yvalue = self.yadjustment.lower+(self.yRange*(self.height - y))//self.height
+ else: yvalue = self.yadjustment.lower+(self.yRange*y)//self.height
+ if yvalue != self.yadjustment.value: self.yadjustment.set_value(yvalue)
+
+class RoundHBox( gtk.HBox ):
+ def __init__( self, radius = 5, fillcolor = "#000", bordercolor = "#FFF", homogeneous = False, spacing = 0 ):
+ gtk.HBox.__init__( self, homogeneous, spacing )
+ self.alloc = None
+
+ self.radius = radius
+
+ colormap = self.get_colormap()
+ self.fillcolor = colormap.alloc_color(fillcolor,True,True)
+ self.bordercolor = colormap.alloc_color(bordercolor,True,True)
+
+ self.connect( "expose-event", self.expose )
+ self.connect( "size-allocate", self.size_allocate )
+
+ def update_constants( self ):
+
+ if self.alloc == None: return
+
+ self.borderW = self.get_border_width()
+ self.borderWMUL2 = self.borderW*2
+ self.corner = self.radius + self.borderW
+ self.cornerMUL2 = self.corner*2
+ self.cornerMINborderW = self.corner - self.borderW
+
+ self.xPLUborderW = self.alloc.x + self.borderW
+ self.xPLUcorner = self.alloc.x + self.corner
+ self.xPLUwidthMINborderW = self.alloc.x + self.alloc.width - self.borderW
+ self.xPLUwidthMINcorner = self.alloc.x + self.alloc.width - self.corner
+ self.yPLUborderW = self.alloc.y + self.borderW
+ self.yPLUcorner = self.alloc.y + self.corner
+ self.yPLUheightMINborderW = self.alloc.y + self.alloc.height - self.borderW
+ self.yPLUheightMINcorner = self.alloc.y + self.alloc.height - self.corner
+ self.widthMINborderW = self.alloc.width - self.borderW
+ self.widthMINcorner = self.alloc.width - self.corner
+ self.widthMINcornerMUL2 = self.alloc.width - self.cornerMUL2
+ self.heightMINborderW = self.alloc.height - self.borderW
+ self.heightMINcorner = self.alloc.height - self.corner
+ self.heightMINborderWMUL2 = self.alloc.height - self.borderWMUL2
+ self.heightMINcornerMUL2 = self.alloc.height - self.cornerMUL2
+
+ self.roundX1 = self.alloc.x + self.borderW - 1
+ self.roundX2 = self.alloc.x + self.alloc.width - self.corner - self.radius - 1
+ self.roundY1 = self.alloc.y + self.borderW - 1
+ self.roundY2 = self.alloc.y + self.alloc.height - self.corner - self.radius - 1
+ self.roundD = self.radius*2 + 1
+ self.rightAngle = 90*64
+
+ def size_allocate( self, widget, allocation ):
+ self.alloc = allocation
+ self.update_constants()
+ return False
+
+ def set_border_width( self, width ):
+ gtk.HBox.set_border_width( self, width )
+ self.update_constants()
+
+ def set_radius( self, radius ):
+ self.radius = radius
+ self.update_constants()
+
+ def set_fill_color( self, color ):
+ colormap = self.get_colormap()
+ self.fillcolor = colormap.alloc_color(color,True,True)
+
+ def set_border_color( self, color ):
+ colormap = self.get_colormap()
+ self.bordercolor = colormap.alloc_color(color,True,True)
+
+ def expose( self, widget, event ):
+
+ if self.alloc == None: return
+
+ #TP.ProfileBegin( "Round*Box::expose" )
+
+ style = self.get_style()
+ gc = style.fg_gc[gtk.STATE_NORMAL]
+
+ startX = event.area.x - self.alloc.x
+ startY = event.area.y - self.alloc.y
+ stopX = startX + event.area.width
+ stopY = startY + event.area.height
+
+ saveForeground = gc.foreground
+
+ # Note: could maybe do some optimization to fill only areas that are within the dirty rect, but drawing
+ # seems to be quite fast compared to python code, so just leave it at clipping by each geometry feature
+
+ gc.foreground = self.bordercolor
+ if self.borderW:
+ if stopY > self.corner and startY < self.heightMINcorner:
+ if startX < self.borderW: # draw left border
+ self.window.draw_rectangle( gc, True, self.alloc.x, self.yPLUcorner, self.borderW, self.heightMINcornerMUL2 )
+ if stopX > self.widthMINborderW: # draw right border
+ self.window.draw_rectangle( gc, True, self.xPLUwidthMINborderW, self.yPLUcorner, self.borderW, self.heightMINcornerMUL2 )
+
+ if stopX > self.corner and startX < self.widthMINcorner:
+ if startY < self.borderW: # draw top border
+ self.window.draw_rectangle( gc, True, self.xPLUcorner, self.alloc.y, self.widthMINcornerMUL2, self.borderW )
+ if stopY > self.heightMINborderW: # draw bottom border
+ self.window.draw_rectangle( gc, True, self.xPLUcorner, self.yPLUheightMINborderW, self.widthMINcornerMUL2, self.borderW )
+
+ if startX < self.corner:
+ if startY < self.corner: # draw top left corner
+ self.window.draw_rectangle( gc, True, self.alloc.x, self.alloc.y, self.corner, self.corner )
+ gc.foreground = self.fillcolor
+ self.window.draw_arc( gc, True, self.roundX1, self.roundY1, self.roundD, self.roundD, self.rightAngle, self.rightAngle )
+ gc.foreground = self.bordercolor
+ if stopY > self.heightMINcorner: # draw bottom left corner
+ self.window.draw_rectangle( gc, True, self.alloc.x, self.yPLUheightMINcorner, self.corner, self.corner )
+ gc.foreground = self.fillcolor
+ self.window.draw_arc( gc, True, self.roundX1, self.roundY2, self.roundD, self.roundD, -self.rightAngle, -self.rightAngle )
+ gc.foreground = self.bordercolor
+ if stopX > self.widthMINcorner:
+ if startY < self.corner: # draw top right corner
+ self.window.draw_rectangle( gc, True, self.xPLUwidthMINcorner, self.alloc.y, self.corner, self.corner )
+ gc.foreground = self.fillcolor
+ self.window.draw_arc( gc, True, self.roundX2, self.roundY1, self.roundD, self.roundD, 0, self.rightAngle )
+ gc.foreground = self.bordercolor
+ if stopY > self.heightMINcorner: # draw bottom right corner
+ self.window.draw_rectangle( gc, True, self.xPLUwidthMINcorner, self.yPLUheightMINcorner, self.corner, self.corner )
+ gc.foreground = self.fillcolor
+ self.window.draw_arc( gc, True, self.roundX2, self.roundY2, self.roundD, self.roundD, 0, -self.rightAngle )
+ gc.foreground = self.bordercolor
+
+ gc.foreground = self.fillcolor
+ if startX < self.widthMINcorner and stopX > self.corner:
+ if startY < self.heightMINborderW and stopY > self.borderW: # draw centre fill
+ self.window.draw_rectangle( gc, True, self.xPLUcorner, self.yPLUborderW, self.widthMINcornerMUL2, self.heightMINborderWMUL2 )
+ if startX < self.corner and stopX > self.borderW:
+ if startY < self.heightMINcorner and stopY > self.corner: # draw left fill
+ self.window.draw_rectangle( gc, True, self.xPLUborderW, self.yPLUcorner, self.cornerMINborderW, self.heightMINcornerMUL2 )
+ if startX < self.widthMINborderW and stopX > self.widthMINcorner:
+ if startY < self.heightMINcorner and stopY > self.corner: # draw right fill
+ self.window.draw_rectangle( gc, True, self.xPLUwidthMINcorner, self.yPLUcorner, self.cornerMINborderW, self.heightMINcornerMUL2 )
+
+ gc.foreground = saveForeground
+
+ #TP.ProfileEnd( "Round*Box::expose" )
+
+ return False
+
+class RoundVBox( gtk.VBox ):
+ def __init__( self, radius = 5, fillcolor = "#000", bordercolor = "#FFF", homogeneous = False, spacing = 0 ):
+ gtk.VBox.__init__( self, homogeneous, spacing )
+ self.alloc = None
+
+ self.radius = radius
+
+ colormap = self.get_colormap()
+ self.fillcolor = colormap.alloc_color(fillcolor,True,True)
+ self.bordercolor = colormap.alloc_color(bordercolor,True,True)
+
+ self.connect( "expose-event",self.expose )
+ self.connect( "size-allocate", self.size_allocate )
+
+ def update_constants( self ):
+
+ if self.alloc == None: return
+
+ self.borderW = self.get_border_width()
+ self.borderWMUL2 = self.borderW*2
+ self.corner = self.radius + self.borderW
+ self.cornerMUL2 = self.corner*2
+ self.cornerMINborderW = self.corner - self.borderW
+
+ self.xPLUborderW = self.alloc.x + self.borderW
+ self.xPLUcorner = self.alloc.x + self.corner
+ self.xPLUwidthMINborderW = self.alloc.x + self.alloc.width - self.borderW
+ self.xPLUwidthMINcorner = self.alloc.x + self.alloc.width - self.corner
+ self.yPLUborderW = self.alloc.y + self.borderW
+ self.yPLUcorner = self.alloc.y + self.corner
+ self.yPLUheightMINborderW = self.alloc.y + self.alloc.height - self.borderW
+ self.yPLUheightMINcorner = self.alloc.y + self.alloc.height - self.corner
+ self.widthMINborderW = self.alloc.width - self.borderW
+ self.widthMINcorner = self.alloc.width - self.corner
+ self.widthMINcornerMUL2 = self.alloc.width - self.cornerMUL2
+ self.heightMINborderW = self.alloc.height - self.borderW
+ self.heightMINcorner = self.alloc.height - self.corner
+ self.heightMINborderWMUL2 = self.alloc.height - self.borderWMUL2
+ self.heightMINcornerMUL2 = self.alloc.height - self.cornerMUL2
+
+ self.roundX1 = self.alloc.x + self.borderW - 1
+ self.roundX2 = self.alloc.x + self.alloc.width - self.corner - self.radius - 1
+ self.roundY1 = self.alloc.y + self.borderW - 1
+ self.roundY2 = self.alloc.y + self.alloc.height - self.corner - self.radius - 1
+ self.roundD = self.radius*2 + 1
+ self.rightAngle = 90*64
+
+ def size_allocate( self, widget, allocation ):
+ self.alloc = allocation
+ self.update_constants()
+ return False
+
+ def set_border_width( self, width ):
+ gtk.VBox.set_border_width( self, width )
+ self.update_constants()
+
+ def set_radius( self, radius ):
+ self.radius = radius
+ self.update_constants()
+
+ def set_fill_color( self, color ):
+ colormap = self.get_colormap()
+ self.fillcolor = colormap.alloc_color(color,True,True)
+
+ def set_border_color( self, color ):
+ colormap = self.get_colormap()
+ self.bordercolor = colormap.alloc_color(color,True,True)
+
+ def expose( self, widget, event ):
+
+ if self.alloc == None: return
+
+ #TP.ProfileBegin( "Round*Box::expose" )
+
+ style = self.get_style()
+ gc = style.fg_gc[gtk.STATE_NORMAL]
+
+ startX = event.area.x - self.alloc.x
+ startY = event.area.y - self.alloc.y
+ stopX = startX + event.area.width
+ stopY = startY + event.area.height
+
+ saveForeground = gc.foreground
+
+ # Note: could maybe do some optimization to fill only areas that are within the dirty rect, but drawing
+ # seems to be quite fast compared to python code, so just leave it at clipping by each geometry feature
+
+ gc.foreground = self.bordercolor
+ if self.borderW:
+ if stopY > self.corner and startY < self.heightMINcorner:
+ if startX < self.borderW: # draw left border
+ self.window.draw_rectangle( gc, True, self.alloc.x, self.yPLUcorner, self.borderW, self.heightMINcornerMUL2 )
+ if stopX > self.widthMINborderW: # draw right border
+ self.window.draw_rectangle( gc, True, self.xPLUwidthMINborderW, self.yPLUcorner, self.borderW, self.heightMINcornerMUL2 )
+
+ if stopX > self.corner and startX < self.widthMINcorner:
+ if startY < self.borderW: # draw top border
+ self.window.draw_rectangle( gc, True, self.xPLUcorner, self.alloc.y, self.widthMINcornerMUL2, self.borderW )
+ if stopY > self.heightMINborderW: # draw bottom border
+ self.window.draw_rectangle( gc, True, self.xPLUcorner, self.yPLUheightMINborderW, self.widthMINcornerMUL2, self.borderW )
+
+ if startX < self.corner:
+ if startY < self.corner: # draw top left corner
+ self.window.draw_rectangle( gc, True, self.alloc.x, self.alloc.y, self.corner, self.corner )
+ gc.foreground = self.fillcolor
+ self.window.draw_arc( gc, True, self.roundX1, self.roundY1, self.roundD, self.roundD, self.rightAngle, self.rightAngle )
+ gc.foreground = self.bordercolor
+ if stopY > self.heightMINcorner: # draw bottom left corner
+ self.window.draw_rectangle( gc, True, self.alloc.x, self.yPLUheightMINcorner, self.corner, self.corner )
+ gc.foreground = self.fillcolor
+ self.window.draw_arc( gc, True, self.roundX1, self.roundY2, self.roundD, self.roundD, -self.rightAngle, -self.rightAngle )
+ gc.foreground = self.bordercolor
+ if stopX > self.widthMINcorner:
+ if startY < self.corner: # draw top right corner
+ self.window.draw_rectangle( gc, True, self.xPLUwidthMINcorner, self.alloc.y, self.corner, self.corner )
+ gc.foreground = self.fillcolor
+ self.window.draw_arc( gc, True, self.roundX2, self.roundY1, self.roundD, self.roundD, 0, self.rightAngle )
+ gc.foreground = self.bordercolor
+ if stopY > self.heightMINcorner: # draw bottom right corner
+ self.window.draw_rectangle( gc, True, self.xPLUwidthMINcorner, self.yPLUheightMINcorner, self.corner, self.corner )
+ gc.foreground = self.fillcolor
+ self.window.draw_arc( gc, True, self.roundX2, self.roundY2, self.roundD, self.roundD, 0, -self.rightAngle )
+ gc.foreground = self.bordercolor
+
+ gc.foreground = self.fillcolor
+ if startX < self.widthMINcorner and stopX > self.corner:
+ if startY < self.heightMINborderW and stopY > self.borderW: # draw centre fill
+ self.window.draw_rectangle( gc, True, self.xPLUcorner, self.yPLUborderW, self.widthMINcornerMUL2, self.heightMINborderWMUL2 )
+ if startX < self.corner and stopX > self.borderW:
+ if startY < self.heightMINcorner and stopY > self.corner: # draw left fill
+ self.window.draw_rectangle( gc, True, self.xPLUborderW, self.yPLUcorner, self.cornerMINborderW, self.heightMINcornerMUL2 )
+ if startX < self.widthMINborderW and stopX > self.widthMINcorner:
+ if startY < self.heightMINcorner and stopY > self.corner: # draw right fill
+ self.window.draw_rectangle( gc, True, self.xPLUwidthMINcorner, self.yPLUcorner, self.cornerMINborderW, self.heightMINcornerMUL2 )
+
+ gc.foreground = saveForeground
+
+ #TP.ProfileEnd( "Round*Box::expose" )
+
+ return False
+
+class RoundFixed( gtk.Fixed ):
+ def __init__( self, radius = 5, fillcolor = "#000", bordercolor = "#FFF" ):
+ gtk.Fixed.__init__( self )
+ self.alloc = None
+
+ self.radius = radius
+
+ colormap = self.get_colormap()
+ self.fillcolor = colormap.alloc_color(fillcolor,True,True)
+ self.bordercolor = colormap.alloc_color(bordercolor,True,True)
+
+ self.connect( "expose-event", self.expose )
+ self.connect( "size-allocate", self.size_allocate )
+
+ def update_constants( self ):
+
+ if self.alloc == None: return
+
+ self.borderW = self.get_border_width()
+ self.borderWMUL2 = self.borderW*2
+ self.corner = self.radius + self.borderW
+ self.cornerMUL2 = self.corner*2
+ self.cornerMINborderW = self.corner - self.borderW
+
+ self.xPLUborderW = self.alloc.x + self.borderW
+ self.xPLUcorner = self.alloc.x + self.corner
+ self.xPLUwidthMINborderW = self.alloc.x + self.alloc.width - self.borderW
+ self.xPLUwidthMINcorner = self.alloc.x + self.alloc.width - self.corner
+ self.yPLUborderW = self.alloc.y + self.borderW
+ self.yPLUcorner = self.alloc.y + self.corner
+ self.yPLUheightMINborderW = self.alloc.y + self.alloc.height - self.borderW
+ self.yPLUheightMINcorner = self.alloc.y + self.alloc.height - self.corner
+ self.widthMINborderW = self.alloc.width - self.borderW
+ self.widthMINcorner = self.alloc.width - self.corner
+ self.widthMINcornerMUL2 = self.alloc.width - self.cornerMUL2
+ self.heightMINborderW = self.alloc.height - self.borderW
+ self.heightMINcorner = self.alloc.height - self.corner
+ self.heightMINborderWMUL2 = self.alloc.height - self.borderWMUL2
+ self.heightMINcornerMUL2 = self.alloc.height - self.cornerMUL2
+
+ self.roundX1 = self.alloc.x + self.borderW - 1
+ self.roundX2 = self.alloc.x + self.alloc.width - self.corner - self.radius - 1
+ self.roundY1 = self.alloc.y + self.borderW - 1
+ self.roundY2 = self.alloc.y + self.alloc.height - self.corner - self.radius - 1
+ self.roundD = self.radius*2 + 1
+ self.rightAngle = 90*64
+
+ def size_allocate( self, widget, allocation ):
+ self.alloc = allocation
+ self.update_constants()
+ return False
+
+ def set_border_width( self, width ):
+ gtk.Fixed.set_border_width( self, width )
+ self.update_constants()
+
+ def set_radius( self, radius ):
+ self.radius = radius
+ self.update_constants()
+
+ def set_fill_color( self, color ):
+ colormap = self.get_colormap()
+ self.fillcolor = colormap.alloc_color(color,True,True)
+
+ def set_border_color( self, color ):
+ colormap = self.get_colormap()
+ self.bordercolor = colormap.alloc_color(color,True,True)
+
+ def expose( self, widget, event ):
+
+ if self.alloc == None: return
+
+ #TP.ProfileBegin( "Round*Box::expose" )
+
+ style = self.get_style()
+ gc = style.fg_gc[gtk.STATE_NORMAL]
+
+ startX = event.area.x - self.alloc.x
+ startY = event.area.y - self.alloc.y
+ stopX = startX + event.area.width
+ stopY = startY + event.area.height
+
+ saveForeground = gc.foreground
+
+ # Note: could maybe do some optimization to fill only areas that are within the dirty rect, but drawing
+ # seems to be quite fast compared to python code, so just leave it at clipping by each geometry feature
+
+ gc.foreground = self.bordercolor
+ if self.borderW:
+ if stopY > self.corner and startY < self.heightMINcorner:
+ if startX < self.borderW: # draw left border
+ self.window.draw_rectangle( gc, True, self.alloc.x, self.yPLUcorner, self.borderW, self.heightMINcornerMUL2 )
+ if stopX > self.widthMINborderW: # draw right border
+ self.window.draw_rectangle( gc, True, self.xPLUwidthMINborderW, self.yPLUcorner, self.borderW, self.heightMINcornerMUL2 )
+
+ if stopX > self.corner and startX < self.widthMINcorner:
+ if startY < self.borderW: # draw top border
+ self.window.draw_rectangle( gc, True, self.xPLUcorner, self.alloc.y, self.widthMINcornerMUL2, self.borderW )
+ if stopY > self.heightMINborderW: # draw bottom border
+ self.window.draw_rectangle( gc, True, self.xPLUcorner, self.yPLUheightMINborderW, self.widthMINcornerMUL2, self.borderW )
+
+ if startX < self.corner:
+ if startY < self.corner: # draw top left corner
+ self.window.draw_rectangle( gc, True, self.alloc.x, self.alloc.y, self.corner, self.corner )
+ gc.foreground = self.fillcolor
+ self.window.draw_arc( gc, True, self.roundX1, self.roundY1, self.roundD, self.roundD, self.rightAngle, self.rightAngle )
+ gc.foreground = self.bordercolor
+ if stopY > self.heightMINcorner: # draw bottom left corner
+ self.window.draw_rectangle( gc, True, self.alloc.x, self.yPLUheightMINcorner, self.corner, self.corner )
+ gc.foreground = self.fillcolor
+ self.window.draw_arc( gc, True, self.roundX1, self.roundY2, self.roundD, self.roundD, -self.rightAngle, -self.rightAngle )
+ gc.foreground = self.bordercolor
+ if stopX > self.widthMINcorner:
+ if startY < self.corner: # draw top right corner
+ self.window.draw_rectangle( gc, True, self.xPLUwidthMINcorner, self.alloc.y, self.corner, self.corner )
+ gc.foreground = self.fillcolor
+ self.window.draw_arc( gc, True, self.roundX2, self.roundY1, self.roundD, self.roundD, 0, self.rightAngle )
+ gc.foreground = self.bordercolor
+ if stopY > self.heightMINcorner: # draw bottom right corner
+ self.window.draw_rectangle( gc, True, self.xPLUwidthMINcorner, self.yPLUheightMINcorner, self.corner, self.corner )
+ gc.foreground = self.fillcolor
+ self.window.draw_arc( gc, True, self.roundX2, self.roundY2, self.roundD, self.roundD, 0, -self.rightAngle )
+ gc.foreground = self.bordercolor
+
+ gc.foreground = self.fillcolor
+ if startX < self.widthMINcorner and stopX > self.corner:
+ if startY < self.heightMINborderW and stopY > self.borderW: # draw centre fill
+ self.window.draw_rectangle( gc, True, self.xPLUcorner, self.yPLUborderW, self.widthMINcornerMUL2, self.heightMINborderWMUL2 )
+ if startX < self.corner and stopX > self.borderW:
+ if startY < self.heightMINcorner and stopY > self.corner: # draw left fill
+ self.window.draw_rectangle( gc, True, self.xPLUborderW, self.yPLUcorner, self.cornerMINborderW, self.heightMINcornerMUL2 )
+ if startX < self.widthMINborderW and stopX > self.widthMINcorner:
+ if startY < self.heightMINcorner and stopY > self.corner: # draw right fill
+ self.window.draw_rectangle( gc, True, self.xPLUwidthMINcorner, self.yPLUcorner, self.cornerMINborderW, self.heightMINcornerMUL2 )
+
+ gc.foreground = saveForeground
+
+ #TP.ProfileEnd( "Round*Box::expose" )
+
+ return False
+
+class ImageButton(gtk.Button):
+ def __init__( self, mainImg_path, clickImg_path = None, enterImg_path = None, backgroundFill = None ):
+ gtk.Button.__init__(self)
+ self.alloc = None
+ win = gtk.gdk.get_default_root_window()
+ self.gc = gtk.gdk.GC( win )
+ self.image = {}
+ self.itype = {}
+ self.iwidth = {}
+ self.iwidthDIV2 = {}
+ self.iheight = {}
+ self.iheightDIV2 = {}
+
+ self.backgroundFill = backgroundFill
+
+ def prepareImage( name, path ):
+ pix = gtk.gdk.pixbuf_new_from_file(path)
+ if pix.get_has_alpha():
+ if backgroundFill == None:
+ self.image[name] = pix
+ self.itype[name] = ITYPE.PIXBUF
+ else:
+ self.image[name] = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ colormap = self.get_colormap()
+ self.gc.foreground = colormap.alloc_color( backgroundFill, True, True )
+ self.image[name].draw_rectangle( self.gc, True, 0, 0, pix.get_width(), pix.get_height() )
+ self.image[name].draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.itype[name] = ITYPE.PIXMAP
+ else:
+ self.image[name] = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ self.image[name].draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.itype[name] = ITYPE.PIXMAP
+ self.iwidth[name] = pix.get_width()
+ self.iwidthDIV2[name] = self.iwidth[name]//2
+ self.iheight[name] = pix.get_height()
+ self.iheightDIV2[name] = self.iheight[name]//2
+
+ prepareImage( "main", mainImg_path )
+
+ if enterImg_path != None:
+ prepareImage( "enter", enterImg_path )
+ self.connect('enter-notify-event',self.on_btn_enter)
+ self.connect('leave-notify-event',self.on_btn_leave)
+ if clickImg_path != None:
+ prepareImage( "click", clickImg_path )
+ self.connect('pressed',self.on_btn_press, None)
+ self.connect('released',self.on_btn_release, None)
+ if enterImg_path == None:
+ self.image["enter"] = self.image["main"]
+ self.itype["enter"] = self.itype["main"]
+ self.iwidth["enter"] = self.iwidth["main"]
+ self.iwidthDIV2["enter"] = self.iwidthDIV2["main"]
+ self.iheight["enter"] = self.iheight["main"]
+ self.iheightDIV2["enter"] = self.iheightDIV2["main"]
+ self.connect('enter-notify-event',self.on_btn_enter)
+ self.connect('leave-notify-event',self.on_btn_leave)
+
+ self.curImage = self.upImage = "main"
+ self.down = False
+
+ self.connect('expose-event', self.expose)
+ self.connect('size-allocate', self.size_allocate)
+
+ self.set_size_request(self.iwidth["main"],self.iheight["main"])
+
+ def size_allocate(self, widget, allocation):
+ self.alloc = allocation
+ self.drawX = allocation.x + allocation.width//2
+ self.drawY = allocation.y + allocation.height//2
+
+ def expose(self, widget, event):
+ if self.itype[self.curImage] == ITYPE.PIXBUF:
+ self.window.draw_pixbuf( self.gc, self.image[self.curImage], 0, 0, self.drawX - self.iwidthDIV2[self.curImage], self.drawY - self.iheightDIV2[self.curImage], self.iwidth[self.curImage], self.iheight[self.curImage], gtk.gdk.RGB_DITHER_NONE)
+ else:
+ self.window.draw_drawable( self.gc, self.image[self.curImage], 0, 0, self.drawX - self.iwidthDIV2[self.curImage], self.drawY - self.iheightDIV2[self.curImage], self.iwidth[self.curImage], self.iheight[self.curImage] )
+ return True
+
+ def setImage(self, name, pix):
+ if name == "main" and self.image["main"] == self.image["enter"]:
+ updateEnter = True
+ else:
+ updateEnter = False
+
+ if pix.get_has_alpha():
+ if self.backgroundFill == None:
+ self.image[name] = pix
+ self.itype[name] = ITYPE.PIXBUF
+ else:
+ self.image[name] = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ colormap = self.get_colormap()
+ self.gc.foreground = colormap.alloc_color( self.backgroundFill, True, True )
+ self.image[name].draw_rectangle( self.gc, True, 0, 0, pix.get_width(), pix.get_height() )
+ self.image[name].draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.itype[name] = ITYPE.PIXMAP
+ else:
+ self.image[name] = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ self.image[name].draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.itype[name] = ITYPE.PIXMAP
+ self.iwidth[name] = pix.get_width()
+ self.iwidthDIV2[name] = self.iwidth[name]//2
+ self.iheight[name] = pix.get_height()
+ self.iheightDIV2[name] = self.iheight[name]//2
+
+ if updateEnter:
+ self.image["enter"] = self.image["main"]
+ self.itype["enter"] = self.itype["main"]
+ self.iwidth["enter"] = self.iwidth["main"]
+ self.iwidthDIV2["enter"] = self.iwidthDIV2["main"]
+ self.iheight["enter"] = self.iheight["main"]
+ self.iheightDIV2["enter"] = self.iheightDIV2["main"]
+ self.connect('enter-notify-event',self.on_btn_enter)
+ self.connect('leave-notify-event',self.on_btn_leave)
+
+ self.queue_draw()
+
+ def on_btn_press(self, widget, event):
+ self.curImage = "click"
+ self.down = True
+ self.queue_draw()
+
+ def on_btn_enter(self, widget, event):
+ if event.mode == gtk.gdk.CROSSING_NORMAL:
+ self.upImage = "enter"
+ if self.down: self.curImage = "click"
+ else: self.curImage = "enter"
+ self.queue_draw()
+
+ def on_btn_leave(self, widget, event):
+ if event.mode == gtk.gdk.CROSSING_NORMAL:
+ self.curImage = self.upImage = "main"
+ self.queue_draw()
+
+ def on_btn_release(self, widget, event):
+ self.curImage = self.upImage
+ self.down = False
+ self.queue_draw()
+
+ def set_palette(self, palette):
+ self._palette = palette
+ self._palette.props.invoker = WidgetInvoker(self)
+ self._palette.props.invoker._position_hint = WidgetInvoker.AT_CURSOR
+
+class ImageToggleButton(gtk.ToggleButton):
+
+ def __init__(self , mainImg_path, altImg_path, enterImg_path = None, backgroundFill = None ):
+ gtk.ToggleButton.__init__(self)
+ self.alloc = None
+ self.within = False
+ self.clicked = False
+
+ win = gtk.gdk.get_default_root_window()
+ self.gc = gtk.gdk.GC( win )
+ self.image = {}
+ self.itype = {}
+ self.iwidth = {}
+ self.iwidthDIV2 = {}
+ self.iheight = {}
+ self.iheightDIV2 = {}
+
+ self.backgroundFill = backgroundFill
+
+ def prepareImage( name, path ):
+ pix = gtk.gdk.pixbuf_new_from_file(path)
+ if pix.get_has_alpha():
+ if backgroundFill == None:
+ self.image[name] = pix
+ self.itype[name] = ITYPE.PIXBUF
+ else:
+ self.image[name] = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ colormap = self.get_colormap()
+ self.gc.foreground = colormap.alloc_color( backgroundFill, True, True )
+ self.image[name].draw_rectangle( self.gc, True, 0, 0, pix.get_width(), pix.get_height() )
+ self.image[name].draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.itype[name] = ITYPE.PIXMAP
+ else:
+ self.image[name] = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ self.image[name].draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.itype[name] = ITYPE.PIXMAP
+ self.iwidth[name] = pix.get_width()
+ self.iwidthDIV2[name] = self.iwidth[name]//2
+ self.iheight[name] = pix.get_height()
+ self.iheightDIV2[name] = self.iheight[name]//2
+
+ prepareImage( "main", mainImg_path )
+ prepareImage( "alt", altImg_path )
+
+ if enterImg_path != None:
+ prepareImage( "enter", enterImg_path )
+ else:
+ self.image["enter"] = self.image["main"]
+ self.itype["enter"] = self.itype["main"]
+ self.iwidth["enter"] = self.iwidth["main"]
+ self.iwidthDIV2["enter"] = self.iwidthDIV2["main"]
+ self.iheight["enter"] = self.iheight["main"]
+ self.iheightDIV2["enter"] = self.iheightDIV2["main"]
+
+ self.connect('enter-notify-event',self.on_btn_enter)
+ self.connect('leave-notify-event',self.on_btn_leave)
+
+ self.connect('toggled',self.toggleImage)
+ self.connect('pressed',self.pressed )
+ self.connect('released',self.released )
+ self.connect('expose-event', self.expose)
+ self.connect('size-allocate', self.size_allocate)
+
+ self.set_size_request(self.iwidth["main"],self.iheight["main"])
+
+ self.toggleImage( self )
+
+ def size_allocate(self, widget, allocation):
+ self.alloc = allocation
+ self.drawX = allocation.x + allocation.width//2
+ self.drawY = allocation.y + allocation.height//2
+
+ def expose(self, widget, event):
+ if self.itype[self.curImage] == ITYPE.PIXBUF:
+ self.window.draw_pixbuf( self.gc, self.image[self.curImage], 0, 0, self.drawX - self.iwidthDIV2[self.curImage], self.drawY - self.iheightDIV2[self.curImage], self.iwidth[self.curImage], self.iheight[self.curImage], gtk.gdk.RGB_DITHER_NONE)
+ else:
+ self.window.draw_drawable( self.gc, self.image[self.curImage], 0, 0, self.drawX - self.iwidthDIV2[self.curImage], self.drawY - self.iheightDIV2[self.curImage], self.iwidth[self.curImage], self.iheight[self.curImage] )
+ return True
+
+ def setImage(self, name, pix):
+ if name == "main" and self.image["main"] == self.image["enter"]:
+ updateEnter = True
+ else:
+ updateEnter = False
+
+ if pix.get_has_alpha():
+ if self.backgroundFill == None:
+ self.image[name] = pix
+ self.itype[name] = ITYPE.PIXBUF
+ else:
+ self.image[name] = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ colormap = self.get_colormap()
+ self.gc.foreground = colormap.alloc_color( self.backgroundFill, True, True )
+ self.image[name].draw_rectangle( self.gc, True, 0, 0, pix.get_width(), pix.get_height() )
+ self.image[name].draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.itype[name] = ITYPE.PIXMAP
+ else:
+ self.image[name] = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ self.image[name].draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.itype[name] = ITYPE.PIXMAP
+ self.iwidth[name] = pix.get_width()
+ self.iwidthDIV2[name] = self.iwidth[name]//2
+ self.iheight[name] = pix.get_height()
+ self.iheightDIV2[name] = self.iheight[name]//2
+
+ if updateEnter:
+ self.image["enter"] = self.image["main"]
+ self.itype["enter"] = self.itype["main"]
+ self.iwidth["enter"] = self.iwidth["main"]
+ self.iwidthDIV2["enter"] = self.iwidthDIV2["main"]
+ self.iheight["enter"] = self.iheight["main"]
+ self.iheightDIV2["enter"] = self.iheightDIV2["main"]
+ self.connect('enter-notify-event',self.on_btn_enter)
+ self.connect('leave-notify-event',self.on_btn_leave)
+
+ self.queue_draw()
+
+ def toggleImage(self, widget):
+ if not self.get_active():
+ if self.within and self.image.has_key("enter"):
+ self.curImage = "enter"
+ else:
+ self.curImage = "main"
+ else:
+ self.curImage = "alt"
+ self.queue_draw()
+
+ def pressed( self, widget ):
+ self.clicked = True
+ self.curImage = "alt"
+ self.queue_draw()
+
+ def released( self, widget ):
+ self.clicked = False
+ self.toggleImage( self )
+
+ def on_btn_enter(self, widget, event ):
+ if event.mode == gtk.gdk.CROSSING_NORMAL:
+ self.within = True
+ if not self.get_active() and not self.clicked:
+ self.curImage = "enter"
+ else:
+ self.curImage = "alt"
+ self.queue_draw()
+
+ def on_btn_leave(self, widget, event ):
+ if event.mode == gtk.gdk.CROSSING_NORMAL:
+ self.within = False
+ if not self.get_active():
+ self.curImage = "main"
+ else:
+ self.curImage = "alt"
+ self.queue_draw()
+
+ def set_palette(self, palette):
+ self._palette = palette
+ self._palette.props.invoker = WidgetInvoker(self)
+ self._palette.props.invoker._position_hint = WidgetInvoker.AT_CURSOR
+
+class ImageRadioButton(gtk.RadioButton):
+
+ def __init__( self, group, mainImg_path, altImg_path, enterImg_path = None, backgroundFill = None ):
+ gtk.RadioButton.__init__(self, group)
+ self.alloc = None
+ self.within = False
+ self.clicked = False
+
+ win = gtk.gdk.get_default_root_window()
+ self.gc = gtk.gdk.GC( win )
+ self.image = {}
+ self.itype = {}
+ self.iwidth = {}
+ self.iwidthDIV2 = {}
+ self.iheight = {}
+ self.iheightDIV2 = {}
+
+ self.backgroundFill = backgroundFill
+
+ def prepareImage( name, path ):
+ pix = gtk.gdk.pixbuf_new_from_file(path)
+ if pix.get_has_alpha():
+ if backgroundFill == None:
+ self.image[name] = pix
+ self.itype[name] = ITYPE.PIXBUF
+ else:
+ self.image[name] = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ colormap = self.get_colormap()
+ self.gc.foreground = colormap.alloc_color( backgroundFill, True, True )
+ self.image[name].draw_rectangle( self.gc, True, 0, 0, pix.get_width(), pix.get_height() )
+ self.image[name].draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.itype[name] = ITYPE.PIXMAP
+ else:
+ self.image[name] = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ self.image[name].draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.itype[name] = ITYPE.PIXMAP
+ self.iwidth[name] = pix.get_width()
+ self.iwidthDIV2[name] = self.iwidth[name]//2
+ self.iheight[name] = pix.get_height()
+ self.iheightDIV2[name] = self.iheight[name]//2
+
+ prepareImage( "main", mainImg_path )
+ prepareImage( "alt", altImg_path )
+
+ if enterImg_path != None:
+ prepareImage( "enter", enterImg_path )
+ else:
+ self.image["enter"] = self.image["main"]
+ self.itype["enter"] = self.itype["main"]
+ self.iwidth["enter"] = self.iwidth["main"]
+ self.iwidthDIV2["enter"] = self.iwidthDIV2["main"]
+ self.iheight["enter"] = self.iheight["main"]
+ self.iheightDIV2["enter"] = self.iheightDIV2["main"]
+
+ self.connect('enter-notify-event',self.on_btn_enter)
+ self.connect('leave-notify-event',self.on_btn_leave)
+
+ self.connect("toggled", self.toggleImage )
+ self.connect('pressed',self.pressed )
+ self.connect('released',self.released )
+ self.connect('expose-event', self.expose)
+ self.connect('size-allocate', self.size_allocate)
+
+ self.set_size_request(self.iwidth["main"],self.iheight["main"])
+
+ self.toggleImage( self )
+
+ def size_allocate(self, widget, allocation):
+ self.alloc = allocation
+ self.drawX = allocation.x + allocation.width//2
+ self.drawY = allocation.y + allocation.height//2
+
+ def expose(self, widget, event):
+ if self.itype[self.curImage] == ITYPE.PIXBUF:
+ self.window.draw_pixbuf( self.gc, self.image[self.curImage], 0, 0, self.drawX - self.iwidthDIV2[self.curImage], self.drawY - self.iheightDIV2[self.curImage], self.iwidth[self.curImage], self.iheight[self.curImage], gtk.gdk.RGB_DITHER_NONE)
+ else:
+ self.window.draw_drawable( self.gc, self.image[self.curImage], 0, 0, self.drawX - self.iwidthDIV2[self.curImage], self.drawY - self.iheightDIV2[self.curImage], self.iwidth[self.curImage], self.iheight[self.curImage] )
+ return True
+
+ def setImage(self, name, pix):
+ if name == "main" and self.image["main"] == self.image["enter"]:
+ updateEnter = True
+ else:
+ updateEnter = False
+
+ if pix.get_has_alpha():
+ if self.backgroundFill == None:
+ self.image[name] = pix
+ self.itype[name] = ITYPE.PIXBUF
+ else:
+ self.image[name] = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ colormap = self.get_colormap()
+ self.gc.foreground = colormap.alloc_color( self.backgroundFill, True, True )
+ self.image[name].draw_rectangle( self.gc, True, 0, 0, pix.get_width(), pix.get_height() )
+ self.image[name].draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.itype[name] = ITYPE.PIXMAP
+ else:
+ self.image[name] = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ self.image[name].draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.itype[name] = ITYPE.PIXMAP
+ self.iwidth[name] = pix.get_width()
+ self.iwidthDIV2[name] = self.iwidth[name]//2
+ self.iheight[name] = pix.get_height()
+ self.iheightDIV2[name] = self.iheight[name]//2
+
+ if updateEnter:
+ self.image["enter"] = self.image["main"]
+ self.itype["enter"] = self.itype["main"]
+ self.iwidth["enter"] = self.iwidth["main"]
+ self.iwidthDIV2["enter"] = self.iwidthDIV2["main"]
+ self.iheight["enter"] = self.iheight["main"]
+ self.iheightDIV2["enter"] = self.iheightDIV2["main"]
+ self.connect('enter-notify-event',self.on_btn_enter)
+ self.connect('leave-notify-event',self.on_btn_leave)
+
+ self.queue_draw()
+
+ def toggleImage( self, widget ):
+ if not self.get_active():
+ if self.within and self.image.has_key("enter"):
+ self.curImage = "enter"
+ else:
+ self.curImage = "main"
+ else:
+ self.curImage = "alt"
+ self.queue_draw()
+
+ def pressed( self, widget ):
+ self.clicked = True
+ self.curImage = "alt"
+ self.queue_draw()
+
+ def released( self, widget ):
+ self.clicked = False
+ self.toggleImage( self )
+
+ def on_btn_enter(self, widget, event):
+ if event.mode == gtk.gdk.CROSSING_NORMAL:
+ self.within = True
+ if not self.get_active() and not self.clicked:
+ self.curImage = "enter"
+ else:
+ self.curImage = "alt"
+ self.queue_draw()
+
+ def on_btn_leave(self, widget, event):
+ if event.mode == gtk.gdk.CROSSING_NORMAL:
+ self.within = False
+ if not self.get_active():
+ self.curImage = "main"
+ else:
+ self.curImage = "alt"
+ self.queue_draw()
+
+ def set_palette(self, palette):
+ self._palette = palette
+ self._palette.props.invoker = WidgetInvoker(self)
+ self._palette.props.invoker._position_hint = WidgetInvoker.AT_CURSOR
+
+class keyButton(gtk.Button):
+ import cairo
+ def __init__(self, width, height, fillcolor, strokecolor):
+ gtk.Button.__init__(self)
+ self.alloc = None
+ win = gtk.gdk.get_default_root_window()
+ self.gc = gtk.gdk.GC(win)
+
+ self.connect('expose-event', self.expose)
+ self.connect('size-allocate', self.size_allocate)
+
+ self.width = width
+ self.height = height
+ self.fillcolor = fillcolor
+ self.strokecolor = strokecolor
+
+ self.set_size_request(self.width,self.height)
+
+ def size_allocate(self, widget, allocation):
+ self.alloc = allocation
+ self.drawX = allocation.x + allocation.width//2
+ self.drawY = allocation.y + allocation.height//2
+
+ def expose(self, widget, event):
+ self.draw()
+ return True
+
+ def draw(self):
+ self.cr = self.window.cairo_create()
+ self.cr.set_source_rgb(self.fillcolor[0],self.fillcolor[1],self.fillcolor[2])
+ self.draw_round_rect(self.cr,self.drawX - self.width//2, self.drawY - self.height //2, self.width,self.height,10)
+ self.cr.fill()
+ self.cr.set_line_width(3)
+ self.cr.set_source_rgb(self.strokecolor[0],self.strokecolor[1],self.strokecolor[2])
+ self.draw_round_rect(self.cr,self.drawX - self.width//2, self.drawY - self.height //2, self.width,self.height,10)
+ self.cr.stroke()
+
+ def draw_round_rect(self,context,x,y,w,h,r):
+ context.move_to(x+r,y) # Move to A
+ context.line_to(x+w-r,y) # Straight line to B
+ context.curve_to(x+w,y,x+w,y,x+w,y+r) # Curve to C, Control points are both at Q
+ context.line_to(x+w,y+h-r) # Move to D
+ context.curve_to(x+w,y+h,x+w,y+h,x+w-r,y+h) # Curve to E
+ context.line_to(x+r,y+h) # Line to F
+ context.curve_to(x,y+h,x,y+h,x,y+h-r) # Curve to G
+ context.line_to(x,y+r) # Line to H
+ context.curve_to(x,y,x,y,x+r,y) # Curve to A
+ return
+
+ def set_fillcolor(self,r,g,b):
+ self.fillcolor = [r,g,b]
+ self.queue_draw()
+
+ def set_strokecolor(self,r,g,b):
+ self.strokecolor = [r,g,b]
+ self.queue_draw()
+
+class BigComboBox(ComboBox):
+ def __init__(self):
+ ComboBox.__init__(self)
+
+ def append_item(self, action_id, text, icon_name=None, size = None):
+ if not self._icon_renderer and icon_name:
+ self._icon_renderer = gtk.CellRendererPixbuf()
+
+ settings = self.get_settings()
+ w, h = gtk.icon_size_lookup_for_settings(settings, gtk.ICON_SIZE_MENU)
+ self._icon_renderer.props.stock_size = w
+
+ self.pack_start(self._icon_renderer, False)
+ self.add_attribute(self._icon_renderer, 'pixbuf', 2)
+
+ if not self._text_renderer and text:
+ self._text_renderer = gtk.CellRendererText()
+ self.pack_end(self._text_renderer, True)
+ self.add_attribute(self._text_renderer, 'text', 1)
+
+ if icon_name:
+ if not size:
+ size = gtk.ICON_SIZE_LARGE_TOOLBAR
+ width, height = gtk.icon_size_lookup(size)
+ else:
+ width, height = size
+ if icon_name[0:6] == "theme:":
+ icon_name = self._get_real_name_from_theme(icon_name[6:], size)
+ pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(icon_name, width, height)
+ else:
+ pixbuf = None
+
+ self._model.append([action_id, text, pixbuf, False])
+
diff --git a/common/Util/Trackpad.py b/common/Util/Trackpad.py
new file mode 100644
index 0000000..0ddb929
--- /dev/null
+++ b/common/Util/Trackpad.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+import pygtk
+pygtk.require( '2.0' )
+import gtk
+import gobject
+
+from common.Util.CSoundClient import new_csound_client
+import common.Config as Config
+
+KEY_MAP_PIANO = Config.KEY_MAP_PIANO
+
+class Trackpad:
+ def __init__(self, win):
+ self.win = win
+ self.csnd = new_csound_client()
+ win.add_events(gtk.gdk.POINTER_MOTION_MASK)
+ win.add_events(gtk.gdk.BUTTON_PRESS_MASK)
+ win.add_events(gtk.gdk.BUTTON_RELEASE_MASK)
+ win.connect('motion-notify-event',self.handle_motion)
+ win.connect('key-press-event',self.handle_keyPress)
+ win.connect('key-release-event',self.handle_keyRelease)
+
+ self.first_x = None
+ self.current_x = None
+ self.final_x = None
+ self.first_y = None
+ self.current_y = None
+ self.final_y = None
+
+ self.buttonPressed = False
+
+ self.create_invisible_cursor()
+
+ self.display = self.win.get_display()
+ self.screen = gtk.gdk.Display.get_default_screen(self.display)
+ self.context = None
+
+ def setContext(self, context):
+ self.context = context
+
+ def create_invisible_cursor(self):
+ pix_data = """/* XPM */
+ static char * invisible_xpm[] = {
+ "1 1 1 1",
+ " c None",
+ " "};"""
+ color = gtk.gdk.Color()
+ pix = gtk.gdk.pixmap_create_from_data(None, pix_data, 1, 1, 1, color, color)
+ self.invisible_cursor = gtk.gdk.Cursor(pix,pix,color,color,0,0)
+
+ def handle_motion(self,widget,event):
+ if self.context != 'edit':
+ if event.x < 0:
+ X = 0
+ elif event.x > self.screen.get_width():
+ X = self.screen.get_width()
+ else:
+ X = event.x
+
+ if event.y < 0:
+ Y = 0
+ elif event.y > self.screen.get_height():
+ Y = self.screen.get_height()
+ else:
+ Y = event.y
+
+ self.current_x = X
+ self.current_y = Y
+ if self.buttonPressed:
+ self.final_x = X - self.first_x
+ self.final_y = Y - self.first_y
+ self.csnd.setTrackpadX(self.final_x)
+ self.csnd.setTrackpadY(self.final_y)
+
+ def handle_keyPress(self,widget,event):
+ if KEY_MAP_PIANO.has_key(event.hardware_keycode) and self.buttonPressed == False:
+ gtk.gdk.Display.warp_pointer(self.display, self.screen, self.screen.get_width() / 2, self.screen.get_height() / 2)
+ gtk.gdk.pointer_grab(self.win.window, event_mask = gtk.gdk.POINTER_MOTION_MASK)#, cursor = self.invisible_cursor)
+ self.buttonPressed = True
+ self.first_x = self.screen.get_width() / 2
+ self.first_y = self.screen.get_height() / 2
+
+ def handle_keyRelease(self,widget,event):
+ if KEY_MAP_PIANO.has_key(event.hardware_keycode):
+ gtk.gdk.pointer_ungrab(time = 0L)
+ self.buttonPressed = False
+ self.restoreDelay = gobject.timeout_add(120, self.restore)
+
+ def restore( self ):
+ self.csnd.setTrackpadX(0)
+ self.csnd.setTrackpadY(0)
+ gobject.source_remove( self.restoreDelay )
+
diff --git a/common/Util/__init__.py b/common/Util/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/common/Util/__init__.py
diff --git a/common/__init__.py b/common/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/common/__init__.py