Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/TamTamSynthLab.activity
diff options
context:
space:
mode:
authorNat <natcl@hotmail.com>2007-09-13 15:55:52 (GMT)
committer Nat <natcl@hotmail.com>2007-09-13 15:55:52 (GMT)
commite12dbff4dda5aafbaac98f75f0467ef00dc06c32 (patch)
tree52f74f5a699ca1a2827b333e76a7225b7d768256 /TamTamSynthLab.activity
parentb94ccdfd2329ed2d1128a4392e2f67b1e6b704da (diff)
Activity split
Diffstat (limited to 'TamTamSynthLab.activity')
-rw-r--r--TamTamSynthLab.activity/NEWS71
-rwxr-xr-xTamTamSynthLab.activity/SynthLab/SynthLabConstants.py374
-rw-r--r--TamTamSynthLab.activity/SynthLab/SynthLabToolbars.py170
-rw-r--r--TamTamSynthLab.activity/SynthLab/SynthLabWindow.py1395
-rwxr-xr-xTamTamSynthLab.activity/SynthLab/SynthObjectsParameters.py42
-rwxr-xr-xTamTamSynthLab.activity/SynthLab/__init__.py0
-rw-r--r--TamTamSynthLab.activity/TamTam.py1229
-rw-r--r--TamTamSynthLab.activity/activity/activity-tamtamsynthlab.svg12
-rw-r--r--TamTamSynthLab.activity/activity/activity.info6
l---------TamTamSynthLab.activity/common1
-rw-r--r--TamTamSynthLab.activity/icons/XYBut.svg14
-rw-r--r--TamTamSynthLab.activity/icons/XYButDown.svg14
-rw-r--r--TamTamSynthLab.activity/icons/XYButDownClick.svg12
-rwxr-xr-xTamTamSynthLab.activity/icons/accept.svg18
-rwxr-xr-xTamTamSynthLab.activity/icons/cancel.svg11
-rw-r--r--TamTamSynthLab.activity/icons/preset1.svg12
-rw-r--r--TamTamSynthLab.activity/icons/preset10.svg15
-rw-r--r--TamTamSynthLab.activity/icons/preset2.svg14
-rw-r--r--TamTamSynthLab.activity/icons/preset3.svg16
-rw-r--r--TamTamSynthLab.activity/icons/preset4.svg14
-rw-r--r--TamTamSynthLab.activity/icons/preset5.svg13
-rw-r--r--TamTamSynthLab.activity/icons/preset6.svg17
-rw-r--r--TamTamSynthLab.activity/icons/preset7.svg13
-rw-r--r--TamTamSynthLab.activity/icons/preset8.svg17
-rw-r--r--TamTamSynthLab.activity/icons/preset9.svg17
-rw-r--r--TamTamSynthLab.activity/icons/rec1.svg11
-rw-r--r--TamTamSynthLab.activity/icons/rec2.svg13
-rw-r--r--TamTamSynthLab.activity/icons/rec3.svg15
-rw-r--r--TamTamSynthLab.activity/icons/rec4.svg13
-rw-r--r--TamTamSynthLab.activity/icons/rec5.svg14
-rw-r--r--TamTamSynthLab.activity/icons/rec6.svg15
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-addSynth+.svg30
-rw-r--r--TamTamSynthLab.activity/icons/sl-addSynth-menu.svg15
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-adsr+.svg21
-rw-r--r--TamTamSynthLab.activity/icons/sl-adsr-menu.svg20
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-buzz+.svg30
-rw-r--r--TamTamSynthLab.activity/icons/sl-buzz-menu.svg15
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-chorus+.svg139
-rw-r--r--TamTamSynthLab.activity/icons/sl-chorus-menu.svg101
-rw-r--r--TamTamSynthLab.activity/icons/sl-distort+.svg30
-rw-r--r--TamTamSynthLab.activity/icons/sl-distort-menu.svg21
-rw-r--r--TamTamSynthLab.activity/icons/sl-eq4band+.svg51
-rw-r--r--TamTamSynthLab.activity/icons/sl-eq4band-menu.svg38
-rw-r--r--TamTamSynthLab.activity/icons/sl-filter+.svg32
-rw-r--r--TamTamSynthLab.activity/icons/sl-filter-menu.svg21
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-fm+.svg43
-rw-r--r--TamTamSynthLab.activity/icons/sl-fm-menu.svg30
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-grain+.svg205
-rw-r--r--TamTamSynthLab.activity/icons/sl-grain-menu.svg190
-rw-r--r--TamTamSynthLab.activity/icons/sl-harmon+.svg30
-rw-r--r--TamTamSynthLab.activity/icons/sl-harmon-menu.svg21
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-lfo+.svg14
-rw-r--r--TamTamSynthLab.activity/icons/sl-lfo-menu.svg20
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-noise+.svg233
-rw-r--r--TamTamSynthLab.activity/icons/sl-noise-menu.svg222
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-pluck+.svg73
-rw-r--r--TamTamSynthLab.activity/icons/sl-pluck-menu.svg62
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-rand+.svg17
-rw-r--r--TamTamSynthLab.activity/icons/sl-rand-menu.svg20
-rw-r--r--TamTamSynthLab.activity/icons/sl-reset.svg13
-rw-r--r--TamTamSynthLab.activity/icons/sl-reverb+.svg39
-rw-r--r--TamTamSynthLab.activity/icons/sl-reverb-menu.svg28
-rw-r--r--TamTamSynthLab.activity/icons/sl-ring+.svg30
-rw-r--r--TamTamSynthLab.activity/icons/sl-ring-menu.svg21
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-sample+.svg34
-rw-r--r--TamTamSynthLab.activity/icons/sl-sample-menu.svg24
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-speaker.svg13
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-trackpadX+.svg22
-rw-r--r--TamTamSynthLab.activity/icons/sl-trackpadX-menu.svg21
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-trackpadY+.svg22
-rw-r--r--TamTamSynthLab.activity/icons/sl-trackpadY-menu.svg21
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-vco+.svg31
-rw-r--r--TamTamSynthLab.activity/icons/sl-vco-menu.svg19
-rwxr-xr-xTamTamSynthLab.activity/icons/sl-voice+.svg28
-rw-r--r--TamTamSynthLab.activity/icons/sl-voice-menu.svg21
-rw-r--r--TamTamSynthLab.activity/icons/sl-wguide+.svg32
-rw-r--r--TamTamSynthLab.activity/icons/sl-wguide-menu.svg25
-rw-r--r--TamTamSynthLab.activity/icons/tam-help.svg18
-rw-r--r--TamTamSynthLab.activity/setup.py21
79 files changed, 5825 insertions, 0 deletions
diff --git a/TamTamSynthLab.activity/NEWS b/TamTamSynthLab.activity/NEWS
new file mode 100644
index 0000000..8120a07
--- /dev/null
+++ b/TamTamSynthLab.activity/NEWS
@@ -0,0 +1,71 @@
+39
+
+* New activity : TamTamJam (lync)
+* Activities are now separate (TamTamJam, TamTamEdit, TamTamSynthLab)
+* No sound when set to language other than english fixed (#3165) (J5, marcopg, tomeu, Flipo)
+
+38
+
+* Adapt to new Palette API (Flipo)
+
+37
+
+* Small layout change in edit (Flipo)
+* Temporary fix for Palettes causing the audio to stop (Flipo)
+
+36
+
+* Major image cleanup, 700k saved (Flipo)
+* Tune generation back (see leftmost icon on generate tab) (Olipet)
+
+35
+
+* TamTam Edit Toolbars enhancements (Flipo, Olipet)
+* TamTam Edit layout changes (lync)
+* Dual instruments for tracks in Edit (Olipet, lync)
+
+34
+
+* Synthlab sugar integration (olipet, Flipo)
+* Toolbars in edit draft, hit alt-t to show the toolbar, alt-y to hide (Flipo)
+* Bug that prevented sound from working fixed (LeJames)
+
+33
+
+* Added Sugar Toolbar to miniTamTam and Synthlab (Flipo)
+* Network now working in miniTamTam, use the share button on the activity toolbar (lync)
+* Added help subsystem (ethrop, LeJames)
+
+32
+
+* Important microphone fix (Olipet)
+
+31
+
+* Working network (create a FORCE_SHARE file in the / dir) (lync)
+* New tune generator in Edit, click the dice in the tune view (Olipet)
+* Fine tuning of the algorythmic generator and orchestras (Olipet)
+* TamTamJam (miniTamTam) integration with the journal (Flipo)
+* Title according to subactivity displayed in the journal (Flipo)
+
+30
+
+* Clicking the close button in Edit and Synthlab goes back to Sugar. (Flipo)
+* Fix to the Journal load and save. (Flipo, lync)
+* Ogg player on the welcome page. (lync)
+* Demo tune instruments and tempo are randomly generated (Olipet)
+* lab placeholder files were reduced in size by 95% (Olipet)
+
+29
+
+* WelcomeScreen: Removed Typing Game icon. (Flipo)
+* General: Added sounds. (ethrop, Olipet)
+* General: Journal integration. (Flipo, lync)
+* TamTamJam: Microphone semi-working. (James)
+* TamTamEdit: Beats per page setting. (lync, Olipet)
+* TamTamEdit: Mute/Solo controls on tracks. (Flipo)
+* TamTamEdit: Paint tool. (Olipet)
+* TamTamEdit: Properties automation. (Olipet)
+* TamTamEdit: Pages can have different colors. (lync)
+* TamTamEdit: Realtime keyboard recording. (Olipet)
+* TamTamEdit: Export song to ogg file. (Olipet) \ No newline at end of file
diff --git a/TamTamSynthLab.activity/SynthLab/SynthLabConstants.py b/TamTamSynthLab.activity/SynthLab/SynthLabConstants.py
new file mode 100755
index 0000000..a16ffe3
--- /dev/null
+++ b/TamTamSynthLab.activity/SynthLab/SynthLabConstants.py
@@ -0,0 +1,374 @@
+from gettext import gettext as _
+
+class SynthLabConstants:
+
+ PIC_SIZE = 80
+ HALF_SIZE = PIC_SIZE // 2
+ PIC_SIZE_HIGHLIGHT = PIC_SIZE + 4
+
+ GT_CONTROL_OUTPUT = 0
+ GT_CONTROL_INPUT = 1
+ GT_SOUND_OUTPUT = 2
+ GT_SOUND_INPUT = 3
+ # GATE_POINT[objecttype][gatetype][gatenum] = (x,y)
+ # relative to object center
+ GATE_POINT = [ [ [ (-1,33) ] ],
+ [ [], [ (-24,-34),(-9,-34),(8,-34),(24,-34) ], [ (-1,33) ] ],
+ [ [], [ (31,-20),(31,-6),(31,6),(31,19) ], [ (-3,33) ], [ (-3,-34) ] ],
+ [ [], [], [], [ (2,-35) ] ] ]
+ # GATE_MAP[objecttype][gatetype][gatenum] = [ sx, sy, ex, ey, (wireX,wireY) ]
+ # gate locations relative to object center
+ GATE_MAP = [ [ [ [-7,26,4,39] ] ],
+ [ [], [[-30,-40,-19,-28], [-15,-40,-3,-28], [3,-40,14,-28], [19,-40,28,-28]], [[-6,28,5,40]] ],
+ [ [], [[25,-25,37,-14], [25,-12,37,-1], [25,1,37,12], [25,13,37,25]], [[-8,27,3,40]], [[-8,-40,3,-27]] ],
+ [ [], [], [], [[-4,-40,7,-29]] ] ]
+ # insert wire locations into map
+ GATE_OFFSET = 15
+ for oT in GATE_MAP:
+ for gT in oT:
+ for m in gT:
+ x = (m[2]+m[0])//2
+ y = (m[3]+m[1])//2
+ # snap to edges
+ if x < -HALF_SIZE+GATE_OFFSET: x = m[0]
+ elif x > HALF_SIZE-GATE_OFFSET: x = m[2]
+ if y < -HALF_SIZE+GATE_OFFSET: y = m[1]
+ elif y > HALF_SIZE-GATE_OFFSET: y = m[3]
+ m.append( ( x, y ) )
+
+ OBJ_Y_LOC = 710
+ INIT_LOCATIONS = [ [450,OBJ_Y_LOC], [450,OBJ_Y_LOC], [450,OBJ_Y_LOC],
+ [450, OBJ_Y_LOC], [225,OBJ_Y_LOC], [225,OBJ_Y_LOC],
+ [225,OBJ_Y_LOC], [225, OBJ_Y_LOC], [675,OBJ_Y_LOC],
+ [675,OBJ_Y_LOC], [675,OBJ_Y_LOC], [675, OBJ_Y_LOC],
+ [450, 625]]
+
+ FLOAT1 = [.1, 1]
+ FLOAT = [.01, 2]
+ INTEGER = [1, 0]
+
+ # s1 s2 s3 s4 s1min s1max s2min s2max s3min s3max s4min s4max [s1step s1digits] [s2step s2digits] [s3step s3digits]
+ TYPES = { 'lfo': [.5, 1, 0, 0, 0, 1, 0, 20, 0, 5, 0, 1, FLOAT, FLOAT, INTEGER],
+ 'rand': [.5, 1.5, 2, 0, 0, 2, 0, 2, 0, 20, 0, 1, FLOAT, FLOAT, FLOAT],
+ 'adsr': [.02, .05, .8, .1, 0, 1, 0, 1, 0, 1, 0, 1, FLOAT, FLOAT, FLOAT],
+ 'trackpadX': [0, 1, 0, 0, -1, 1, 0, 2, 0, 1, 0, 1, FLOAT, FLOAT, INTEGER],
+ 'trackpadY': [0, 1, 0, 0, -1, 1, 0, 2, 0, 1, 0, 1, FLOAT, FLOAT, INTEGER],
+ 'fm': [1, .5, 5, 1, 0, 2, 0, 2, 0, 10, 0, 2, FLOAT, FLOAT, FLOAT],
+ 'buzz': [1, 30, .85, 1, 0, 2, 0, 40, 0, 1, 0, 2, FLOAT, INTEGER, FLOAT],
+ 'vco': [1, 1, .2, 1, 0, 2, 0, 2, 0, .5, 0, 2, FLOAT, INTEGER, FLOAT],
+ 'pluck': [1, 5000, 0, 1, 0, 2, 100, 8000, 0, 8, 0, 2, FLOAT, INTEGER, FLOAT],
+ 'noise': [0, 3000, 4000, 1, 0, 2, 0, 8000, 0, 6000, 0, 2, INTEGER, INTEGER,INTEGER],
+ 'sample': [1, 5, 5000, 1, 0, 2, 0, 99, 100, 8000, 0, 2, FLOAT, INTEGER, INTEGER],
+ 'voice': [1, 3, 5, 1, 0, 2, 0, 8, 1, 10, 0, 2, FLOAT, INTEGER, FLOAT],
+ 'grain': [1, 4, 1, 1, 0, 2, 0, 99, 0, 1, 0, 2, FLOAT, INTEGER, FLOAT],
+ 'addSynth': [1, .005, 5, 1, 0, 2, 0, 20, 0, 9, 0, 2, FLOAT, FLOAT, INTEGER],
+ 'wguide': [100, 3000, .8, 1, 0, 200, 100, 5000, 0, 1, 0, 2, FLOAT1, INTEGER, FLOAT],
+ 'distort': [800, .7, .7, 1, 0, 1000, 0, 1, 0, 1, 0, 2, INTEGER, FLOAT, FLOAT],
+ 'filter': [1000, .6, 0, 1, 200, 5000, 0, 1, 0, 2, 0, 2, INTEGER, FLOAT, INTEGER],
+ 'ring': [500, 1, 0, 1, 0, 1000, 0, 1, 0, 5, 0, 2, INTEGER, FLOAT, INTEGER],
+ 'reverb': [1.5, 3000, .5, 1, 0, 4, 100, 7000, 0, 1, 0, 2, FLOAT, INTEGER, FLOAT],
+ 'harmon': [1.25, .04, .5, 1, 0, 2, 0, 1, 0, 1, 0, 2, FLOAT, FLOAT, FLOAT],
+ 'eq4band': [1., 1., 1., 1., 0, 2, 0, 2, 0, 2, 0, 2, FLOAT, FLOAT, FLOAT],
+ 'chorus': [.5, 1., 5., .5, 0, 3, 0, 10, 0, 30, 0, 1, FLOAT, FLOAT, FLOAT]}
+
+ CONTROL_TYPES = ['lfo', 'rand', 'adsr', 'trackpadX', 'trackpadY']
+ CONTROL_TYPES_SEL = [type + 'sel' for type in CONTROL_TYPES]
+ CONTROL_TYPES_PLUS = [type + '+' for type in CONTROL_TYPES]
+ SOURCE_TYPES = ['fm', 'buzz', 'vco', 'pluck', 'noise', 'sample', 'voice', 'grain', 'addSynth']
+ SOURCE_TYPES_SEL = [type + 'sel' for type in SOURCE_TYPES]
+ SOURCE_TYPES_PLUS = [type + '+' for type in SOURCE_TYPES]
+ FX_TYPES = ['wguide', 'distort','filter', 'ring', 'reverb', 'harmon', 'eq4band', 'chorus']
+ FX_TYPES_SEL = [type + 'sel' for type in FX_TYPES]
+ FX_TYPES_PLUS = [type + '+' for type in FX_TYPES]
+ OUTPUT_TYPE = ['adsr']
+ OUTPUT_TYPE_SEL = ['adsrsel']
+ CHOOSE_TYPE = [CONTROL_TYPES, SOURCE_TYPES, FX_TYPES, OUTPUT_TYPE]
+ CHOOSE_TYPE2 = [CONTROL_TYPES_SEL, SOURCE_TYPES_SEL, FX_TYPES_SEL, OUTPUT_TYPE_SEL]
+ CHOOSE_TYPE_PLUS = [CONTROL_TYPES_PLUS, SOURCE_TYPES_PLUS, FX_TYPES_PLUS]
+
+# SynthLab Tooltips
+ SOURCE = _('Source')
+ EFFECT = _('Effect')
+ CONTROL = _('Control')
+ SOUNDOUT = _('Sound Output')
+
+ #Controls
+ LFO = _('LFO')
+ AMP = _('Amplitude')
+ FREQ = _('Frequency')
+ WAVEFORM = _('Waveform')
+ LFO_WAVEFORMS = [_('Sine'), _('Triangle'), _('Bi-Square'), _('Uni-Square'), _('Sawtooth'), _('Sawtooth-down')]
+ OFFSET = _('Offset')
+ LFO_INFO = _('A low frequency oscillation (LFO) is a signal usually below 20 Hz which creates a pulsating rythm rather than a audible tone. This signal is commonly used to control sound parameters.')
+ LFO_PARA1 = _('The amplitude (volume) of the LFO signal. More amplitude means the effect will be more noticeable.')
+ LFO_PARA2 = _('The speed of the signal beteen 0 Hz and 20 hz.')
+ LFO_PARA3 = _('The type of waveform that will be used for the LFO.')
+ LFO_PARA4 = _('Offset: ')
+
+ RANDOM = _('Random')
+ MIN = _('Minimum')
+ MAX = _('Maximum')
+ FREQ = FREQ
+ SEED = _('Seed')
+ RANDOM_INFO = _('A random number generator is a computational device designed to generate a sequence of numbers that lack any pattern.')
+ RANDOM_PARA1 = _('')
+ RANDOM_PARA2 = _('The minimum value that can be generated.')
+ RANDOM_PARA3 = _('The maximum value that can be generated.')
+ RANDOM_PARA4 = _('')
+
+ ADSR = _('Envelope')
+ ATTACK = _('Attack')
+ DECAY = _('Decay')
+ SUSTAIN = _('Sustain')
+ RELEASE = _('Release')
+ ADSR_INFO = _("An ADSR envelope is a component of many sythesizers, samplers, and other electronic musical instruments. Its function is to modulate some aspect of the instrument's sound - often its volume - over time.")
+ ADSR_PARA1 = _('How quickly the sound reaches full volume after the sound is activated.')
+ ADSR_PARA2 = _('How quickly the sound drops to the sustain level after the initial peak.')
+ ADSR_PARA3= _('The "constant" volume that the sound takes after decay until the note is released.')
+ ADSR_PARA4 = _('How quickly the sound fades when a note ends.')
+
+ TRACKPADX = _('Trackpad X')
+ MIN = MIN
+ MAX = MAX
+ SCALING = _('Scaling')
+ SCALING_TYPES = [_('Lin'), _('Log')]
+ POLL = _('Poll time')
+ TRACKPADX_INFO = _('The XO trackpad can be used to control sound parameters. This is the x axis, from left to right.')
+ TRACKPADX_PARA1 = _('The minimum value the trackpad will send.')
+ TRACKPADX_PARA2 = _('The maximum value de trackpad will send.')
+ TRACKPADX_PARA3 = _('The type of scaling, logarithmic or linear.')
+ TRACKPADX_PARA4= _('The time interval between each event coming from the trackpad.')
+
+ TRACKPADY = _('Trackpad Y')
+ MIN = MIN
+ MAX = MAX
+ SCALING = SCALING
+ SCALING_TYPES = SCALING_TYPES
+ POLL = POLL
+ TRACKPADY_INFO = _('The XO trackpad can be used to control sound parameters. This is the y axis, from top to bottom.')
+ TRACKPADY_PARA1 = _('The minimum value the trackpad will send.')
+ TRACKPADY_PARA2 = _('The maximum value de trackpad will send.')
+ TRACKPADY_PARA3 = _('The type of scaling, logarithmic or linear.')
+ TRACKPADY_PARA4 = _('The time interval between each event coming from the trackpad.')
+
+ #Source
+ FM = _('FM')
+ CAR = _('Carrier Frequency')
+ MOD = _('Modulator Frequency')
+ INDEX = _('Index')
+ GAIN = _('Gain')
+ FM_INFO = _('Frequency modulation synthesis is a form of audio synthesis where the timbre of a simple waveform is changed by frequency modulating it with a modulating frequency that is also in the audio range, resulting in a more complex waveform and a different-sounding tone.')
+ FM_PARA1 = _('The main waveform frequency.')
+ FM_PARA2 = _('The frequency of the waveform that will modulate the Carrier waveform.')
+ FM_PARA3 = _('The variation in frequency of the Carrier waveform.')
+ FM_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ BUZZ = _('Buzz')
+ FREQ = FREQ
+ NHARM = _('Number of harmonics')
+ FSLOPE = _('Filter Slope')
+ GAIN = GAIN
+ BUZZ_INFO = _('')
+ BUZZ_PARA1 = _('')
+ BUZZ_PARA2 = _('')
+ BUZZ_PARA3 = _('')
+ BUZZ_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ VCO = _('VCO')
+ FREQ = FREQ
+ WAVEFORM = WAVEFORM
+ VCO_WAVEFORMS = [_('Sawtooth'), _('Square'), _('Triangle')]
+ FSLOPE = FSLOPE
+ GAIN = GAIN
+ VCO_INFO = _('')
+ VCO_PARA1 = _('')
+ VCO_PARA2 = _('')
+ VCO_PARA3 = _('')
+ VCO_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ PLUCK = _('Pluck')
+ FREQ = FREQ
+ LFILTER = _('Lowpass Filter')
+ VIBRATO = _('Vibrato')
+ GAIN = GAIN
+ PLUCK_INFO = _('')
+ PLUCK_PARA1 = _('')
+ PLUCK_PARA2 = _('')
+ PLUCK_PARA3 = _('')
+ PLUCK_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ NOISE = _('Noise')
+ NOISETYPE = _('Type')
+ NOISE_TYPES = [_('White'), _('Pink'), _('Gauss')]
+ FREQ = FREQ
+ BANDWITH = _('Bandwith')
+ GAIN = GAIN
+ NOISE_INFO = _('')
+ NOISE_PARA1 = _('')
+ NOISE_PARA2 = _('')
+ NOISE_PARA3 = _('')
+ NOISE_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ SAMPLE = _('Sound Sample')
+ FREQ = FREQ
+ SAMPLEN = _('Sample Number')
+ SAMPLE_NAMES = _('Sample name')
+ LFILTER = LFILTER
+ GAIN = GAIN
+ SAMPLE_INFO = _('')
+ SAMPLE_PARA1 = _('')
+ SAMPLE_PARA2 = _('')
+ SAMPLE_PARA3 = _('')
+ SAMPLE_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ VOICE = _('Voice')
+ FREQ = FREQ
+ VOWEL = _('Vowel')
+ VOWEL_TYPES = ['i', 'e', 'ee', 'a', 'u', 'o1', 'o2', 'oa', 'oe']
+ VIBRATO = VIBRATO
+ GAIN = GAIN
+ VOICE_INFO = _('')
+ VOICE_PARA1 = _('')
+ VOICE_PARA2 = _('')
+ VOICE_PARA3 = _('')
+ VOICE_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ GRAIN = _('Grain')
+ FREQ = FREQ
+ SAMPLEN = SAMPLEN
+ INDEX = _('Index')
+ GAIN = GAIN
+ GRAIN_INFO = _('')
+ GRAIN_PARA1 = _('')
+ GRAIN_PARA2 = _('')
+ GRAIN_PARA3 = _('')
+ GRAIN_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ ADDSYNTH = _('Additive Synthesis')
+ FREQ = FREQ
+ SPREAD = _('Spread')
+ WAVE = _('Waveform')
+ GAIN = GAIN
+ ADDSYNTH_INFO = _('')
+ ADDSYNTH_PARA1 = _('')
+ ADDSYNTH_PARA2 = _('')
+ ADDSYNTH_PARA3 = _('')
+ ADDSYNTH_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ #Effects
+ DELAY = _('Delay')
+ FREQ = FREQ
+ LFILTER = LFILTER
+ FEEDBACK = _('Feedback')
+ GAIN = GAIN
+ DELAY_INFO = _('')
+ DELAY_PARA1 = _('')
+ DELAY_PARA2 = _('')
+ DELAY_PARA3 = _('')
+ DELAY_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ DIST = _('Distortion')
+ FREQ = FREQ
+ RESON = _('Resonance')
+ DISTL = _('Distotion Level')
+ GAIN = GAIN
+ DIST_INFO = _('')
+ DIST_PARA1 = _('')
+ DIST_PARA2 = _('')
+ DIST_PARA3 = _('')
+ DIST_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ FILTER = _('Filter')
+ FREQ = FREQ
+ FSLOPE = FSLOPE
+ FTYPE = _('Type')
+ FILTER_TYPES = [_('Lowpass'), _('Highpass'), _('Bandpass')]
+ GAIN = GAIN
+ FILTER_INFO = _('')
+ FILTER_PARA1 = _('')
+ FILTER_PARA2 = _('')
+ FILTER_PARA3 = _('')
+ FILTER_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ RINGMOD = _('Ring Modulator')
+ FREQ = FREQ
+ MIX = _('Mix')
+ WAVEFORM = WAVEFORM
+ LFO_WAVEFORMS = LFO_WAVEFORMS
+ GAIN = GAIN
+ RINGMOD_INFO = _('')
+ RINGMOD_PARA1 = _('')
+ RINGMOD_PARA2 = _('')
+ RINGMOD_PARA3 = _('')
+ RINGMOD_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ REVERB = _('Reverb')
+ REVERBD = _('Length')
+ REVERBF = _('Lowpass Filter')
+ REVERBL = _('Reverb Level')
+ GAIN = GAIN
+ REVERB_INFO = _('Reverberation is the persistence od sound in a particular space after the original sound is removed.')
+ REVERB_PARA1 = _('')
+ REVERB_PARA2 = _('')
+ REVERB_PARA3 = _('')
+ REVERB_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ HARMON = _('Harmonizer')
+ FREQ = FREQ
+ DRYDELAY = _('Dry delay')
+ MIX = MIX
+ GAIN = GAIN
+ HARMON_INFO = _('')
+ HARMON_PARA1 = _('')
+ HARMON_PARA2 = _('')
+ HARMON_PARA3 = _('')
+ HARMON_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ EQ4BAND = _('Equalizer 4 bands')
+ FREQ1 = _('Band one gain')
+ FREQ2 = _('Band two gain')
+ FREQ3 = _('Band three gain')
+ FREQ4 = _('Band four gain')
+ EQ4BAND_INFO = _('A 4 band equalizer is an effect that splits the spectrum into 4 bands and allows the bands to be set at different levels.')
+ EQ4BAND_PARA1 = _('The gain (volume) of band 1.')
+ EQ4BAND_PARA2 = _('The gain (volume) of band 2.')
+ EQ4BAND_PARA3 = _('The gain (volume) of band 3.')
+ EQ4BAND_PARA4 = _('The gain (volume) of band 4.')
+
+ CHORUS = _('Chorus')
+ LFODEPTH = _('LFO Depth')
+ LFOFREQ = _('LFO Frequency')
+ DELAY = _('Delay')
+ FEEDBACK = FEEDBACK
+ CHORUS_INFO = _('A chorus effect is a condition in the way people perceive similar sounds coming from multiple sources.')
+ CHORUS_PARA1 = _('LFO Depth: The amplitude of the LFO signal.')
+ CHORUS_PARA2 = _('LFO Frequency: the frequency of the LFO signal.')
+ CHORUS_PARA3 = _('Delay: The amount of delay between the two signals.')
+ CHORUS_PARA4 = _('The overall gain (volume) of the sound source.')
+
+ SYNTHTYPES = [[LFO, RANDOM, ADSR, TRACKPADX, TRACKPADY],
+ [FM, BUZZ, VCO, PLUCK, NOISE, SAMPLE, VOICE, GRAIN, ADDSYNTH],
+ [DELAY, DIST, FILTER, RINGMOD, REVERB, HARMON, EQ4BAND, CHORUS], [ADSR]]
+
+ SYNTHPARA = { _('lfo'): [AMP, FREQ, WAVEFORM, OFFSET, LFO_INFO, LFO_PARA1, LFO_PARA2, LFO_PARA3, LFO_PARA4],
+ _('rand'): [MIN, MAX, FREQ, SEED, RANDOM_INFO, RANDOM_PARA1, RANDOM_PARA2, RANDOM_PARA3, RANDOM_PARA4],
+ _('adsr'): [ATTACK, DECAY, SUSTAIN, RELEASE, ADSR_INFO, ADSR_PARA1, ADSR_PARA2, ADSR_PARA3, ADSR_PARA4],
+ _('trackpadX'): [MIN, MAX, SCALING, POLL, TRACKPADX_INFO, TRACKPADX_PARA1, TRACKPADX_PARA2, TRACKPADX_PARA3, TRACKPADX_PARA4],
+ _('trackpadY'): [MIN, MAX, SCALING, POLL, TRACKPADY_INFO, TRACKPADY_PARA1, TRACKPADY_PARA2, TRACKPADY_PARA3, TRACKPADY_PARA4],
+ _('fm'): [CAR, MOD, INDEX, GAIN, FM_INFO, FM_PARA1, FM_PARA2, FM_PARA3, FM_PARA4],
+ _('buzz'): [FREQ, NHARM, FSLOPE, GAIN, BUZZ_INFO, BUZZ_PARA1, BUZZ_PARA2, BUZZ_PARA3, BUZZ_PARA4],
+ _('vco'): [FREQ, WAVEFORM, FSLOPE, GAIN, VCO_INFO, VCO_PARA1, VCO_PARA2, VCO_PARA3, VCO_PARA4],
+ _('pluck'): [FREQ, LFILTER, VIBRATO, GAIN, PLUCK_INFO, PLUCK_PARA1, PLUCK_PARA2, PLUCK_PARA3, PLUCK_PARA4],
+ _('noise'): [NOISETYPE, FREQ, BANDWITH, GAIN, NOISE_INFO, NOISE_PARA1, NOISE_PARA2, NOISE_PARA3, NOISE_PARA4],
+ _('sample'): [FREQ, SAMPLEN, LFILTER, GAIN, SAMPLE_INFO, SAMPLE_PARA1, SAMPLE_PARA2, SAMPLE_PARA3, SAMPLE_PARA4],
+ _('voice'): [FREQ, VOWEL, VIBRATO, GAIN, VOICE_INFO, VOICE_PARA1, VOICE_PARA2, VOICE_PARA3, VOICE_PARA4],
+ _('grain'): [FREQ, SAMPLEN, INDEX, GAIN, GRAIN_INFO, GRAIN_PARA1, GRAIN_PARA2, GRAIN_PARA3, GRAIN_PARA4],
+ _('addSynth'): [FREQ, SPREAD, WAVE, GAIN, ADDSYNTH_INFO, ADDSYNTH_PARA1, ADDSYNTH_PARA2, ADDSYNTH_PARA3, ADDSYNTH_PARA4],
+ _('wguide'): [FREQ, LFILTER, FEEDBACK, GAIN, DELAY_INFO, DELAY_PARA1, DELAY_PARA2, DELAY_PARA3, DELAY_PARA4],
+ _('distort'): [FREQ, RESON, DISTL, GAIN, DIST_INFO, DIST_PARA1, DIST_PARA2, DIST_PARA3, DIST_PARA4],
+ _('filter'): [FREQ, FSLOPE, FTYPE, GAIN, FILTER_INFO, FILTER_PARA1, FILTER_PARA2, FILTER_PARA3, FILTER_PARA4],
+ _('ring'): [FREQ, MIX, WAVEFORM, GAIN, RINGMOD_INFO, RINGMOD_PARA1, RINGMOD_PARA2, RINGMOD_PARA3, RINGMOD_PARA4],
+ _('reverb'): [REVERBD, REVERBF, REVERBL, GAIN, REVERB_INFO, REVERB_PARA1, REVERB_PARA2, REVERB_PARA3, REVERB_PARA4],
+ _('harmon'): [FREQ, DRYDELAY, MIX, GAIN, HARMON_INFO, HARMON_PARA1, HARMON_PARA2, HARMON_PARA3, HARMON_PARA4],
+ _('eq4band'): [FREQ1, FREQ2, FREQ3, FREQ4, EQ4BAND_INFO, EQ4BAND_PARA1, EQ4BAND_PARA2, EQ4BAND_PARA3, EQ4BAND_PARA4],
+ _('chorus'): [LFODEPTH, LFOFREQ, DELAY, FEEDBACK, CHORUS_INFO, CHORUS_PARA1, CHORUS_PARA2, CHORUS_PARA3, CHORUS_PARA4]}
diff --git a/TamTamSynthLab.activity/SynthLab/SynthLabToolbars.py b/TamTamSynthLab.activity/SynthLab/SynthLabToolbars.py
new file mode 100644
index 0000000..8b535eb
--- /dev/null
+++ b/TamTamSynthLab.activity/SynthLab/SynthLabToolbars.py
@@ -0,0 +1,170 @@
+#!/usr/bin/env python
+
+import gtk
+import Config
+
+from sugar.graphics.toolbutton import ToolButton
+from sugar.graphics.toggletoolbutton import ToggleToolButton
+from sugar.graphics.radiotoolbutton import RadioToolButton
+from gettext import gettext as _
+
+class mainToolbar(gtk.Toolbar):
+ def __init__(self,toolbox, synthLab):
+ gtk.Toolbar.__init__(self)
+
+ def _insertSeparator(x = 1):
+ for i in range(x):
+ self.separator = gtk.SeparatorToolItem()
+ self.separator.set_draw(False)
+ self.insert(self.separator,-1)
+ self.separator.show()
+
+ self.toolbox = toolbox
+ self.synthLab = synthLab
+
+ self.tooltips = gtk.Tooltips()
+
+ self.durationSliderLabel = gtk.Label(_('Duration: '))
+ self.durationSliderLabelTool = gtk.ToolItem()
+ self.durationSliderLabelTool.add(self.durationSliderLabel)
+ self.durationSliderLabelSecond = gtk.Label(_(' s.'))
+ self.durationSliderLabelSecondTool = gtk.ToolItem()
+ self.durationSliderLabelSecondTool.add(self.durationSliderLabelSecond)
+ self.durationSliderAdj = gtk.Adjustment(2, .5, 10, .01, .01, 0)
+ self.durationSliderAdj.connect("value_changed" , self.synthLab.handleDuration)
+ self.durationSlider = gtk.HScale(adjustment = self.durationSliderAdj)
+ self.durationSlider.set_size_request(250,15)
+ self.durationSlider.set_inverted(False)
+ self.durationSlider.set_value_pos(gtk.POS_RIGHT)
+ self.durationSliderTool = gtk.ToolItem()
+ self.durationSliderTool.add(self.durationSlider)
+ self.insert(self.durationSliderLabelTool, -1)
+ self.insert(self.durationSliderTool, -1)
+ self.insert(self.durationSliderLabelSecondTool, -1)
+ self.durationSliderLabelTool.show()
+ self.durationSliderLabel.show()
+ self.durationSliderLabelSecondTool.show()
+ self.durationSliderLabelSecond.show()
+ self.durationSlider.show()
+ self.durationSliderTool.show()
+ self.durationSliderTool.set_tooltip(self.tooltips, _('Duration'))
+
+ _insertSeparator(1)
+
+ self.synthRec1Button = ToggleToolButton('rec1')
+ self.synthRec1Button.connect('clicked',self.synthLab.recordSound,1)
+ self.insert(self.synthRec1Button, -1)
+ self.synthRec1Button.show()
+ self.synthRec1Button.set_tooltip(_('Record Synth sound into slot 1'))
+
+ self.synthRec2Button = ToggleToolButton('rec2')
+ self.synthRec2Button.connect('clicked',self.synthLab.recordSound,2)
+ self.insert(self.synthRec2Button, -1)
+ self.synthRec2Button.show()
+ self.synthRec2Button.set_tooltip(_('Record Synth sound into slot 2'))
+
+ self.synthRec3Button = ToggleToolButton('rec3')
+ self.synthRec3Button.connect('clicked',self.synthLab.recordSound,3)
+ self.insert(self.synthRec3Button, -1)
+ self.synthRec3Button.show()
+ self.synthRec3Button.set_tooltip(_('Record Synth sound into slot 3'))
+
+ self.synthRec4Button = ToggleToolButton('rec4')
+ self.synthRec4Button.connect('clicked',self.synthLab.recordSound,4)
+ self.insert(self.synthRec4Button, -1)
+ self.synthRec4Button.show()
+ self.synthRec4Button.set_tooltip(_('Record Synth sound into slot 4'))
+
+ self.synthRec5Button = ToggleToolButton('rec5')
+ self.synthRec5Button.connect('clicked',self.synthLab.recordSound,5)
+ self.insert(self.synthRec5Button, -1)
+ self.synthRec5Button.show()
+ self.synthRec5Button.set_tooltip(_('Record Synth sound into slot 5'))
+
+ self.synthRec6Button = ToggleToolButton('rec6')
+ self.synthRec6Button.connect('clicked',self.synthLab.recordSound,6)
+ self.insert(self.synthRec6Button, -1)
+ self.synthRec6Button.show()
+ self.synthRec6Button.set_tooltip(_('Record Synth sound into slot 6'))
+
+ _insertSeparator(1)
+
+ self.resetButton = ToolButton('sl-reset')
+ self.resetButton.connect('clicked',self.synthLab.handleReset)
+ self.insert(self.resetButton, -1)
+ self.resetButton.show()
+ self.resetButton.set_tooltip(_('Reset the worktable'))
+
+class presetToolbar(gtk.Toolbar):
+ def __init__(self,toolbox, synthLab):
+ gtk.Toolbar.__init__(self)
+
+ def _insertSeparator(x = 1):
+ for i in range(x):
+ self.separator = gtk.SeparatorToolItem()
+ self.separator.set_draw(False)
+ self.insert(self.separator,-1)
+ self.separator.show()
+
+ self.toolbox = toolbox
+ self.synthLab = synthLab
+
+ self.preset1Button = RadioToolButton('preset1', group = None)
+ self.preset1Button.connect('clicked',self.synthLab.presetCallback,1)
+ self.insert(self.preset1Button, -1)
+ self.preset1Button.show()
+ self.preset1Button.set_tooltip(_('Preset 1'))
+
+ self.preset2Button = RadioToolButton('preset2', group = self.preset1Button)
+ self.preset2Button.connect('clicked',self.synthLab.presetCallback,2)
+ self.insert(self.preset2Button, -1)
+ self.preset2Button.show()
+ self.preset2Button.set_tooltip(_('Preset 2'))
+
+ self.preset3Button = RadioToolButton('preset3', group = self.preset1Button)
+ self.preset3Button.connect('clicked',self.synthLab.presetCallback,3)
+ self.insert(self.preset3Button, -1)
+ self.preset3Button.show()
+ self.preset3Button.set_tooltip(_('Preset 3'))
+
+ self.preset4Button = RadioToolButton('preset4', group = self.preset1Button)
+ self.preset4Button.connect('clicked',self.synthLab.presetCallback,4)
+ self.insert(self.preset4Button, -1)
+ self.preset4Button.show()
+ self.preset4Button.set_tooltip(_('Preset 4'))
+
+ self.preset5Button = RadioToolButton('preset5', group = self.preset1Button)
+ self.preset5Button.connect('clicked',self.synthLab.presetCallback,5)
+ self.insert(self.preset5Button, -1)
+ self.preset5Button.show()
+ self.preset5Button.set_tooltip(_('Preset 5'))
+
+ self.preset6Button = RadioToolButton('preset6', group = self.preset1Button)
+ self.preset6Button.connect('clicked',self.synthLab.presetCallback,6)
+ self.insert(self.preset6Button, -1)
+ self.preset6Button.show()
+ self.preset6Button.set_tooltip(_('Preset 6'))
+
+ self.preset7Button = RadioToolButton('preset7', group = self.preset1Button)
+ self.preset7Button.connect('clicked',self.synthLab.presetCallback,7)
+ self.insert(self.preset7Button, -1)
+ self.preset7Button.show()
+ self.preset7Button.set_tooltip(_('Preset 7'))
+
+ self.preset8Button = RadioToolButton('preset8', group = self.preset1Button)
+ self.preset8Button.connect('clicked',self.synthLab.presetCallback,8)
+ self.insert(self.preset8Button, -1)
+ self.preset8Button.show()
+ self.preset8Button.set_tooltip(_('Preset 8'))
+
+ self.preset9Button = RadioToolButton('preset9', group = self.preset1Button)
+ self.preset9Button.connect('clicked',self.synthLab.presetCallback,9)
+ self.insert(self.preset9Button, -1)
+ self.preset9Button.show()
+ self.preset9Button.set_tooltip(_('Preset 9'))
+
+ self.preset10Button = RadioToolButton('preset10', group = self.preset1Button)
+ self.preset10Button.connect('clicked',self.synthLab.presetCallback,10)
+ self.insert(self.preset10Button, -1)
+ self.preset10Button.show()
+ self.preset10Button.set_tooltip(_('Preset 10'))
diff --git a/TamTamSynthLab.activity/SynthLab/SynthLabWindow.py b/TamTamSynthLab.activity/SynthLab/SynthLabWindow.py
new file mode 100644
index 0000000..194f71e
--- /dev/null
+++ b/TamTamSynthLab.activity/SynthLab/SynthLabWindow.py
@@ -0,0 +1,1395 @@
+import pygtk
+pygtk.require('2.0')
+import gtk
+
+from Util.Profiler import TP
+
+import gobject
+import time
+import shelve
+from gettext import gettext as _
+import os
+
+from sugar.graphics.toolcombobox import ToolComboBox
+from Util.ThemeWidgets import BigComboBox
+
+import Config
+from Util.ThemeWidgets import *
+from Util.CSoundClient import new_csound_client
+from SynthLab.SynthObjectsParameters import SynthObjectsParameters
+from SynthLab.SynthLabConstants import SynthLabConstants
+from SynthLab.SynthLabToolbars import mainToolbar
+from SynthLab.SynthLabToolbars import presetToolbar
+from Util.Trackpad import Trackpad
+from SubActivity import SubActivity
+
+as_window = False
+
+class SynthLabWindow(SubActivity):
+ def __init__( self, activity, set_mode, dummy_to_change_signature ):
+ SubActivity.__init__(self, set_mode)
+ if as_window:
+ color = gtk.gdk.color_parse(Config.PANEL_BCK_COLOR)
+ self.modify_bg(gtk.STATE_NORMAL, color)
+ self.set_border_width(Config.MAIN_WINDOW_PADDING)
+ self.set_keep_above(False)
+ self.set_decorated(False)
+ self.activity = activity
+ self.csnd = new_csound_client()
+ self.trackpad = Trackpad( self )
+ self.synthObjectsParameters = SynthObjectsParameters()
+ self.resetLocations()
+ self.objectCount = len(self.locations)
+ self.connections = []
+ self.initializeConnections()
+ self.bounds = []
+ for i in range(self.objectCount):
+ self.bounds.append([0,0,0,0])
+ self.updateBounds(i)
+ self.instanceOpen = 0
+ self.recordWait = 0
+ self.recCount = 0
+ self.new = True
+ self.duration = 2
+ self.viewType = ''
+ self.viewParam = ''
+ self.curSlider = 1
+ self.durString = '%.2f' % self.duration
+ self.playingPitch = []
+ self.journalCalled = True
+
+ #Toolbars
+ self.activity.activity_toolbar.keep.show()
+ self._mainToolbar = mainToolbar(self.activity.toolbox, self)
+ self._presetToolbar = presetToolbar(self.activity.toolbox, self)
+ self.activity.toolbox.add_toolbar(_('Main'), self._mainToolbar)
+ self.activity.toolbox.add_toolbar(_('Presets'), self._presetToolbar)
+ self.activity.toolbox.set_current_toolbar(1)
+ self._mainToolbar.show()
+ self._presetToolbar.show()
+
+ loopPointsTable = []
+ sample_names = [name for i in range( len( Config.INSTRUMENTS ) ) for name in Config.INSTRUMENTS.keys() if Config.INSTRUMENTS[ name ].instrumentId == i ]
+ for inst in sample_names:
+ loopStart = Config.INSTRUMENTS[ inst ].loopStart
+ loopEnd = Config.INSTRUMENTS[ inst ].loopEnd
+ crossDur = Config.INSTRUMENTS[ inst ].crossDur
+ loopPointsTable.extend( [ loopStart, loopEnd, crossDur ] )
+ mess = "f5755 0 512 -2 " + " " .join([str(n) for n in loopPointsTable])
+ self.csnd.inputMessage( mess )
+
+ self.lineWidth = 3
+ self.lineWidthMUL2 = self.lineWidth*2
+ self.lineWidthMUL4 = self.lineWidth*4
+ self.lineWidthMUL4SQ = self.lineWidthMUL4*self.lineWidthMUL4
+ self.clockStart = 0
+ self.sample_names = [name for i in range( len( Config.INSTRUMENTS ) ) for name in Config.INSTRUMENTS.keys() if Config.INSTRUMENTS[ name ].instrumentId == i ]
+ if as_window:
+ self.add_events(gtk.gdk.KEY_PRESS_MASK|gtk.gdk.KEY_RELEASE_MASK)
+
+ self.action = None
+ self.dragObject = None
+ self.overWire = None
+ self.overGate = None
+ self.overGateObj = None
+ self.overGateReject = False
+ self.overGateSize = 32
+ self.overGateSizeDIV2 = self.overGateSize//2
+ self.overLineWidth = self.lineWidth*2
+ self.overLineWidthMUL2 = self.overLineWidth*2
+
+ self.gatePoint = SynthLabConstants.GATE_POINT
+ self.gateMap = SynthLabConstants.GATE_MAP
+ # look up gate type to find the matching gate type
+ self.gateMatch = [ SynthLabConstants.GT_CONTROL_INPUT,
+ SynthLabConstants.GT_CONTROL_OUTPUT,
+ SynthLabConstants.GT_SOUND_INPUT,
+ SynthLabConstants.GT_SOUND_OUTPUT ]
+
+ # set up window
+ if as_window:
+ self.set_position( gtk.WIN_POS_CENTER_ON_PARENT )
+ self.set_title("Synth Lab")
+ self.mainBox = gtk.HBox()
+ self.subBox = gtk.HBox()
+ self.drawingBox = RoundVBox( 10, Config.PANEL_COLOR, Config.PANEL_COLOR )
+ self.drawingBox.set_border_width(0)
+ self.infoBox = RoundVBox( 10, Config.TOOLBAR_BCK_COLOR, Config.TOOLBAR_BCK_COLOR )
+ self.infoBox.set_border_width(Config.PANEL_SPACING)
+ self.infoBox.set_size_request(300, 750)
+ self.subBox.pack_start(self.drawingBox, True, True)
+ self.subBox.pack_start(self.infoBox, True, True)
+ self.mainBox.pack_start(self.subBox)
+
+ menuBox = gtk.HBox()
+ self.objComboBox = BigComboBox()
+ self.objComboBox.append_item(0, 'Envelope', Config.TAM_TAM_ROOT + '/icons/sl-adsr-menu.svg')
+ self.objComboBox.set_active(0)
+ self.objComboBox.connect('changed', self.changeObject)
+ comboMenu = ToolComboBox(self.objComboBox)
+ menuBox.pack_start(comboMenu)
+ self.infoBox.pack_start(menuBox, False, False, 5)
+
+ slidersBox = gtk.HBox()
+
+ self.instanceID = 12 # object number
+ self.objectType = self.instanceID / 4 #(control, source, fx, output)
+ self.choosenType = 0 # self.synthObjectsParameters.types[self.instanceID] module as an index
+ selectedType = SynthLabConstants.CHOOSE_TYPE[self.objectType][self.choosenType] #module as a string
+
+ slider1Min = SynthLabConstants.TYPES[selectedType][4]
+ slider1Max = SynthLabConstants.TYPES[selectedType][5]
+ slider2Min = SynthLabConstants.TYPES[selectedType][6]
+ slider2Max = SynthLabConstants.TYPES[selectedType][7]
+ slider3Min = SynthLabConstants.TYPES[selectedType][8]
+ slider3Max = SynthLabConstants.TYPES[selectedType][9]
+ slider4Min = SynthLabConstants.TYPES[selectedType][10]
+ slider4Max = SynthLabConstants.TYPES[selectedType][11]
+
+ slider1Step = SynthLabConstants.TYPES[selectedType][12][0]
+ slider1Snap = SynthLabConstants.TYPES[selectedType][12][1]
+ slider2Step = SynthLabConstants.TYPES[selectedType][13][0]
+ slider2Snap = SynthLabConstants.TYPES[selectedType][13][1]
+ slider3Step = SynthLabConstants.TYPES[selectedType][14][0]
+ slider3Snap = SynthLabConstants.TYPES[selectedType][14][1]
+
+ parametersTable = self.synthObjectsParameters.choiceParamsSet[self.objectType]
+ tablePos = (self.instanceID % 4)*4
+ slider1Init = parametersTable[tablePos]
+ slider2Init = parametersTable[tablePos+1]
+ slider3Init = parametersTable[tablePos+2]
+ slider4Init = parametersTable[tablePos+3]
+
+ sliderTextColor = gtk.gdk.color_parse(Config.WHITE_COLOR)
+ sliderHeight = 240
+
+ self.p1Adjust = gtk.Adjustment(slider1Init, slider1Min, slider1Max, slider1Step, slider1Step, 0)
+ self.p1Adjust.connect("value-changed", self.sendTables, 1)
+ self.slider1 = gtk.VScale(self.p1Adjust)
+ self.slider1.connect("button-release-event", self.handleSliderRelease)
+ self.slider1.connect("enter-notify-event", self.handleSliderEnter, 1)
+ self.slider1.set_digits(slider1Snap)
+ self.slider1.set_inverted(True)
+ self.slider1.set_size_request(55, sliderHeight)
+ self.slider1.modify_fg(gtk.STATE_NORMAL, sliderTextColor)
+ slidersBox.pack_start(self.slider1, True, False)
+
+ self.p2Adjust = gtk.Adjustment(slider2Init, slider2Min, slider2Max, slider2Step, slider2Step, 0)
+ self.p2Adjust.connect("value-changed", self.sendTables, 2)
+ self.slider2 = gtk.VScale(self.p2Adjust)
+ self.slider2.connect("button-release-event", self.handleSliderRelease)
+ self.slider2.connect("enter-notify-event", self.handleSliderEnter, 2)
+ self.slider2.set_digits(slider2Snap)
+ self.slider2.set_inverted(True)
+ self.slider2.set_size_request(55, sliderHeight)
+ self.slider2.modify_fg(gtk.STATE_NORMAL, sliderTextColor)
+ slidersBox.pack_start(self.slider2, True, False)
+
+ self.p3Adjust = gtk.Adjustment(slider3Init, slider3Min, slider3Max, slider3Step, slider3Step, 0)
+ self.p3Adjust.connect("value-changed", self.sendTables, 3)
+ self.slider3 = gtk.VScale(self.p3Adjust)
+ self.slider3.connect("button-release-event", self.handleSliderRelease)
+ self.slider3.connect("enter-notify-event", self.handleSliderEnter, 3)
+ self.slider3.set_digits(slider3Snap)
+ self.slider3.set_inverted(True)
+ self.slider3.set_size_request(55, sliderHeight)
+ self.slider3.modify_fg(gtk.STATE_NORMAL, sliderTextColor)
+ slidersBox.pack_start(self.slider3, True, False)
+
+ self.p4Adjust = gtk.Adjustment(slider4Init, slider4Min, slider4Max, .01, .01, 0)
+ self.p4Adjust.connect("value-changed", self.sendTables, 4)
+ self.slider4 = gtk.VScale(self.p4Adjust)
+ self.slider4.connect("button-release-event", self.handleSliderRelease)
+ self.slider4.connect("enter-notify-event", self.handleSliderEnter, 4)
+ self.slider4.set_digits(2)
+ self.slider4.set_inverted(True)
+ self.slider4.set_size_request(55, sliderHeight)
+ self.slider4.modify_fg(gtk.STATE_NORMAL, sliderTextColor)
+ slidersBox.pack_start(self.slider4, True, False)
+
+ self.infoBox.pack_start(slidersBox, False, False, 5)
+
+ self.infoText = 'ADSR envelope apply on the overall signal'
+ textBox = gtk.HBox()
+ text_color = gtk.gdk.color_parse(Config.WHITE_COLOR)
+ text_bg_color = gtk.gdk.color_parse(Config.TOOLBAR_BCK_COLOR)
+ textScroller = gtk.ScrolledWindow()
+ textScroller.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ textScroller.set_size_request(270, 301)
+ self.textBuf = gtk.TextBuffer(None)
+ self.textBuf.set_text(self.infoText)
+ self.textViewer = gtk.TextView(self.textBuf)
+ self.textViewer.modify_text(gtk.STATE_NORMAL, text_color)
+ self.textViewer.modify_base(gtk.STATE_NORMAL, text_bg_color)
+ self.textViewer.set_border_window_size(gtk.TEXT_WINDOW_LEFT, 1)
+ self.textViewer.set_border_window_size(gtk.TEXT_WINDOW_RIGHT, 1)
+ self.textViewer.set_border_window_size(gtk.TEXT_WINDOW_TOP, 1)
+ self.textViewer.set_border_window_size(gtk.TEXT_WINDOW_BOTTOM, 1)
+ self.textViewer.set_wrap_mode(gtk.WRAP_WORD)
+ self.textViewer.set_editable(False)
+ self.textViewer.set_overwrite(True)
+ self.textViewer.set_cursor_visible(False)
+ self.textViewer.set_left_margin(10)
+ self.textViewer.set_right_margin(10)
+ self.textViewer.set_pixels_above_lines(7)
+ self.textViewer.set_justification(gtk.JUSTIFY_LEFT)
+ textScroller.add(self.textViewer)
+ textBox.pack_start(textScroller, False, False, 10)
+ self.infoBox.pack_start(textBox, False, False, 5)
+
+ self.infoLabel = gtk.Label()
+ self.infoBox.pack_end(self.infoLabel, False, False, 20)
+ textColor = gtk.gdk.color_parse(Config.WHITE_COLOR)
+ self.infoLabel.set_justify(gtk.JUSTIFY_LEFT)
+ self.infoLabel.modify_fg(gtk.STATE_NORMAL, textColor)
+
+ self.drawingAreaWidth = 900
+ self.drawingAreaHeight = 750
+ self.separatorY = 660
+
+ self.clearMask = gtk.gdk.Rectangle(0,0,self.drawingAreaWidth,self.drawingAreaHeight)
+
+ win = gtk.gdk.get_default_root_window()
+ self.gc = gtk.gdk.GC( win )
+ self.gc.set_line_attributes( self.lineWidth, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER )
+
+
+ self.dirtyRectToAdd = gtk.gdk.Rectangle()
+ self.dirty = False
+
+ self.screenBuf = gtk.gdk.Pixmap( win, self.drawingAreaWidth, self.drawingAreaHeight )
+ self.screenBufDirtyRect = gtk.gdk.Rectangle()
+ self.screenBufDirty = False
+
+ self.drawingArea = gtk.DrawingArea()
+ self.drawingArea.set_size_request( self.drawingAreaWidth, self.drawingAreaHeight )
+ self.col = gtk.gdk.color_parse(Config.PANEL_COLOR)
+ colormap = self.drawingArea.get_colormap()
+ self.bgColor = colormap.alloc_color( Config.PANEL_COLOR, True, True )
+ self.lineColor = colormap.alloc_color( Config.SL_LINE_COLOR, True, True )
+ self.highlightColor = colormap.alloc_color( Config.SL_HIGHLIGHT_COLOR, True, True )
+ self.overWireColor = colormap.alloc_color( Config.SL_OVER_WIRE_COLOR, True, True )
+ self.overGateColor = colormap.alloc_color( Config.SL_OVER_GATE_COLOR, True, True )
+ self.overGateRejectColor = colormap.alloc_color( Config.SL_OVER_GATE_REJECT_COLOR, True, True )
+ self.drawingArea.modify_bg(gtk.STATE_NORMAL, self.col)
+
+ self.loadPixmaps()
+
+ self.drawingArea.add_events( gtk.gdk.BUTTON_PRESS_MASK
+ | gtk.gdk.BUTTON_RELEASE_MASK
+ | gtk.gdk.POINTER_MOTION_MASK
+ | gtk.gdk.POINTER_MOTION_HINT_MASK )
+ self.drawingArea.connect( "button-press-event", self.handleButtonPress )
+ self.drawingArea.connect( "button-release-event", self.handleButtonRelease )
+ self.drawingArea.connect( "motion-notify-event", self.handleMotion )
+ self.drawingArea.connect("expose-event", self.draw)
+ self.drawingBox.pack_start(self.drawingArea, False, False, 0)
+
+ tempFile = 'synthTemp'
+ if tempFile in os.listdir(Config.PREF_DIR):
+ self.handleLoadTemp()
+ else:
+ self.presetCallback(None,1)
+ self.add(self.mainBox)
+ self.show_all()
+
+ def onDestroy(self):
+ pass
+
+ def select(self, i):
+ if i == self.instanceID:
+ return
+ self.new = False
+ if self.instanceID > 0:
+ self.invalidate_rect( self.bounds[self.instanceID][0], self.bounds[self.instanceID][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT )
+ self.instanceID = i
+ self.invalidate_rect( self.bounds[i][0], self.bounds[i][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT )
+
+ if self.instanceID / 4 != self.objectType:
+ self.objectType = self.instanceID / 4
+ self.objComboBox.remove_all()
+ for i in range(len(SynthLabConstants.CHOOSE_TYPE[self.objectType])):
+ self.objComboBox.append_item(i, SynthLabConstants.SYNTHTYPES[self.objectType][i], Config.TAM_TAM_ROOT + '/icons/sl-' + SynthLabConstants.CHOOSE_TYPE[self.objectType][i] + '-menu.svg')
+
+ oldChoosen = self.choosenType
+ if self.instanceID != 12:
+ self.choosenType = self.synthObjectsParameters.types[self.instanceID]
+ else:
+ self.choosenType = 0
+
+ self.objComboBox.set_active(self.choosenType)
+ #Not sure about this
+ self.slider1.grab_focus()
+ self.sendTables(self.slider1, 1)
+
+ def changeObject(self, widget):
+ self.choosenType = widget.props.value
+ self.resize()
+ if self.instanceID != 12:
+ self.synthObjectsParameters.setType(self.instanceID, self.choosenType)
+ self.invalidate_rect( self.bounds[self.instanceID][0], self.bounds[self.instanceID][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT )
+ if self.new:
+ self.writeTables( self.synthObjectsParameters.types,
+ self.synthObjectsParameters.controlsParameters,
+ self.synthObjectsParameters.sourcesParameters,
+ self.synthObjectsParameters.fxsParameters )
+
+ def updateViewer(self):
+ selectedType = SynthLabConstants.CHOOSE_TYPE[self.objectType][self.choosenType]
+ infoType = SynthLabConstants.SYNTHPARA[selectedType][4]
+ infoPara = SynthLabConstants.SYNTHPARA[selectedType][4+self.curSlider]
+ #infoPara = "Parameter's info not yet set"
+ self.infoText = infoType + '\n\n' + SynthLabConstants.SYNTHPARA[selectedType][self.curSlider-1] + ': ' + infoPara
+ self.textBuf.set_text(self.infoText)
+
+ def recallSliderValue( self, num ):
+ if num == 1:
+ if SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.NOISE:
+ return SynthLabConstants.NOISE_TYPES[int(self.slider1Val)]
+ else:
+ return '%.2f' % self.slider1Val
+ if num == 2:
+ if SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.VCO:
+ return SynthLabConstants.VCO_WAVEFORMS[int(self.slider2Val)]
+ elif SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.SAMPLE or SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.GRAIN:
+ return self.sample_names[int(self.slider2Val)]
+ elif SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.VOICE:
+ return SynthLabConstants.VOWEL_TYPES[int(self.slider2Val)]
+ else:
+ return '%.2f' % self.slider2Val
+ if num == 3:
+ if SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.LFO:
+ return SynthLabConstants.LFO_WAVEFORMS[int(self.slider3Val)]
+ elif SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.TRACKPADX:
+ return SynthLabConstants.SCALING_TYPES[int(self.slider3Val)]
+ elif SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.TRACKPADY:
+ return SynthLabConstants.SCALING_TYPES[int(self.slider3Val)]
+ elif SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.FILTER:
+ return SynthLabConstants.FILTER_TYPES[int(self.slider3Val)]
+ elif SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] == SynthLabConstants.RINGMOD:
+ return SynthLabConstants.LFO_WAVEFORMS[int(self.slider3Val)]
+ else:
+ return '%.2f' % self.slider3Val
+ if num == 4: return '%.2f' % self.slider4Val
+
+ def resize( self ):
+ selectedType = SynthLabConstants.CHOOSE_TYPE[self.objectType][self.choosenType]
+ if self.new:
+ slider1Init = SynthLabConstants.TYPES[selectedType][0]
+ slider2Init = SynthLabConstants.TYPES[selectedType][1]
+ slider3Init = SynthLabConstants.TYPES[selectedType][2]
+ slider4Init = SynthLabConstants.TYPES[selectedType][3]
+ else:
+ parametersTable = self.synthObjectsParameters.choiceParamsSet[self.objectType]
+ tablePos = (self.instanceID % 4)*4
+ slider1Init = parametersTable[tablePos]
+ slider2Init = parametersTable[tablePos+1]
+ slider3Init = parametersTable[tablePos+2]
+ slider4Init = parametersTable[tablePos+3]
+
+ slider1Min = SynthLabConstants.TYPES[selectedType][4]
+ slider1Max = SynthLabConstants.TYPES[selectedType][5]
+ slider2Min = SynthLabConstants.TYPES[selectedType][6]
+ slider2Max = SynthLabConstants.TYPES[selectedType][7]
+ slider3Min = SynthLabConstants.TYPES[selectedType][8]
+ slider3Max = SynthLabConstants.TYPES[selectedType][9]
+ slider4Min = SynthLabConstants.TYPES[selectedType][10]
+ slider4Max = SynthLabConstants.TYPES[selectedType][11]
+
+ slider1Step = SynthLabConstants.TYPES[selectedType][12][0]
+ slider1Snap = SynthLabConstants.TYPES[selectedType][12][1]
+ slider2Step = SynthLabConstants.TYPES[selectedType][13][0]
+ slider2Snap = SynthLabConstants.TYPES[selectedType][13][1]
+ slider3Step = SynthLabConstants.TYPES[selectedType][14][0]
+ slider3Snap = SynthLabConstants.TYPES[selectedType][14][1]
+
+ self.p1Adjust.set_all(slider1Init, slider1Min, slider1Max, slider1Step, slider1Step, 0)
+ self.p2Adjust.set_all(slider2Init, slider2Min, slider2Max, slider2Step, slider2Step, 0)
+ self.p3Adjust.set_all(slider3Init, slider3Min, slider3Max, slider3Step, slider3Step, 0)
+ self.p4Adjust.set_all(slider4Init, slider4Min, slider4Max, 0.01, 0.01, 0)
+
+ self.slider1.set_digits(slider1Snap)
+ self.slider2.set_digits(slider2Snap)
+ self.slider3.set_digits(slider3Snap)
+
+ self.new = True
+
+ def sendTables( self, widget, data ):
+ self.curSlider = data
+ self.slider1Val = self.p1Adjust.value
+ self.slider2Val = self.p2Adjust.value
+ self.slider3Val = self.p3Adjust.value
+ self.slider4Val = self.p4Adjust.value
+ if self.instanceID != 12:
+ self.synthObjectsParameters.setType(self.instanceID, self.choosenType)
+ sliderListValue = [ self.p1Adjust.value, self.p2Adjust.value, self.p3Adjust.value, self.p4Adjust.value ]
+ if self.objectType == 0:
+ for i in range(4):
+ self.synthObjectsParameters.setControlParameter((self.instanceID % 4)*4+i, sliderListValue[i])
+ elif self.objectType == 1:
+ for i in range(4):
+ self.synthObjectsParameters.setSourceParameter((self.instanceID % 4)*4+i, sliderListValue[i])
+ elif self.objectType == 2:
+ for i in range(4):
+ self.synthObjectsParameters.setFxParameter((self.instanceID % 4)*4+i, sliderListValue[i])
+ elif self.objectType == 3:
+ for i in range(4):
+ self.synthObjectsParameters.setOutputParameter(i, sliderListValue[i])
+ self.updateViewer()
+ selectedType = SynthLabConstants.CHOOSE_TYPE[self.objectType][self.choosenType]
+ _str = SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] + '\n' + SynthLabConstants.SYNTHPARA[selectedType][self.curSlider-1] + ': ' + self.recallSliderValue(self.curSlider)
+ self.parameterUpdate(_str)
+
+ def handleSliderRelease(self, widget, data=None):
+ if self.instanceID != 12:
+ self.writeTables( self.synthObjectsParameters.types, self.synthObjectsParameters.controlsParameters,
+ self.synthObjectsParameters.sourcesParameters, self.synthObjectsParameters.fxsParameters )
+
+ def handleSliderEnter(self, widget, data, slider):
+ widget.grab_focus()
+ self.sendTables(widget, slider)
+
+ #selectedType = SynthLabConstants.CHOOSE_TYPE[self.objectType][self.choosenType]
+ #_str = SynthLabConstants.SYNTHTYPES[self.objectType][self.choosenType] + '\n' + SynthLabConstants.SYNTHPARA[selectedType][self.curSlider-1] + ': ' + self.recallSliderValue(self.curSlider)
+ #self.parameterUpdate(_str)
+
+ def onKeyPress(self,widget,event):
+ key = event.hardware_keycode
+ if key not in Config.KEY_MAP:
+ return
+ midiPitch = Config.KEY_MAP[key]
+ if midiPitch not in self.playingPitch:
+ if self.recordWait == 0:
+ self.playingPitch.append( midiPitch )
+ self.playNote( midiPitch, 0 )
+ else:
+ self.recordWait = 0
+ self.playingPitch.append( midiPitch )
+ self.playNote( midiPitch, self.table )
+ self.waitRecording()
+
+ def resetRecord( self ):
+ gobject.source_remove( self.wait )
+ self.recordButton.set_active(False)
+ inst = 'lab' + str(self.table-85)
+ self.csnd.load_synth_instrument(inst)
+ self.table = 0
+ return True
+
+ def waitRecording(self):
+ self.wait = gobject.timeout_add(int(self.duration*1000) , self.resetRecord )
+
+ def onKeyRelease( self, widget, event ):
+ key = event.hardware_keycode
+ if key not in Config.KEY_MAP:
+ return
+ midiPitch = Config.KEY_MAP[key]
+ if midiPitch in self.playingPitch:
+ self.playingPitch.remove( midiPitch )
+
+ def handleDuration( self, adjustment ):
+ self.duration = adjustment.value
+
+ def parameterUpdate( self, string ):
+ self.infoLabel.set_text(string)
+
+ def playNote( self, midiPitch, table ):
+ cpsPitch = 261.626*pow(1.0594633, midiPitch-36)
+ self.recCount += 1
+ mess = "i5203." + str(self.recCount) + " 0 " + str(self.duration) + " " + str(cpsPitch) + " " + str(table) + " " + " " .join([str(n) for n in self.synthObjectsParameters.getOutputParameters()])
+ self.csnd.inputMessage( mess )
+ if self.recCount >= 9: self.recCount = 0
+
+ def handleClose( self, widget, data ):
+ if self.journalCalled:
+ self.activity.close()
+ return
+ self.set_mode('welcome')
+ if as_window:
+ self.set_keep_above(False)
+ self.hide()
+
+ def resetLocations( self ):
+ # deep copy the list
+ self.locations = [ loc[:] for loc in SynthLabConstants.INIT_LOCATIONS ]
+
+ def handleReset( self, widget, data = None):
+ self.resetLocations()
+ self.objectCount = len(self.locations)
+ for i in range(self.objectCount):
+ self.updateBounds( i )
+ self.duration = 2
+ self._mainToolbar.durationSliderAdj.set_value(self.duration)
+ self.connections = []
+ self.synthObjectsParameters.__init__()
+ self.writeTables( self.synthObjectsParameters.types, self.synthObjectsParameters.controlsParameters, self.synthObjectsParameters.sourcesParameters, self.synthObjectsParameters.fxsParameters )
+ self.synthObjectsParameters.update()
+ self.initializeConnections()
+ self.invalidate_rect( 0, 0, self.drawingAreaWidth, self.drawingAreaHeight )
+ time.sleep(.01)
+ self.controlToSrcConnections()
+ time.sleep(.01)
+ self.controlToFxConnections()
+ time.sleep(.01)
+ self.audioConnections()
+ time.sleep(.01)
+
+ def setAction( self, action ):
+ self.action = action
+
+ def doneAction( self ):
+ if self.action == "drag-object": self.doneDragObject()
+ self.action = None
+
+ def handleButtonRelease( self, widget, event ):
+
+ self.highlightWire( None )
+ self.highlightGate( None )
+
+ if self.action == "drag-object":
+ self.doneAction()
+ elif self.action == "draw-wire":
+ for i in range(self.objectCount):
+ if self.bounds[i][0] < event.x < self.bounds[i][2] and self.bounds[i][1] < event.y < self.bounds[i][3]:
+ if i == self.wireObj:
+ break
+ gate = self.testGates( i, event.x-self.locations[i][0], event.y-self.locations[i][1] )
+ if gate:
+ self.connectWire( i, gate )
+ break
+ # if we don't connect the wire here they can try to click it somewhere, so don't end the action
+
+ def handleButtonPress( self, widget, event):
+ self.clickLoc = (int(event.x),int(event.y))
+
+ self.highlightWire( None )
+ self.highlightGate( None )
+
+ if event.button == 1:
+ for i in range(self.objectCount-1,-1,-1):
+ if self.bounds[i][0] < event.x < self.bounds[i][2] and self.bounds[i][1] < event.y < self.bounds[i][3]:
+ if self.locations[i][1] == SynthLabConstants.INIT_LOCATIONS[i][1] \
+ and i != self.objectCount-1:
+ gate = False
+ else:
+ gate = self.testGates( i, event.x-self.locations[i][0], event.y-self.locations[i][1] )
+ if gate:
+ if self.action == "draw-wire":
+ self.connectWire( i, gate )
+ else:
+ self.startWire( i, gate )
+ else:
+ if self.action == "draw-wire":
+ self.doneWire()
+ if i != self.objectCount-1:
+ self.startDragObject( i )
+ else:
+ self.select( i )
+ return
+ if self.action == "draw-wire": # didn't hit anything
+ self.doneWire()
+ else:
+ # check if we clicked a wire
+ i = self.wireUnderLoc( event.x, event.y )
+ if i >= 0: self.deleteWire( i )
+
+
+ def handleMotion( self, widget, event ):
+
+ if event.is_hint:
+ x, y, state = widget.window.get_pointer()
+ event.x = float(x)
+ event.y = float(y)
+ event.state = state
+
+ if self.action == "drag-object":
+ self.updateDragObject( int(event.x), int(event.y) )
+ elif self.action == "draw-wire":
+ self.updateWire( int(event.x), int(event.y) )
+ for i in range(self.objectCount):
+ if self.locations[i] == SynthLabConstants.INIT_LOCATIONS[i] \
+ and i != self.objectCount-1: continue
+ if self.bounds[i][0] < event.x < self.bounds[i][2] and self.bounds[i][1] < event.y < self.bounds[i][3]:
+ gate = self.testGates( i, event.x-self.locations[i][0], event.y-self.locations[i][1] )
+ if gate and ( gate != self.wireGate or i != self.wireObj ):
+ if gate[0] == SynthLabConstants.GT_CONTROL_OUTPUT or gate[0] == SynthLabConstants.GT_SOUND_OUTPUT:
+ ok = self.testConnection( i, gate, self.wireObj, self.wireGate )
+ else:
+ ok = self.testConnection( self.wireObj, self.wireGate, i, gate )
+ self.highlightGate( i, gate, not ok )
+ else: self.highlightGate( None )
+ return
+ self.highlightGate( None )
+ else: # check for mouse overs
+ for i in range(self.objectCount):
+ if self.locations[i] == SynthLabConstants.INIT_LOCATIONS[i] \
+ and i != self.objectCount-1: continue
+
+ if self.bounds[i][0] < event.x < self.bounds[i][2] and self.bounds[i][1] < event.y < self.bounds[i][3]:
+ gate = self.testGates( i, event.x-self.locations[i][0], event.y-self.locations[i][1] )
+ if gate:
+ self.highlightGate( i, gate )
+ else:
+ self.highlightGate( None )
+ self.highlightWire( None )
+ return
+ # didn't find a gate
+ self.highlightGate( None )
+ # check for wires
+ i = self.wireUnderLoc( event.x, event.y )
+ if i >= 0: self.highlightWire( i )
+ else: self.highlightWire( None )
+
+ def testGates( self, i, x, y ):
+ oT = i >> 2
+ for gT in range(len(self.gateMap[oT])):
+ for n in range(len(self.gateMap[oT][gT])):
+ if self.gateMap[oT][gT][n][0] <= x <= self.gateMap[oT][gT][n][2] \
+ and self.gateMap[oT][gT][n][1] <= y <= self.gateMap[oT][gT][n][3]:
+ return ( gT, n, self.gateMap[oT][gT][n][4], self.gatePoint[oT][gT][n] ) # type, index, wire loc, center loc
+ return False
+
+ def startWire( self, obj, gate ):
+ self.wireObj = obj
+ self.wireGate = gate
+ x = gate[2][0] + self.locations[obj][0]
+ y = gate[2][1] + self.locations[obj][1]
+ self.wirePoint = [ [ x, y ], [ x, y ] ]
+ self.wireRect = [ 0, 0, 0, 0 ]
+ self.setAction( "draw-wire" )
+
+ def updateWire( self, x, y ):
+ if x < 0: x = 0
+ elif x > self.drawingAreaWidth: x = self.drawingAreaWidth
+ if y < 0: y = 0
+ elif y > self.separatorY: y = self.separatorY
+ self.invalidate_rect( self.wireRect[0], self.wireRect[1], self.wireRect[2], self.wireRect[3], False )
+ if x < self.wirePoint[0][0]: self.wireRect[0], self.wireRect[2] = x-self.lineWidth, self.wirePoint[0][0]-x+self.lineWidthMUL2
+ else: self.wireRect[0], self.wireRect[2] = self.wirePoint[0][0]-self.lineWidth, x-self.wirePoint[0][0]+self.lineWidthMUL2
+ if y < self.wirePoint[0][1]: self.wireRect[1], self.wireRect[3] = y-self.lineWidth, self.wirePoint[0][1]-y+self.lineWidthMUL2
+ else: self.wireRect[1], self.wireRect[3] = self.wirePoint[0][1]-self.lineWidth, y-self.wirePoint[0][1]+self.lineWidthMUL2
+ self.wirePoint[1][0] = x
+ self.wirePoint[1][1] = y
+ self.invalidate_rect( self.wireRect[0], self.wireRect[1], self.wireRect[2], self.wireRect[3], False )
+
+ def connectWire( self, obj, gate ):
+ if gate[0] == SynthLabConstants.GT_CONTROL_OUTPUT or gate[0] == SynthLabConstants.GT_SOUND_OUTPUT:
+ bObj, eObj = obj, self.wireObj
+ bGate, eGate = gate, self.wireGate
+ else:
+ bObj, eObj = self.wireObj, obj
+ bGate, eGate = self.wireGate, gate
+
+ i = self.newConnection( bObj, bGate, eObj, eGate )
+ if i >= 0: # successful connection
+ self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3] )
+ self.doneWire()
+
+ def deleteWire( self, i ):
+ self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3] )
+ self.delConnection( i )
+
+ def doneWire( self ):
+ self.invalidate_rect( self.wireRect[0], self.wireRect[1], self.wireRect[2], self.wireRect[3] )
+ self.doneAction()
+
+ def wireUnderLoc( self, x, y ):
+ for i in range(len(self.connections)):
+ if x < self.cBounds[i][0] or x > self.cBounds[i][4]: continue
+ if y < self.cBounds[i][1] or y > self.cBounds[i][5]: continue
+ if self.cPoints[i][0] == self.cPoints[i][2]: # vertical line
+ if abs(x-self.cPoints[i][0]) < self.lineWidthMUL4:
+ return i
+ else:
+ slope = (self.cPoints[i][3]-self.cPoints[i][1])/float(self.cPoints[i][2]-self.cPoints[i][0])
+ if abs(slope) < 1:
+ yy = self.cPoints[i][1] + (x-self.cPoints[i][0])*slope
+ if abs(y-yy) < self.lineWidthMUL4:
+ return i
+ else:
+ xx = self.cPoints[i][0] + (y-self.cPoints[i][1])/slope
+ if abs(x-xx) < self.lineWidthMUL4:
+ return i
+ return -1 # nothing found
+
+ # pass in i = None to clear
+ def highlightWire( self, i ):
+ if self.overWire != i:
+ if self.overWire != None:
+ self.invalidate_rect( self.cBounds[self.overWire][0], self.cBounds[self.overWire][1], self.cBounds[self.overWire][2], self.cBounds[self.overWire][3] )
+ self.overWire = i
+ if self.overWire != None:
+ self.invalidate_rect( self.cBounds[self.overWire][0], self.cBounds[self.overWire][1], self.cBounds[self.overWire][2], self.cBounds[self.overWire][3] )
+
+ # pass in obj = None to clear
+ def highlightGate( self, obj, gate = None, reject = False ):
+ if obj == None:
+ self.parameterUpdate('')
+ if self.overGateObj != obj or self.overGate != gate or self.overGateReject != reject:
+ if self.overGate != None:
+ self.invalidate_rect( self.overGateLoc[0], self.overGateLoc[1], self.overGateSize, self.overGateSize )
+ self.overGateObj = obj
+ self.overGate = gate
+ self.overGateReject = reject
+ if self.overGate != None:
+ oT = self.overGateObj//4
+ x = self.locations[self.overGateObj][0] + self.overGate[3][0] - self.overGateSizeDIV2
+ y = self.locations[self.overGateObj][1] + self.overGate[3][1] - self.overGateSizeDIV2
+ self.overGateLoc = ( x, y )
+ self.invalidate_rect( self.overGateLoc[0], self.overGateLoc[1], self.overGateSize, self.overGateSize )
+ if True: #obj != 12:
+ if gate[0] == 0:
+ _str = SynthLabConstants.SYNTHTYPES[obj/4][self.typesTable[obj]] + _(': controller output')
+ elif gate[0] == 1:
+ choosen = SynthLabConstants.CHOOSE_TYPE[obj/4][self.typesTable[obj]]
+ parametersTable = self.synthObjectsParameters.choiceParamsSet[obj/4]
+ tablePos = (obj % 4)*4+gate[1]
+ paraVal = '%.2f' % parametersTable[tablePos]
+ _str = SynthLabConstants.SYNTHTYPES[obj/4][self.typesTable[obj]] + '\n' + SynthLabConstants.SYNTHPARA[choosen][gate[1]] + ': ' + paraVal
+ if self.overGateObj == self.instanceID:
+ gateNum = self.overGate[1]+1
+ exec 'self.slider%s.grab_focus()' % str(gateNum)
+ exec 'self.sendTables(self.slider%s, %d)' % (str(gateNum), gateNum)
+ elif gate[0] == 2:
+ _str = SynthLabConstants.SYNTHTYPES[obj/4][self.typesTable[obj]] + _(': sound output')
+ elif gate[0] == 3:
+ if obj != 12:
+ _str = SynthLabConstants.SYNTHTYPES[obj/4][self.typesTable[obj]] + _(': sound input')
+ else:
+ _str = _('Send sound to the speakers')
+ self.parameterUpdate( _str )
+
+ def startDragObject( self, i ):
+ self.dragObject = i
+ self.dragInitialLoc = (self.locations[i][0],self.locations[i][1])
+ self.potentialDisconnect = False
+ self.invalidate_rect( self.bounds[i][0], self.bounds[i][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT )
+ for i in self.outputMap[self.dragObject]:
+ self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3] )
+ for i in self.inputMap[self.dragObject]:
+ self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3] )
+ self.setAction( "drag-object" )
+
+ def updateDragObject( self, x, y ):
+ delta = [ x-self.clickLoc[0], y-self.clickLoc[1] ]
+ x = self.dragInitialLoc[0]+delta[0]
+ if x-SynthLabConstants.HALF_SIZE < 0: x = SynthLabConstants.HALF_SIZE
+ elif x+SynthLabConstants.HALF_SIZE > self.drawingAreaWidth: x = self.drawingAreaWidth - SynthLabConstants.HALF_SIZE
+ y = self.dragInitialLoc[1]+delta[1]
+ if y-SynthLabConstants.HALF_SIZE < 0: y = SynthLabConstants.HALF_SIZE
+ elif y+SynthLabConstants.HALF_SIZE > self.drawingAreaHeight: y = self.drawingAreaHeight - SynthLabConstants.HALF_SIZE
+
+ self.invalidate_rect(self.bounds[self.dragObject][0], self.bounds[self.dragObject][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT, False )
+ if not self.potentialDisconnect:
+ for i in self.outputMap[self.dragObject]:
+ self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3], False )
+ for i in self.inputMap[self.dragObject]:
+ self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3], False )
+
+ if y > (self.separatorY-5): self.potentialDisconnect = True
+ else: self.potentialDisconnect = False
+
+ self.locations[self.dragObject][0] = int( x )
+ self.locations[self.dragObject][1] = int( y )
+ self.updateBounds(self.dragObject)
+
+ self.invalidate_rect(self.bounds[self.dragObject][0], self.bounds[self.dragObject][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT, False )
+ if not self.potentialDisconnect:
+ for i in self.outputMap[self.dragObject]:
+ self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3], False )
+ for i in self.inputMap[self.dragObject]:
+ self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3], False )
+
+ def doneDragObject( self ):
+ if self.potentialDisconnect:
+ self.invalidate_rect( self.bounds[self.dragObject][0], self.bounds[self.dragObject][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT, False )
+ m = self.outputMap[self.dragObject][:]
+ m.sort(reverse=True)
+ for i in m: self.delConnection( i )
+ m = self.inputMap[self.dragObject][:]
+ m.sort(reverse=True)
+ for i in m: self.delConnection( i )
+ self.locations[self.dragObject][0] = SynthLabConstants.INIT_LOCATIONS[self.dragObject][0]
+ self.locations[self.dragObject][1] = SynthLabConstants.INIT_LOCATIONS[self.dragObject][1]
+ self.updateBounds( self.dragObject )
+ #self.invalidate_rect(self.bounds[self.dragObject][0], self.bounds[self.dragObject][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT )
+ else:
+ #self.invalidate_rect( self.bounds[self.dragObject][0], self.bounds[self.dragObject][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT )
+ for i in self.outputMap[self.dragObject]:
+ self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3] )
+ for i in self.inputMap[self.dragObject]:
+ self.invalidate_rect( self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3] )
+
+ # NOTE: select function invalidates the rect so no need to do it above
+ self.select( self.dragObject )
+
+ self.dragObject = None
+ self.handleSaveTemp()
+
+ def updateBounds( self, i ):
+ self.bounds[i][0] = self.locations[i][0]-SynthLabConstants.HALF_SIZE
+ self.bounds[i][1] = self.locations[i][1]-SynthLabConstants.HALF_SIZE
+ self.bounds[i][2] = self.locations[i][0]+SynthLabConstants.HALF_SIZE
+ self.bounds[i][3] = self.locations[i][1]+SynthLabConstants.HALF_SIZE
+
+ for c in self.outputMap[i]:
+ self.updateConnection( c )
+ for c in self.inputMap[i]:
+ self.updateConnection( c )
+
+ def updateConnection( self, i ):
+ c = self.connections[i]
+ oT = c[0][0]//4
+ x1 = self.locations[c[0][0]][0] + self.gateMap[oT][c[0][1]][c[0][2]][4][0]
+ y1 = self.locations[c[0][0]][1] + self.gateMap[oT][c[0][1]][c[0][2]][4][1]
+ oT = c[1][0]//4
+ x2 = self.locations[c[1][0]][0] + self.gateMap[oT][c[1][1]][c[1][2]][4][0]
+ y2 = self.locations[c[1][0]][1] + self.gateMap[oT][c[1][1]][c[1][2]][4][1]
+ self.cPoints[i][0], self.cPoints[i][1], self.cPoints[i][2], self.cPoints[i][3] = ( x1, y1, x2, y2 )
+ if x1 > x2: x1, x2 = ( x2, x1 )
+ if y1 > y2: y1, y2 = ( y2, y1 )
+ self.cBounds[i][0], self.cBounds[i][1], self.cBounds[i][2], self.cBounds[i][3], self.cBounds[i][4], self.cBounds[i][5] = ( x1-self.lineWidth, y1-self.lineWidth, x2-x1+self.lineWidthMUL2, y2-y1+self.lineWidthMUL2, x2+self.lineWidth, y2+self.lineWidth )
+
+ def findRecursive( self, obj, target ):
+ if obj == target: return True
+ for c in self.outputMap[obj]:
+ if self.findRecursive( self.straightConnections[c][1], target ):
+ return True
+ return False
+
+ def testConnection( self, bObj, bGate, eObj, eGate ):
+ if self.gateMatch[bGate[0]] != eGate[0]:
+ return False # type mismatch
+
+ for c in self.inputMap[eObj]:
+ if self.connections[c][1][1] == eGate[0] \
+ and self.connections[c][1][2] == eGate[1] : # same type and port
+ if self.connections[c][0][0] == bObj:
+ return False # connections already exists
+
+ if self.findRecursive( eObj, bObj ):
+ return False # loop
+
+ return True
+
+ def newConnection( self, bObj, bGate, eObj, eGate ):
+ if not self.testConnection( bObj, bGate, eObj, eGate ):
+ return -1 # connection failed
+
+ ind = len(self.connections)
+ # connection format: [ ( outputObject, gate type, gate num ), ( inputObject, gate type, gate num ) ]
+ self.connections.append ( [ ( bObj, bGate[0], bGate[1] ),
+ ( eObj, eGate[0], eGate[1] ) ] )
+ self.straightConnections.append( ( bObj, eObj ) )
+ self.outputMap[bObj].append(ind)
+ self.inputMap[eObj].append(ind)
+ self.outputs.append( bObj )
+ self.cPoints.append( [ 0, 0, 0, 0 ] )
+ self.cBounds.append( [ 0, 0, 0, 0, 0, 0 ] )
+ self.updateConnection( ind )
+
+ self.updateSound()
+
+ self.handleSaveTemp()
+
+ return ind
+
+ def delConnection( self, i ):
+ b = self.straightConnections[i][0]
+ e = self.straightConnections[i][1]
+ self.straightConnections.pop(i)
+ self.outputMap[b].remove(i)
+ self.inputMap[e].remove(i)
+ self.outputs.pop(i)
+ self.cPoints.pop(i)
+ self.cBounds.pop(i)
+ self.connections.pop(i)
+ for o in range(self.objectCount):
+ for m in range(len(self.outputMap[o])):
+ if self.outputMap[o][m] > i: self.outputMap[o][m] -= 1
+ for m in range(len(self.inputMap[o])):
+ if self.inputMap[o][m] > i: self.inputMap[o][m] -= 1
+
+ self.updateSound()
+
+ self.handleSaveTemp()
+
+ def initializeConnections( self ):
+ self.straightConnections = []
+ self.outputMap = [ [] for i in self.locations ]
+ self.inputMap = [ [] for i in self.locations ]
+ self.outputs = []
+ self.cPoints = []
+ self.cBounds = []
+ for i in range(len(self.connections)):
+ c = self.connections[i]
+ first = c[0][0]
+ second = c[1][0]
+ self.straightConnections.append([first, second])
+ self.outputMap[first].append(i)
+ self.inputMap[second].append(i)
+ self.outputs.append(first)
+ self.cPoints.append( [ 0, 0, 0, 0 ] )
+ self.cBounds.append( [ 0, 0, 0, 0, 0, 0 ] )
+ self.updateConnection( i )
+
+ self.updateSound()
+
+ def predraw( self, buf ):
+ startX = self.screenBufDirtyRect.x
+ startY = self.screenBufDirtyRect.y
+ stopX = self.screenBufDirtyRect.x + self.screenBufDirtyRect.width
+ stopY = self.screenBufDirtyRect.y + self.screenBufDirtyRect.height
+
+ # draw bg
+ self.gc.foreground = self.bgColor
+ buf.draw_rectangle( self.gc, True, startX, startY, self.screenBufDirtyRect.width, self.screenBufDirtyRect.height )
+
+ # draw separator
+ self.gc.foreground = self.lineColor
+ buf.draw_line( self.gc, startX, 1, stopX, 1 )
+ buf.draw_line( self.gc, startX, self.separatorY, stopX, self.separatorY )
+
+ # draw objects
+ types = self.synthObjectsParameters.getTypes() + [0] # speaker
+ self.gc.set_clip_mask( self.clipMask )
+ for i in range(self.objectCount):
+ if i == self.dragObject or i == self.instanceID:
+ continue
+ if startX > self.bounds[i][2] or stopX < self.bounds[i][0] or startY > self.bounds[i][3] or stopY < self.bounds[i][1]:
+ continue
+ type = i >> 2
+ self.gc.set_clip_origin( self.bounds[i][0]-SynthLabConstants.PIC_SIZE*type, self.bounds[i][1] )
+ buf.draw_drawable( self.gc, self.pixmap[type][types[i]], 0, 0, self.bounds[i][0], self.bounds[i][1], SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE )
+
+ if self.dragObject != self.instanceID:
+ i = self.instanceID
+ type = i >> 2
+ #draw object
+ self.gc.set_clip_origin( self.bounds[i][0]-SynthLabConstants.PIC_SIZE*type, self.bounds[i][1] )
+ buf.draw_drawable( self.gc, self.pixmap[type][types[i]], 0, 0, self.bounds[i][0], self.bounds[i][1], SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE )
+ # draw selectionHighlight
+ self.gc.set_clip_origin( self.bounds[i][0]-SynthLabConstants.PIC_SIZE*type, self.bounds[i][1]-82 )
+ self.gc.foreground = self.highlightColor
+ buf.draw_rectangle( self.gc, True, self.bounds[i][0], self.bounds[i][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT )
+ self.gc.foreground = self.lineColor
+
+ self.gc.set_clip_rectangle( self.clearMask )
+
+ # draw wires
+ for c in range(len(self.connections)):
+ if self.straightConnections[c][0] == self.dragObject or self.straightConnections[c][1] == self.dragObject:
+ continue
+ if startX > self.cBounds[c][4] or stopX < self.cBounds[c][0] or startY > self.cBounds[c][5] or stopY < self.cBounds[c][1]:
+ continue
+ buf.draw_line( self.gc, self.cPoints[c][0], self.cPoints[c][1],
+ self.cPoints[c][2], self.cPoints[c][3] )
+
+ self.screenBufDirty = False
+
+ def draw( self, widget, event ):
+ #TP.ProfileBegin("SL::draw")
+ startX = event.area.x
+ startY = event.area.y
+ stopX = event.area.x + event.area.width
+ stopY = event.area.y + event.area.height
+
+ if self.screenBufDirty:
+ self.predraw( self.screenBuf )
+
+ # draw base
+ widget.window.draw_drawable( self.gc, self.screenBuf, startX, startY, startX, startY, event.area.width, event.area.height )
+
+ if self.action == "drag-object":
+ # draw dragObject
+ types = self.synthObjectsParameters.getTypes()
+ self.gc.set_clip_mask( self.clipMask )
+ type = self.dragObject >> 2
+ self.gc.set_clip_origin( self.bounds[self.dragObject][0]-SynthLabConstants.PIC_SIZE*type, self.bounds[self.dragObject][1] )
+ widget.window.draw_drawable( self.gc, self.pixmap[type][types[self.dragObject]], 0, 0, self.bounds[self.dragObject][0], self.bounds[self.dragObject][1], SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE )
+
+ if self.instanceID == self.dragObject:
+ # draw selectionHighlight
+ self.gc.set_clip_origin( self.bounds[self.dragObject][0]-SynthLabConstants.PIC_SIZE*type, self.bounds[self.dragObject][1]-82 )
+ self.gc.foreground = self.highlightColor
+ widget.window.draw_rectangle( self.gc, True, self.bounds[self.dragObject][0], self.bounds[self.dragObject][1]-2, SynthLabConstants.PIC_SIZE, SynthLabConstants.PIC_SIZE_HIGHLIGHT )
+
+ self.gc.set_clip_rectangle( self.clearMask )
+
+ # draw wires
+ if not self.potentialDisconnect:
+ self.gc.foreground = self.lineColor
+ for c in self.outputMap[self.dragObject]:
+ if startX > self.cBounds[c][4] or stopX < self.cBounds[c][0] or startY > self.cBounds[c][5] or stopY < self.cBounds[c][1]:
+ continue
+ widget.window.draw_line( self.gc, self.cPoints[c][0], self.cPoints[c][1],
+ self.cPoints[c][2], self.cPoints[c][3] )
+ for c in self.inputMap[self.dragObject]:
+ if startX > self.cBounds[c][4] or stopX < self.cBounds[c][0] or startY > self.cBounds[c][5] or stopY < self.cBounds[c][1]:
+ continue
+ widget.window.draw_line( self.gc, self.cPoints[c][0], self.cPoints[c][1],
+ self.cPoints[c][2], self.cPoints[c][3] )
+ elif self.action == "draw-wire":
+ # draw the wire
+ self.gc.foreground = self.lineColor
+ widget.window.draw_line( self.gc, self.wirePoint[0][0], self.wirePoint[0][1],
+ self.wirePoint[1][0], self.wirePoint[1][1] )
+
+ # draw highlights
+ if self.overWire != None:
+ self.gc.foreground = self.overWireColor
+ widget.window.draw_line( self.gc, self.cPoints[self.overWire][0], self.cPoints[self.overWire][1],
+ self.cPoints[self.overWire][2], self.cPoints[self.overWire][3] )
+ elif self.overGate != None:
+ self.gc.set_line_attributes( self.overLineWidth, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER )
+ if self.overGateReject:
+ self.gc.foreground = self.overGateRejectColor
+ widget.window.draw_line( self.gc, self.overGateLoc[0]+self.overLineWidth, self.overGateLoc[1]+self.overLineWidth, self.overGateLoc[0]+self.overGateSize-self.overLineWidth, self.overGateLoc[1]+self.overGateSize-self.overLineWidth )
+ widget.window.draw_line( self.gc, self.overGateLoc[0]+self.overLineWidth, self.overGateLoc[1]+self.overGateSize-self.overLineWidth, self.overGateLoc[0]+self.overGateSize-self.overLineWidth, self.overGateLoc[1]+self.overLineWidth )
+ else:
+ self.gc.foreground = self.overGateColor
+ widget.window.draw_arc( self.gc, False, self.overGateLoc[0]+self.overLineWidth, self.overGateLoc[1]+self.overLineWidth, self.overGateSize-self.overLineWidthMUL2, self.overGateSize-self.overLineWidthMUL2, 0, 23040 )
+ self.gc.set_line_attributes( self.lineWidth, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_BUTT, gtk.gdk.JOIN_MITER )
+
+ #print TP.ProfileEndAndPrint("SL::draw")
+ return True
+
+ def invalidate_rect( self, x, y, w, h, dirtyScreenBuf = True ):
+ self.dirtyRectToAdd.x = x
+ self.dirtyRectToAdd.y = y
+ self.dirtyRectToAdd.width = w
+ self.dirtyRectToAdd.height = h
+
+ if dirtyScreenBuf:
+ if self.screenBufDirty:
+ self.screenBufDirtyRect = self.screenBufDirtyRect.union(self.dirtyRectToAdd)
+ else:
+ self.screenBufDirtyRect.x = x
+ self.screenBufDirtyRect.y = y
+ self.screenBufDirtyRect.width = w
+ self.screenBufDirtyRect.height = h
+ self.screenBufDirty = True
+
+ if self.drawingArea.window != None:
+ self.drawingArea.window.invalidate_rect( self.dirtyRectToAdd, True )
+
+ self.dirty = True
+
+ def writeTables( self, typesTable, controlParametersTable, sourceParametersTable, fxParametersTable ):
+ mess = 'f5200 0 16 -2 ' + " ".join([str(n) for n in controlParametersTable])
+ self.csnd.inputMessage( mess )
+ time.sleep(0.001)
+ mess = "f5201 0 16 -2 " + " " .join([str(n) for n in sourceParametersTable])
+ self.csnd.inputMessage( mess )
+ time.sleep(.001)
+ mess = "f5202 0 16 -2 " + " " .join([str(n) for n in fxParametersTable])
+ self.csnd.inputMessage( mess )
+ time.sleep(.001)
+ self.typesTable = typesTable
+ lastTable = [0]*12
+ for i in range(12):
+ if i in self.outputs:
+ lastTable[i] = (typesTable[i]+1)
+ mess = "f5203 0 16 -2 " + " " .join([str(n) for n in lastTable]) + " 0 0 0 0"
+ self.csnd.inputMessage( mess )
+ time.sleep(.001)
+ if lastTable[4] == 8:
+ snd = Config.SOUNDS_DIR + '/' + self.sample_names[int(sourceParametersTable[1])]
+ mess = "f5501 0 32768 -1 " + "\"%s\" 0 0 0" % snd
+ self.csnd.inputMessage( mess )
+ if lastTable[5] == 8:
+ snd = Config.SOUNDS_DIR + '/' + self.sample_names[int(sourceParametersTable[5])]
+ mess = "f5502 0 32768 -1 " + "\"%s\" 0 0 0" % snd
+ self.csnd.inputMessage( mess )
+ if lastTable[6] == 8:
+ snd = Config.SOUNDS_DIR + '/' + self.sample_names[int(sourceParametersTable[9])]
+ mess = "f5503 0 32768 -1 " + "\"%s\" 0 0 0" % snd
+ self.csnd.inputMessage( mess )
+ if lastTable[7] == 8:
+ snd = Config.SOUNDS_DIR + '/' + self.sample_names[int(sourceParametersTable[13])]
+ mess = "f5504 0 32768 -1 " + "\"%s\" 0 0 0" % snd
+ self.csnd.inputMessage( mess )
+ time.sleep(.005)
+
+ def recordSound( self, widget, data ):
+ if widget.get_active() == True:
+ self.recordButton = widget
+ self.recordWait = 1
+ os.system('rm ' + Config.SNDS_DIR + '/lab' + str(data))
+ self.table = 85 + data
+ else:
+ self.recordWait = 0
+
+ def updateSound( self ):
+ self.controlToSrcConnections()
+ time.sleep(.01)
+ self.controlToFxConnections()
+ time.sleep(.01)
+ self.audioConnections()
+ time.sleep(.01)
+ lastTable = [0]*12
+ for i in range(12):
+ if i in self.outputs:
+ lastTable[i] = (self.synthObjectsParameters.types[i]+1)
+ mess = "f5203 0 16 -2 " + " " .join([str(n) for n in lastTable]) + " 0 0 0 0"
+ self.csnd.inputMessage( mess )
+ time.sleep(.01)
+
+ def updateTables( self ):
+ self.writeTables( self.synthObjectsParameters.types, self.synthObjectsParameters.controlsParameters, self.synthObjectsParameters.sourcesParameters, self.synthObjectsParameters.fxsParameters )
+
+ def controlToSrcConnections( self ):
+ self.contSrcConnections = []
+ for i in self.connections:
+ if i[0][0] < 4 and 3 < i[1][0] < 8:
+ offset = i[1][2]
+ self.contSrcConnections.append([i[0][0], i[1][0], offset])
+ table = [0 for i in range(16)]
+ sources = [source for source in range(4,8) if source in self.outputs]
+ for source in sources:
+ for entre in range(4):
+ value = sum([2**(li[0]+1) for li in self.contSrcConnections if li[1] == source and li[2] == entre], 1)
+ table[(source % 4) * 4 + entre] = value
+ mess = "f5204 0 16 -2 " + " " .join([str(n) for n in table])
+ self.csnd.inputMessage( mess )
+
+ def controlToFxConnections( self ):
+ self.contFxConnections = []
+ for i in self.connections:
+ if i[0][0] < 4 and 7 < i[1][0] < 12:
+ offset = i[1][2]
+ self.contFxConnections.append([i[0][0], i[1][0], offset])
+ table = [0 for i in range(16)]
+ fxs = [fx for fx in range(8,12) if fx in self.outputs]
+ for fx in fxs:
+ for entre in range(4):
+ value = sum([2**(li[0]+1) for li in self.contFxConnections if li[1] == fx and li[2] == entre], 1)
+ table[(fx % 4) * 4 + entre] = value
+ mess = "f5205 0 16 -2 " + " " .join([str(n) for n in table])
+ self.csnd.inputMessage( mess )
+
+ def audioConnections( self ):
+ self.srcFxConnections = [i for i in self.straightConnections if 3 < i[0] < 8 and 7 < i[1] < 12]
+ self.fxConnections = [i for i in self.straightConnections if 7 < i[0] < 12 and 7 < i[1] < 12]
+ self.outConnections = [i[0] for i in self.straightConnections if i[1] == 12]
+
+ table = []
+ for fx in range(8, 12):
+ value = 0
+ for li in self.srcFxConnections:
+ if li[1] == fx:
+ value += pow(2, li[0]-4)
+ table.append(value)
+
+ for fx in range(8, 12):
+ value = 0
+ for li in self.fxConnections:
+ if li[1] == fx:
+ value += pow(2, li[0]-8)
+ table.append(value)
+
+ for sig in range(4, 12):
+ value = 0
+ if sig in self.outConnections:
+ value = 1
+ table.append(value)
+ mess = "f5206 0 16 -2 " + " " .join([str(n) for n in table])
+ self.csnd.inputMessage( mess )
+
+ def loadPixmaps( self ):
+ win = gtk.gdk.get_default_root_window()
+ gc = gtk.gdk.GC( win )
+ gc.foreground = self.bgColor
+ self.pixmap = [ [], [], [], [] ]
+
+ def loadImg( type, img ):
+ pix = gtk.gdk.pixbuf_new_from_file(Config.TAM_TAM_ROOT + '/icons/sl-' + img + '.svg')
+ map = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() )
+ map.draw_rectangle( gc, True, 0, 0, pix.get_width(), pix.get_height() )
+ map.draw_pixbuf( gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE )
+ self.pixmap[type].append(map)
+
+ for i in range(len(SynthLabConstants.CONTROL_TYPES_PLUS)):
+ loadImg( 0, SynthLabConstants.CONTROL_TYPES_PLUS[i] )
+ for i in range(len(SynthLabConstants.SOURCE_TYPES_PLUS)):
+ loadImg( 1, SynthLabConstants.SOURCE_TYPES_PLUS[i] )
+ for i in range(len(SynthLabConstants.FX_TYPES_PLUS)):
+ loadImg( 2, SynthLabConstants.FX_TYPES_PLUS[i] )
+ loadImg( 3, "speaker" )
+
+ pix = gtk.gdk.pixbuf_new_from_file(Config.IMAGE_ROOT+'synthlabMask.png')
+ pixels = pix.get_pixels()
+ stride = pix.get_rowstride()
+ channels = pix.get_n_channels()
+ bitmap = ""
+ byte = 0
+ shift = 0
+ for j in range(pix.get_height()):
+ offset = stride*j
+ for i in range(pix.get_width()):
+ r = pixels[i*channels+offset]
+ if r != "\0": byte += 1 << shift
+ shift += 1
+ if shift > 7:
+ bitmap += "%c" % byte
+ byte = 0
+ shift = 0
+ if shift > 0:
+ bitmap += "%c" % byte
+ byte = 0
+ shift = 0
+ self.clipMask = gtk.gdk.bitmap_create_from_data( None, bitmap, pix.get_width(), pix.get_height() )
+
+ def handleSave(self, widget, data):
+ chooser = gtk.FileChooserDialog(title='Save SynthLab Preset',action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE,gtk.RESPONSE_OK))
+ filter = gtk.FileFilter()
+ filter.add_pattern('*.syn')
+ chooser.set_filter(filter)
+ chooser.set_current_folder(Config.SYNTH_DIR)
+
+ for f in chooser.list_shortcut_folder_uris():
+ chooser.remove_shortcut_folder_uri(f)
+
+ if chooser.run() == gtk.RESPONSE_OK:
+ ofilename = chooser.get_filename()
+ if ofilename[-4:] != '.syn':
+ ofilename += '.syn'
+ try:
+ print 'INFO: save SynthLab file %s' % chooser.get_filename()
+ f = shelve.open(ofilename, 'n')
+ self.saveState(f)
+ f.close()
+ except IOError:
+ print 'ERROR: failed to save SynthLab to file %s' % chooser.get_filename()
+
+ chooser.destroy()
+
+ def handleJournalSave(self, file_path):
+ f = shelve.open(file_path, 'n')
+ self.saveState(f)
+ f.close()
+
+ def handleLoad(self, widget, data):
+ chooser = gtk.FileChooserDialog(title='Load SynthLab Preset',action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
+
+ filter = gtk.FileFilter()
+ filter.add_pattern('*.syn')
+ chooser.set_filter(filter)
+ chooser.set_current_folder(Config.SYNTH_DIR)
+
+ for f in chooser.list_shortcut_folder_uris():
+ chooser.remove_shortcut_folder_uri(f)
+
+ if chooser.run() == gtk.RESPONSE_OK:
+ try:
+ print 'INFO: load SynthLab 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 SynthLab state from file %s' % chooser.get_filename()
+
+ chooser.destroy()
+
+ def handleJournalLoad(self, file_path):
+ f = shelve.open( file_path, 'r')
+ self.loadState(f)
+ f.close()
+
+ def handleSaveTemp( self ):
+ file = Config.PREF_DIR + '/synthTemp'
+ f = shelve.open(file, 'n')
+ self.saveState(f)
+ f.close()
+
+ def handleLoadTemp( self ):
+ file = Config.PREF_DIR + '/synthTemp'
+ f = shelve.open(file, 'r')
+ self.loadState(f)
+ f.close()
+
+ def saveState( self, state ):
+ state['types'] = self.synthObjectsParameters.types
+ state['controls'] = self.synthObjectsParameters.controlsParameters
+ state['sources'] = self.synthObjectsParameters.sourcesParameters
+ state['fxs'] = self.synthObjectsParameters.fxsParameters
+ state['envelope'] = self.synthObjectsParameters.outputParameters
+ state['locations'] = self.locations
+ state['connections'] = self.connections
+ state['duration'] = self.duration
+
+ def tempVerifyLocations(self):
+ for l in self.locations:
+ l[0] = int(l[0])
+ l[1] = int(l[1])
+
+ def tempVerifyConnectionFormat(self):
+ for c in self.connections:
+ if c[0][1] > 3 or c[0][2] > 3 \
+ or c[1][1] > 3 or c[1][2] > 3:
+ print "old format"
+ print c
+ i = c[0]
+ if i[1] == 0 and i[2] == 40:
+ if i[0] < 4: t,n = 0,0 # control output
+ else: t,n = 2,0 # sound output
+ else:
+ print "unhandled loc"
+ t,n = i[1],i[2]
+ c[0] = ( c[0][0], t, n )
+ i = c[1]
+ if i[1] == 0 and i[2] == -40: t,n = 3,0
+ elif i[1] == 40 and i[2] == -19: t,n = 1,0
+ elif i[1] == -25 and i[2] == -40: t,n = 1,0
+ elif i[1] == -9 and i[2] == -40: t,n = 1,1
+ elif i[1] == 8 and i[2] == -40: t,n = 1,2
+ elif i[1] == 25 and i[2] == -40: t,n = 1,3
+ else:
+ print "unhandled loc"
+ t,n = i[1],i[2]
+ c[1] = ( c[1][0], t, n )
+
+ def loadState( self, state ):
+ self.synthObjectsParameters.types = state['types']
+ self.synthObjectsParameters.controlsParameters = state['controls']
+ self.synthObjectsParameters.sourcesParameters = state['sources']
+ self.synthObjectsParameters.fxsParameters = state['fxs']
+ self.synthObjectsParameters.outputParameters = state['envelope']
+ self.locations = state['locations']
+ #self.tempVerifyLocations()
+ self.objectCount = len(self.locations)
+ for i in range(self.objectCount):
+ self.updateBounds( i )
+ self.connections = state['connections']
+ #self.tempVerifyConnectionFormat()
+ self.duration = state['duration']
+ self._mainToolbar.durationSliderAdj.set_value(self.duration)
+
+ self.initializeConnections()
+ self.controlToSrcConnections()
+ time.sleep(.01)
+ self.controlToFxConnections()
+ time.sleep(.01)
+ self.audioConnections()
+ time.sleep(.01)
+ self.synthObjectsParameters.update()
+ self.writeTables( self.synthObjectsParameters.types, self.synthObjectsParameters.controlsParameters, self.synthObjectsParameters.sourcesParameters, self.synthObjectsParameters.fxsParameters )
+ time.sleep(.01)
+ self.invalidate_rect( 0, 0, self.drawingAreaWidth, self.drawingAreaHeight )
+
+ def presetCallback( self, widget, data ):
+ preset = 'synthFile' + str(data)
+ f = shelve.open( Config.TAM_TAM_ROOT + '/Resources/SynthFiles/' + preset, 'r')
+ self.loadState(f)
+ f.close()
+ self.handleSaveTemp()
+
+ def initRadioButton( self, labelList, methodCallback, box ):
+ for i in range( len( labelList ) ):
+ label = labelList[i]
+ if i == 0:
+ button = ImageRadioButton( group = None, mainImg_path = Config.IMAGE_ROOT + label + '.png', altImg_path = Config.IMAGE_ROOT + label + 'sel.png' )
+ else:
+ button = ImageRadioButton( group = button, mainImg_path = Config.IMAGE_ROOT + label + '.png', altImg_path = Config.IMAGE_ROOT + label + 'sel.png' )
+ button.connect( "toggled", methodCallback, i )
+ box.pack_start( button, True, True )
diff --git a/TamTamSynthLab.activity/SynthLab/SynthObjectsParameters.py b/TamTamSynthLab.activity/SynthLab/SynthObjectsParameters.py
new file mode 100755
index 0000000..7a9b8f3
--- /dev/null
+++ b/TamTamSynthLab.activity/SynthLab/SynthObjectsParameters.py
@@ -0,0 +1,42 @@
+class SynthObjectsParameters:
+
+ def __init__( self ):
+ self.types = [0,0,0,0,0,0,0,0,0,0,0,0]
+ self.controlsParameters = [.5,1,0,0,.5,1,0,0,.5,1,0,0,.5,1,0,0]
+ self.sourcesParameters = [1,.5,5,1,1,.5,5,1,1,.5,5,1,1,.5,5,1]
+ self.fxsParameters = [100,3000,.8,1,100,3000,.8,1,100,3000,.8,1,100,3000,.8,1]
+ self.outputParameters = [.01, .05, .9, .05]
+ self.choiceParamsSet = [self.controlsParameters, self.sourcesParameters, self.fxsParameters, self.outputParameters]
+
+ def update( self ):
+ self.choiceParamsSet = [self.controlsParameters, self.sourcesParameters, self.fxsParameters, self.outputParameters]
+
+ def getTypes( self ):
+ return self.types
+
+ def getControlsParameters( self ):
+ return self.controlsParameters
+
+ def getSourcesParameters( self ):
+ return self.sourcesParameters
+
+ def getFxsParameters( self ):
+ return self.fxsParameters
+
+ def getOutputParameters( self ):
+ return self.outputParameters
+
+ def setType( self, pos, value ):
+ self.types[pos] = value
+
+ def setControlParameter( self, pos, value ):
+ self.controlsParameters[pos] = value
+
+ def setSourceParameter( self, pos, value ):
+ self.sourcesParameters[pos] = value
+
+ def setFxParameter( self, pos, value ):
+ self.fxsParameters[pos] = value
+
+ def setOutputParameter( self, pos, value ):
+ self.outputParameters[pos] = value
diff --git a/TamTamSynthLab.activity/SynthLab/__init__.py b/TamTamSynthLab.activity/SynthLab/__init__.py
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/TamTamSynthLab.activity/SynthLab/__init__.py
diff --git a/TamTamSynthLab.activity/TamTam.py b/TamTamSynthLab.activity/TamTam.py
new file mode 100644
index 0000000..e282df9
--- /dev/null
+++ b/TamTamSynthLab.activity/TamTam.py
@@ -0,0 +1,1229 @@
+import locale
+locale.setlocale(locale.LC_NUMERIC, 'C')
+import signal , time , sys , os, shutil
+import pygtk
+pygtk.require( '2.0' )
+import gtk
+
+import gobject
+import time
+
+import Config
+from Util.CSoundClient import new_csound_client
+from Util.Profiler import TP
+
+from Util.InstrumentPanel import InstrumentPanel
+from miniTamTam.miniTamTamMain import miniTamTamMain
+from Jam.JamMain import JamMain
+from Edit.MainWindow import MainWindow
+from Welcome import Welcome
+from SynthLab.SynthLabWindow import SynthLabWindow
+from Util.Trackpad import Trackpad
+from gettext import gettext as _
+#from Util.KeyboardWindow import KeyboardWindow
+import commands
+
+if __name__ != '__main__':
+ try:
+ from sugar.activity.activity import Activity
+ from sugar.activity import activity
+ FAKE_ACTIVITY = False
+ if Config.DEBUG: print 'using sugar Activity'
+ except ImportError:
+ from FActivity import FakeActivity as Activity
+ FAKE_ACTIVITY = True
+ if Config.DEBUG: print 'using fake activity'
+else:
+ from FActivity import FakeActivity as Activity
+ if Config.DEBUG: print 'using fake activity'
+
+
+class TamTam(Activity):
+ # TamTam is the topmost container in the TamTam application
+ # At all times it has one child, which may be one of
+ # - the welcome screen
+ # - the mini-tamtam
+ # - the synth lab
+ # - edit mode
+
+ def __init__(self, handle, mode='welcome'):
+ Activity.__init__(self, handle)
+ self.ensure_dirs()
+
+ color = gtk.gdk.color_parse(Config.WS_BCK_COLOR)
+ self.modify_bg(gtk.STATE_NORMAL, color)
+
+ self.set_title('TamTam')
+ self.set_resizable(False)
+
+ self.trackpad = Trackpad( self )
+ #self.keyboardWindow = KeyboardWindow(size = 8, popup = True)
+ #self.keyboardWindow.color_piano()
+
+ self.preloadTimeout = None
+
+ self.focusInHandler = self.connect('focus_in_event',self.onFocusIn)
+ self.focusOutHandler = self.connect('focus_out_event',self.onFocusOut)
+ self.connect('notify::active', self.onActive)
+ self.connect('destroy', self.onDestroy)
+ self.connect( "key-press-event", self.onKeyPress )
+ self.connect( "key-release-event", self.onKeyRelease )
+ #self.connect( "key-press-event", self.keyboardWindow.handle_keypress)
+ #self.connect( "key-release-event", self.keyboardWindow.handle_keyrelease)
+ #self.connect( "button-press-event", self.keyboardWindow.handle_mousePress)
+ #self.connect( "button-release-event", self.keyboardWindow.handle_mouseRelease)
+
+ self.mode = None
+ self.modeList = {}
+
+ self.instrumentPanel = InstrumentPanel( force_load = False )
+ self.preloadList = [ self.instrumentPanel ]
+
+ #load the sugar toolbar
+ self.toolbox = activity.ActivityToolbox(self)
+ self.set_toolbox(self.toolbox)
+
+ self.activity_toolbar = self.toolbox.get_activity_toolbar()
+ self.activity_toolbar.share.hide()
+ self.activity_toolbar.keep.hide()
+
+ self.toolbox.show()
+
+ if self._shared_activity: # if we're joining a shared activity force mini
+ self.set_mode("mini")
+ else:
+ self.set_mode(mode)
+
+ def onPreloadTimeout( self ):
+ if Config.DEBUG > 4: print "TamTam::onPreloadTimeout", self.preloadList
+
+ t = time.time()
+ if self.preloadList[0].load( t + 0.100 ): # finished preloading this object
+ self.preloadList.pop(0)
+ if not len(self.preloadList):
+ if Config.DEBUG > 1: print "TamTam::finished preloading", time.time() - t
+ self.preloadTimeout = False
+ return False # finished preloading everything
+
+ if Config.DEBUG > 4: print "TamTam::preload returned after", time.time() - t
+
+ return True
+
+ def doNothing(): #a callback function to appease SynthLab
+ pass
+
+ def set_mode(self, mode, arg = None):
+ if Config.DEBUG: print 'DEBUG: TamTam::set_mode from', self.mode, 'to', mode
+
+ if self.mode != None:
+ self.modeList[ self.mode ].onDeactivate()
+ if FAKE_ACTIVITY:
+ self.remove( self.modeList[ self.mode ] )
+
+ self.mode = None
+ self.trackpad.setContext(mode)
+
+ if mode == 'welcome':
+ if not (mode in self.modeList):
+ self.modeList[mode] = Welcome(self, self.set_mode)
+ self.mode = mode
+ #if len( self.preloadList ):
+ # self.preloadTimeout = gobject.timeout_add( 300, self.onPreloadTimeout )
+ elif self.preloadTimeout:
+ gobject.source_remove( self.preloadTimeout )
+ self.predrawTimeout = False
+
+ if mode == 'jam':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Jam'
+ self.modeList[mode] = JamMain(self, self.set_mode)
+ self.mode = mode
+
+ if mode == 'mini':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Mini'
+ self.modeList[mode] = miniTamTamMain(self, self.set_mode)
+ else:
+ self.modeList[mode].regenerate()
+ if self.instrumentPanel in self.preloadList:
+ self.instrumentPanel.load() # finish loading
+ self.modeList[mode].setInstrumentPanel( self.instrumentPanel )
+ self.mode = mode
+
+ if mode == 'edit':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Edit'
+ self.modeList[mode] = MainWindow(self, self.set_mode)
+ if self.instrumentPanel in self.preloadList:
+ self.instrumentPanel.load() # finish loading
+ self.modeList[mode].setInstrumentPanel( self.instrumentPanel )
+ self.mode = mode
+
+ if mode == 'synth':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam SynthLab'
+ self.modeList[mode] = SynthLabWindow(self, self.set_mode, None)
+ self.mode = mode
+
+ if self.mode == None:
+ print 'DEBUG: TamTam::set_mode invalid mode:', mode
+ else:
+ try: # activity mode
+ self.set_canvas( self.modeList[ self.mode ] )
+ except: # fake mode
+ self.add( self.modeList[ self.mode ] )
+ self.modeList[ self.mode ].onActivate(arg)
+ self.show()
+
+ def onFocusIn(self, event, data=None):
+ if Config.DEBUG > 3: print 'DEBUG: TamTam::onFocusOut in TamTam.py'
+ csnd = new_csound_client()
+ csnd.connect(True)
+ if self.mode == 'synth':
+ self.modeList[ self.mode ].updateSound()
+ self.modeList[ self.mode ].updateTables()
+ #csnd.load_instruments()
+
+ def onFocusOut(self, event, data=None):
+ if Config.DEBUG > 3: print 'DEBUG: TamTam::onFocusOut in TamTam.py'
+ csnd = new_csound_client()
+ csnd.connect(False)
+
+ def onActive(self, widget = None, event = None):
+ pass
+
+ def onKeyPress(self, widget, event):
+ if Config.DEBUG > 5: print 'DEBUG: TamTam::onKeyPress in TamTam.py'
+ #print "-----", event.keyval, event.string, event.hardware_keycode
+ if event.state == gtk.gdk.MOD1_MASK:
+ key = event.keyval
+ if key == gtk.keysyms.j:
+ self.set_mode("jam")
+ return
+ elif key == gtk.keysyms.m:
+ self.set_mode('mini')
+ return
+ elif key == gtk.keysyms.s:
+ self.set_mode('synth')
+ return
+ elif key == gtk.keysyms.w:
+ self.set_mode('welcome')
+ return
+ elif key == gtk.keysyms.e:
+ self.set_mode('edit')
+ return
+ elif key == gtk.keysyms.t:
+ self.toolbox.show()
+ return
+ elif key == gtk.keysyms.y:
+ self.toolbox.hide()
+ if self.mode:
+ self.modeList[ self.mode ].onKeyPress(widget, event)
+
+ def onKeyRelease(self, widget, event):
+ if Config.DEBUG > 5: print 'DEBUG: TamTam::onKeyRelease in TamTam.py'
+ self.modeList[ self.mode ].onKeyRelease(widget, event)
+ pass
+
+ def onDestroy(self, arg2):
+ if Config.DEBUG: print 'DEBUG: TamTam::onDestroy()'
+ os.system('rm -f ' + Config.PREF_DIR + '/synthTemp*')
+
+ for m in self.modeList:
+ if self.modeList[m] != None:
+ self.modeList[m].onDestroy()
+
+ csnd = new_csound_client()
+ csnd.connect(False)
+ csnd.destroy()
+
+ gtk.main_quit()
+
+ def ensure_dir(self, dir, perms=0777, rw=os.R_OK|os.W_OK):
+ if not os.path.isdir( dir ):
+ try:
+ os.makedirs(dir, perms)
+ except OSError, e:
+ print 'ERROR: failed to make dir %s: %i (%s)\n' % (dir, e.errno, e.strerror)
+ if not os.access(dir, rw):
+ print 'ERROR: directory %s is missing required r/w access\n' % dir
+
+ def ensure_dirs(self):
+ self.ensure_dir(Config.TUNE_DIR)
+ self.ensure_dir(Config.SYNTH_DIR)
+ self.ensure_dir(Config.SNDS_DIR)
+ self.ensure_dir(Config.SCRATCH_DIR)
+
+ if not os.path.isdir(Config.PREF_DIR):
+ os.mkdir(Config.PREF_DIR)
+ os.system('chmod 0777 ' + Config.PREF_DIR + ' &')
+ for snd in ['mic1','mic2','mic3','mic4','lab1','lab2','lab3','lab4', 'lab5', 'lab6']:
+ shutil.copyfile(Config.SOUNDS_DIR + '/' + snd , Config.SNDS_DIR + '/' + snd)
+ os.system('chmod 0777 ' + Config.SNDS_DIR + '/' + snd + ' &')
+
+ def read_file(self,file_path):
+ subactivity_name = self.metadata['tamtam_subactivity']
+ if subactivity_name == 'edit' \
+ or subactivity_name == 'synth' \
+ or subactivity_name == 'jam':
+ self.set_mode(subactivity_name)
+ self.modeList[subactivity_name].handleJournalLoad(file_path)
+ elif subactivity_name == 'mini':
+ self.set_mode(subactivity_name)
+ else:
+ return
+
+ def write_file(self,file_path):
+ if self.mode == 'edit':
+ self.metadata['tamtam_subactivity'] = self.mode
+ self.modeList[self.mode].handleJournalSave(file_path)
+ elif self.mode == 'synth':
+ self.metadata['tamtam_subactivity'] = self.mode
+ self.modeList[self.mode].handleJournalSave(file_path)
+ elif self.mode == 'mini':
+ self.metadata['tamtam_subactivity'] = self.mode
+ f = open(file_path,'w')
+ f.close()
+ elif self.mode == 'jam':
+ self.metadata['tamtam_subactivity'] = self.mode
+ self.modeList[self.mode].handleJournalSave(file_path)
+
+class TamTamJam(Activity):
+ # TamTam is the topmost container in the TamTam application
+ # At all times it has one child, which may be one of
+ # - the welcome screen
+ # - the mini-tamtam
+ # - the synth lab
+ # - edit mode
+
+ def __init__(self, handle, mode='welcome'):
+ Activity.__init__(self, handle)
+ self.ensure_dirs()
+
+ color = gtk.gdk.color_parse(Config.WS_BCK_COLOR)
+ self.modify_bg(gtk.STATE_NORMAL, color)
+
+ self.set_title('TamTam Jam')
+ self.set_resizable(False)
+
+ self.trackpad = Trackpad( self )
+ #self.keyboardWindow = KeyboardWindow(size = 8, popup = True)
+ #self.keyboardWindow.color_piano()
+
+ self.preloadTimeout = None
+
+ self.focusInHandler = self.connect('focus_in_event',self.onFocusIn)
+ self.focusOutHandler = self.connect('focus_out_event',self.onFocusOut)
+ self.connect('notify::active', self.onActive)
+ self.connect('destroy', self.onDestroy)
+ self.connect( "key-press-event", self.onKeyPress )
+ self.connect( "key-release-event", self.onKeyRelease )
+ #self.connect( "key-press-event", self.keyboardWindow.handle_keypress)
+ #self.connect( "key-release-event", self.keyboardWindow.handle_keyrelease)
+ #self.connect( "button-press-event", self.keyboardWindow.handle_mousePress)
+ #self.connect( "button-release-event", self.keyboardWindow.handle_mouseRelease)
+
+ self.mode = None
+ self.modeList = {}
+
+ self.instrumentPanel = InstrumentPanel( force_load = False )
+ self.preloadList = [ self.instrumentPanel ]
+
+ #load the sugar toolbar
+ self.toolbox = activity.ActivityToolbox(self)
+ self.set_toolbox(self.toolbox)
+
+ self.activity_toolbar = self.toolbox.get_activity_toolbar()
+ self.activity_toolbar.share.hide()
+ self.activity_toolbar.keep.hide()
+
+ self.toolbox.show()
+
+ self.set_mode("jam")
+
+ def onPreloadTimeout( self ):
+ if Config.DEBUG > 4: print "TamTam::onPreloadTimeout", self.preloadList
+
+ t = time.time()
+ if self.preloadList[0].load( t + 0.100 ): # finished preloading this object
+ self.preloadList.pop(0)
+ if not len(self.preloadList):
+ if Config.DEBUG > 1: print "TamTam::finished preloading", time.time() - t
+ self.preloadTimeout = False
+ return False # finished preloading everything
+
+ if Config.DEBUG > 4: print "TamTam::preload returned after", time.time() - t
+
+ return True
+
+ def doNothing(): #a callback function to appease SynthLab
+ pass
+
+ def set_mode(self, mode, arg = None):
+ if Config.DEBUG: print 'DEBUG: TamTam::set_mode from', self.mode, 'to', mode
+
+ if self.mode != None:
+ self.modeList[ self.mode ].onDeactivate()
+ if FAKE_ACTIVITY:
+ self.remove( self.modeList[ self.mode ] )
+
+ self.mode = None
+ self.trackpad.setContext(mode)
+
+ if mode == 'welcome':
+ if not (mode in self.modeList):
+ self.modeList[mode] = Welcome(self, self.set_mode)
+ self.mode = mode
+ if len( self.preloadList ):
+ self.preloadTimeout = gobject.timeout_add( 300, self.onPreloadTimeout )
+ elif self.preloadTimeout:
+ gobject.source_remove( self.preloadTimeout )
+ self.predrawTimeout = False
+
+ if mode == 'jam':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Jam'
+ self.modeList[mode] = JamMain(self, self.set_mode)
+ self.mode = mode
+
+ if mode == 'mini':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Mini'
+ self.modeList[mode] = miniTamTamMain(self, self.set_mode)
+ else:
+ self.modeList[mode].regenerate()
+ if self.instrumentPanel in self.preloadList:
+ self.instrumentPanel.load() # finish loading
+ self.modeList[mode].setInstrumentPanel( self.instrumentPanel )
+ self.mode = mode
+
+ if mode == 'edit':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Edit'
+ self.modeList[mode] = MainWindow(self, self.set_mode)
+ if self.instrumentPanel in self.preloadList:
+ self.instrumentPanel.load() # finish loading
+ self.modeList[mode].setInstrumentPanel( self.instrumentPanel )
+ self.mode = mode
+
+ if mode == 'synth':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam SynthLab'
+ self.modeList[mode] = SynthLabWindow(self, self.set_mode, None)
+ self.mode = mode
+
+ if self.mode == None:
+ print 'DEBUG: TamTam::set_mode invalid mode:', mode
+ else:
+ try: # activity mode
+ self.set_canvas( self.modeList[ self.mode ] )
+ except: # fake mode
+ self.add( self.modeList[ self.mode ] )
+ self.modeList[ self.mode ].onActivate(arg)
+ self.show()
+
+ def onFocusIn(self, event, data=None):
+ if Config.DEBUG > 3: print 'DEBUG: TamTam::onFocusOut in TamTam.py'
+ csnd = new_csound_client()
+ csnd.connect(True)
+ if self.mode == 'synth':
+ self.modeList[ self.mode ].updateSound()
+ self.modeList[ self.mode ].updateTables()
+ #csnd.load_instruments()
+
+ def onFocusOut(self, event, data=None):
+ if Config.DEBUG > 3: print 'DEBUG: TamTam::onFocusOut in TamTam.py'
+ csnd = new_csound_client()
+ csnd.connect(False)
+
+ def onActive(self, widget = None, event = None):
+ pass
+
+ def onKeyPress(self, widget, event):
+ if Config.DEBUG > 5: print 'DEBUG: TamTam::onKeyPress in TamTam.py'
+ if event.state == gtk.gdk.MOD1_MASK:
+ key = event.keyval
+ if key == gtk.keysyms.j:
+ self.set_mode("jam")
+ return
+ elif key == gtk.keysyms.m:
+ self.set_mode('mini')
+ return
+ elif key == gtk.keysyms.s:
+ self.set_mode('synth')
+ return
+ elif key == gtk.keysyms.w:
+ self.set_mode('welcome')
+ return
+ elif key == gtk.keysyms.e:
+ self.set_mode('edit')
+ return
+ elif key == gtk.keysyms.t:
+ self.toolbox.show()
+ return
+ elif key == gtk.keysyms.y:
+ self.toolbox.hide()
+ if self.mode:
+ self.modeList[ self.mode ].onKeyPress(widget, event)
+
+ def onKeyRelease(self, widget, event):
+ if Config.DEBUG > 5: print 'DEBUG: TamTam::onKeyRelease in TamTam.py'
+ self.modeList[ self.mode ].onKeyRelease(widget, event)
+ pass
+
+ def onDestroy(self, arg2):
+ if Config.DEBUG: print 'DEBUG: TamTam::onDestroy()'
+ os.system('rm -f ' + Config.PREF_DIR + '/synthTemp*')
+
+ for m in self.modeList:
+ if self.modeList[m] != None:
+ self.modeList[m].onDestroy()
+
+ csnd = new_csound_client()
+ csnd.connect(False)
+ csnd.destroy()
+
+ gtk.main_quit()
+
+ def ensure_dir(self, dir, perms=0777, rw=os.R_OK|os.W_OK):
+ if not os.path.isdir( dir ):
+ try:
+ os.makedirs(dir, perms)
+ except OSError, e:
+ print 'ERROR: failed to make dir %s: %i (%s)\n' % (dir, e.errno, e.strerror)
+ if not os.access(dir, rw):
+ print 'ERROR: directory %s is missing required r/w access\n' % dir
+
+ def ensure_dirs(self):
+ self.ensure_dir(Config.TUNE_DIR)
+ self.ensure_dir(Config.SYNTH_DIR)
+ self.ensure_dir(Config.SNDS_DIR)
+ self.ensure_dir(Config.SCRATCH_DIR)
+
+ if not os.path.isdir(Config.PREF_DIR):
+ os.mkdir(Config.PREF_DIR)
+ os.system('chmod 0777 ' + Config.PREF_DIR + ' &')
+ for snd in ['mic1','mic2','mic3','mic4','lab1','lab2','lab3','lab4', 'lab5', 'lab6']:
+ shutil.copyfile(Config.SOUNDS_DIR + '/' + snd , Config.SNDS_DIR + '/' + snd)
+ os.system('chmod 0777 ' + Config.SNDS_DIR + '/' + snd + ' &')
+
+ def read_file(self,file_path):
+ self.modeList['jam'].handleJournalLoad(file_path)
+
+ def write_file(self,file_path):
+ self.modeList['jam'].handleJournalSave(file_path)
+
+class TamTamEdit(Activity):
+ # TamTam is the topmost container in the TamTam application
+ # At all times it has one child, which may be one of
+ # - the welcome screen
+ # - the mini-tamtam
+ # - the synth lab
+ # - edit mode
+
+ def __init__(self, handle, mode='edit'):
+ Activity.__init__(self, handle)
+ self.ensure_dirs()
+
+ color = gtk.gdk.color_parse(Config.WS_BCK_COLOR)
+ self.modify_bg(gtk.STATE_NORMAL, color)
+
+ self.set_title('TamTam Edit')
+ self.set_resizable(False)
+
+ self.trackpad = Trackpad( self )
+ #self.keyboardWindow = KeyboardWindow(size = 8, popup = True)
+ #self.keyboardWindow.color_piano()
+
+ self.preloadTimeout = None
+
+ self.focusInHandler = self.connect('focus_in_event',self.onFocusIn)
+ self.focusOutHandler = self.connect('focus_out_event',self.onFocusOut)
+ self.connect('notify::active', self.onActive)
+ self.connect('destroy', self.onDestroy)
+ self.connect( "key-press-event", self.onKeyPress )
+ self.connect( "key-release-event", self.onKeyRelease )
+ #self.connect( "key-press-event", self.keyboardWindow.handle_keypress)
+ #self.connect( "key-release-event", self.keyboardWindow.handle_keyrelease)
+ #self.connect( "button-press-event", self.keyboardWindow.handle_mousePress)
+ #self.connect( "button-release-event", self.keyboardWindow.handle_mouseRelease)
+
+ self.mode = None
+ self.modeList = {}
+
+ self.instrumentPanel = InstrumentPanel( force_load = False )
+ self.preloadList = [ self.instrumentPanel ]
+
+ #load the sugar toolbar
+ self.toolbox = activity.ActivityToolbox(self)
+ self.set_toolbox(self.toolbox)
+
+ self.activity_toolbar = self.toolbox.get_activity_toolbar()
+ self.activity_toolbar.share.hide()
+ self.activity_toolbar.keep.hide()
+
+ self.toolbox.show()
+
+ self.set_mode("edit")
+
+ def onPreloadTimeout( self ):
+ if Config.DEBUG > 4: print "TamTam::onPreloadTimeout", self.preloadList
+
+ t = time.time()
+ if self.preloadList[0].load( t + 0.100 ): # finished preloading this object
+ self.preloadList.pop(0)
+ if not len(self.preloadList):
+ if Config.DEBUG > 1: print "TamTam::finished preloading", time.time() - t
+ self.preloadTimeout = False
+ return False # finished preloading everything
+
+ if Config.DEBUG > 4: print "TamTam::preload returned after", time.time() - t
+
+ return True
+
+ def doNothing(): #a callback function to appease SynthLab
+ pass
+
+ def set_mode(self, mode, arg = None):
+ if Config.DEBUG: print 'DEBUG: TamTam::set_mode from', self.mode, 'to', mode
+
+ if self.mode != None:
+ self.modeList[ self.mode ].onDeactivate()
+ if FAKE_ACTIVITY:
+ self.remove( self.modeList[ self.mode ] )
+
+ self.mode = None
+ self.trackpad.setContext(mode)
+
+ if mode == 'welcome':
+ if not (mode in self.modeList):
+ self.modeList[mode] = Welcome(self, self.set_mode)
+ self.mode = mode
+ if len( self.preloadList ):
+ self.preloadTimeout = gobject.timeout_add( 300, self.onPreloadTimeout )
+ elif self.preloadTimeout:
+ gobject.source_remove( self.preloadTimeout )
+ self.predrawTimeout = False
+
+ if mode == 'jam':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Jam'
+ self.modeList[mode] = JamMain(self, self.set_mode)
+ self.mode = mode
+
+ if mode == 'mini':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Mini'
+ self.modeList[mode] = miniTamTamMain(self, self.set_mode)
+ else:
+ self.modeList[mode].regenerate()
+ if self.instrumentPanel in self.preloadList:
+ self.instrumentPanel.load() # finish loading
+ self.modeList[mode].setInstrumentPanel( self.instrumentPanel )
+ self.mode = mode
+
+ if mode == 'edit':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Edit'
+ self.modeList[mode] = MainWindow(self, self.set_mode)
+ if self.instrumentPanel in self.preloadList:
+ self.instrumentPanel.load() # finish loading
+ self.modeList[mode].setInstrumentPanel( self.instrumentPanel )
+ self.mode = mode
+
+ if mode == 'synth':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam SynthLab'
+ self.modeList[mode] = SynthLabWindow(self, self.set_mode, None)
+ self.mode = mode
+
+ if self.mode == None:
+ print 'DEBUG: TamTam::set_mode invalid mode:', mode
+ else:
+ try: # activity mode
+ self.set_canvas( self.modeList[ self.mode ] )
+ except: # fake mode
+ self.add( self.modeList[ self.mode ] )
+ self.modeList[ self.mode ].onActivate(arg)
+ self.show()
+
+ def onFocusIn(self, event, data=None):
+ if Config.DEBUG > 3: print 'DEBUG: TamTam::onFocusOut in TamTam.py'
+ csnd = new_csound_client()
+ csnd.connect(True)
+ if self.mode == 'synth':
+ self.modeList[ self.mode ].updateSound()
+ self.modeList[ self.mode ].updateTables()
+ #csnd.load_instruments()
+
+ def onFocusOut(self, event, data=None):
+ if Config.DEBUG > 3: print 'DEBUG: TamTam::onFocusOut in TamTam.py'
+ csnd = new_csound_client()
+ csnd.connect(False)
+
+ def onActive(self, widget = None, event = None):
+ pass
+
+ def onKeyPress(self, widget, event):
+ if Config.DEBUG > 5: print 'DEBUG: TamTam::onKeyPress in TamTam.py'
+ if event.state == gtk.gdk.MOD1_MASK:
+ key = event.keyval
+ if key == gtk.keysyms.j:
+ self.set_mode("jam")
+ return
+ elif key == gtk.keysyms.m:
+ self.set_mode('mini')
+ return
+ elif key == gtk.keysyms.s:
+ self.set_mode('synth')
+ return
+ elif key == gtk.keysyms.w:
+ self.set_mode('welcome')
+ return
+ elif key == gtk.keysyms.e:
+ self.set_mode('edit')
+ return
+ elif key == gtk.keysyms.t:
+ self.toolbox.show()
+ return
+ elif key == gtk.keysyms.y:
+ self.toolbox.hide()
+ if self.mode:
+ self.modeList[ self.mode ].onKeyPress(widget, event)
+
+ def onKeyRelease(self, widget, event):
+ if Config.DEBUG > 5: print 'DEBUG: TamTam::onKeyRelease in TamTam.py'
+ self.modeList[ self.mode ].onKeyRelease(widget, event)
+ pass
+
+ def onDestroy(self, arg2):
+ if Config.DEBUG: print 'DEBUG: TamTam::onDestroy()'
+ os.system('rm -f ' + Config.PREF_DIR + '/synthTemp*')
+
+ for m in self.modeList:
+ if self.modeList[m] != None:
+ self.modeList[m].onDestroy()
+
+ csnd = new_csound_client()
+ csnd.connect(False)
+ csnd.destroy()
+
+ gtk.main_quit()
+
+ def ensure_dir(self, dir, perms=0777, rw=os.R_OK|os.W_OK):
+ if not os.path.isdir( dir ):
+ try:
+ os.makedirs(dir, perms)
+ except OSError, e:
+ print 'ERROR: failed to make dir %s: %i (%s)\n' % (dir, e.errno, e.strerror)
+ if not os.access(dir, rw):
+ print 'ERROR: directory %s is missing required r/w access\n' % dir
+
+ def ensure_dirs(self):
+ self.ensure_dir(Config.TUNE_DIR)
+ self.ensure_dir(Config.SYNTH_DIR)
+ self.ensure_dir(Config.SNDS_DIR)
+ self.ensure_dir(Config.SCRATCH_DIR)
+
+ if not os.path.isdir(Config.PREF_DIR):
+ os.mkdir(Config.PREF_DIR)
+ os.system('chmod 0777 ' + Config.PREF_DIR + ' &')
+ for snd in ['mic1','mic2','mic3','mic4','lab1','lab2','lab3','lab4', 'lab5', 'lab6']:
+ shutil.copyfile(Config.SOUNDS_DIR + '/' + snd , Config.SNDS_DIR + '/' + snd)
+ os.system('chmod 0777 ' + Config.SNDS_DIR + '/' + snd + ' &')
+
+ def read_file(self,file_path):
+ self.modeList['edit'].handleJournalLoad(file_path)
+
+ def write_file(self,file_path):
+ self.modeList['edit'].handleJournalSave(file_path)
+
+class TamTamSynthLab(Activity):
+ # TamTam is the topmost container in the TamTam application
+ # At all times it has one child, which may be one of
+ # - the welcome screen
+ # - the mini-tamtam
+ # - the synth lab
+ # - edit mode
+
+ def __init__(self, handle, mode='synth'):
+ Activity.__init__(self, handle)
+ self.ensure_dirs()
+
+ color = gtk.gdk.color_parse(Config.WS_BCK_COLOR)
+ self.modify_bg(gtk.STATE_NORMAL, color)
+
+ self.set_title('TamTam SynthLab')
+ self.set_resizable(False)
+
+ self.trackpad = Trackpad( self )
+ #self.keyboardWindow = KeyboardWindow(size = 8, popup = True)
+ #self.keyboardWindow.color_piano()
+
+ self.preloadTimeout = None
+
+ self.focusInHandler = self.connect('focus_in_event',self.onFocusIn)
+ self.focusOutHandler = self.connect('focus_out_event',self.onFocusOut)
+ self.connect('notify::active', self.onActive)
+ self.connect('destroy', self.onDestroy)
+ self.connect( "key-press-event", self.onKeyPress )
+ self.connect( "key-release-event", self.onKeyRelease )
+ #self.connect( "key-press-event", self.keyboardWindow.handle_keypress)
+ #self.connect( "key-release-event", self.keyboardWindow.handle_keyrelease)
+ #self.connect( "button-press-event", self.keyboardWindow.handle_mousePress)
+ #self.connect( "button-release-event", self.keyboardWindow.handle_mouseRelease)
+
+ self.mode = None
+ self.modeList = {}
+
+ self.instrumentPanel = InstrumentPanel( force_load = False )
+ self.preloadList = [ self.instrumentPanel ]
+
+ #load the sugar toolbar
+ self.toolbox = activity.ActivityToolbox(self)
+ self.set_toolbox(self.toolbox)
+
+ self.activity_toolbar = self.toolbox.get_activity_toolbar()
+ self.activity_toolbar.share.hide()
+ self.activity_toolbar.keep.hide()
+
+ self.toolbox.show()
+
+ self.set_mode("synth")
+
+ def onPreloadTimeout( self ):
+ if Config.DEBUG > 4: print "TamTam::onPreloadTimeout", self.preloadList
+
+ t = time.time()
+ if self.preloadList[0].load( t + 0.100 ): # finished preloading this object
+ self.preloadList.pop(0)
+ if not len(self.preloadList):
+ if Config.DEBUG > 1: print "TamTam::finished preloading", time.time() - t
+ self.preloadTimeout = False
+ return False # finished preloading everything
+
+ if Config.DEBUG > 4: print "TamTam::preload returned after", time.time() - t
+
+ return True
+
+ def doNothing(): #a callback function to appease SynthLab
+ pass
+
+ def set_mode(self, mode, arg = None):
+ if Config.DEBUG: print 'DEBUG: TamTam::set_mode from', self.mode, 'to', mode
+
+ if self.mode != None:
+ self.modeList[ self.mode ].onDeactivate()
+ if FAKE_ACTIVITY:
+ self.remove( self.modeList[ self.mode ] )
+
+ self.mode = None
+ self.trackpad.setContext(mode)
+
+ if mode == 'welcome':
+ if not (mode in self.modeList):
+ self.modeList[mode] = Welcome(self, self.set_mode)
+ self.mode = mode
+ if len( self.preloadList ):
+ self.preloadTimeout = gobject.timeout_add( 300, self.onPreloadTimeout )
+ elif self.preloadTimeout:
+ gobject.source_remove( self.preloadTimeout )
+ self.predrawTimeout = False
+
+ if mode == 'jam':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Jam'
+ self.modeList[mode] = JamMain(self, self.set_mode)
+ self.mode = mode
+
+ if mode == 'mini':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Mini'
+ self.modeList[mode] = miniTamTamMain(self, self.set_mode)
+ else:
+ self.modeList[mode].regenerate()
+ if self.instrumentPanel in self.preloadList:
+ self.instrumentPanel.load() # finish loading
+ self.modeList[mode].setInstrumentPanel( self.instrumentPanel )
+ self.mode = mode
+
+ if mode == 'edit':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Edit'
+ self.modeList[mode] = MainWindow(self, self.set_mode)
+ if self.instrumentPanel in self.preloadList:
+ self.instrumentPanel.load() # finish loading
+ self.modeList[mode].setInstrumentPanel( self.instrumentPanel )
+ self.mode = mode
+
+ if mode == 'synth':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam SynthLab'
+ self.modeList[mode] = SynthLabWindow(self, self.set_mode, None)
+ self.mode = mode
+
+ if self.mode == None:
+ print 'DEBUG: TamTam::set_mode invalid mode:', mode
+ else:
+ try: # activity mode
+ self.set_canvas( self.modeList[ self.mode ] )
+ except: # fake mode
+ self.add( self.modeList[ self.mode ] )
+ self.modeList[ self.mode ].onActivate(arg)
+ self.show()
+
+ def onFocusIn(self, event, data=None):
+ if Config.DEBUG > 3: print 'DEBUG: TamTam::onFocusOut in TamTam.py'
+ csnd = new_csound_client()
+ csnd.connect(True)
+ if self.mode == 'synth':
+ self.modeList[ self.mode ].updateSound()
+ self.modeList[ self.mode ].updateTables()
+ #csnd.load_instruments()
+
+ def onFocusOut(self, event, data=None):
+ if Config.DEBUG > 3: print 'DEBUG: TamTam::onFocusOut in TamTam.py'
+ csnd = new_csound_client()
+ csnd.connect(False)
+
+ def onActive(self, widget = None, event = None):
+ pass
+
+ def onKeyPress(self, widget, event):
+ if Config.DEBUG > 5: print 'DEBUG: TamTam::onKeyPress in TamTam.py'
+ if event.state == gtk.gdk.MOD1_MASK:
+ key = event.keyval
+ if key == gtk.keysyms.j:
+ self.set_mode("jam")
+ return
+ elif key == gtk.keysyms.m:
+ self.set_mode('mini')
+ return
+ elif key == gtk.keysyms.s:
+ self.set_mode('synth')
+ return
+ elif key == gtk.keysyms.w:
+ self.set_mode('welcome')
+ return
+ elif key == gtk.keysyms.e:
+ self.set_mode('edit')
+ return
+ elif key == gtk.keysyms.t:
+ self.toolbox.show()
+ return
+ elif key == gtk.keysyms.y:
+ self.toolbox.hide()
+ if self.mode:
+ self.modeList[ self.mode ].onKeyPress(widget, event)
+
+ def onKeyRelease(self, widget, event):
+ if Config.DEBUG > 5: print 'DEBUG: TamTam::onKeyRelease in TamTam.py'
+ self.modeList[ self.mode ].onKeyRelease(widget, event)
+ pass
+
+ def onDestroy(self, arg2):
+ if Config.DEBUG: print 'DEBUG: TamTam::onDestroy()'
+ os.system('rm -f ' + Config.PREF_DIR + '/synthTemp*')
+
+ for m in self.modeList:
+ if self.modeList[m] != None:
+ self.modeList[m].onDestroy()
+
+ csnd = new_csound_client()
+ csnd.connect(False)
+ csnd.destroy()
+
+ gtk.main_quit()
+
+ def ensure_dir(self, dir, perms=0777, rw=os.R_OK|os.W_OK):
+ if not os.path.isdir( dir ):
+ try:
+ os.makedirs(dir, perms)
+ except OSError, e:
+ print 'ERROR: failed to make dir %s: %i (%s)\n' % (dir, e.errno, e.strerror)
+ if not os.access(dir, rw):
+ print 'ERROR: directory %s is missing required r/w access\n' % dir
+
+ def ensure_dirs(self):
+ self.ensure_dir(Config.TUNE_DIR)
+ self.ensure_dir(Config.SYNTH_DIR)
+ self.ensure_dir(Config.SNDS_DIR)
+ self.ensure_dir(Config.SCRATCH_DIR)
+
+ if not os.path.isdir(Config.PREF_DIR):
+ os.mkdir(Config.PREF_DIR)
+ os.system('chmod 0777 ' + Config.PREF_DIR + ' &')
+ for snd in ['mic1','mic2','mic3','mic4','lab1','lab2','lab3','lab4', 'lab5', 'lab6']:
+ shutil.copyfile(Config.SOUNDS_DIR + '/' + snd , Config.SNDS_DIR + '/' + snd)
+ os.system('chmod 0777 ' + Config.SNDS_DIR + '/' + snd + ' &')
+
+ def read_file(self,file_path):
+ self.modeList['synth'].handleJournalLoad(file_path)
+
+ def write_file(self,file_path):
+ self.modeList['synth'].handleJournalSave(file_path)
+
+class TamTamMini(Activity):
+ # TamTam is the topmost container in the TamTam application
+ # At all times it has one child, which may be one of
+ # - the welcome screen
+ # - the mini-tamtam
+ # - the synth lab
+ # - edit mode
+
+ def __init__(self, handle, mode='mini'):
+ Activity.__init__(self, handle)
+ self.ensure_dirs()
+
+ color = gtk.gdk.color_parse(Config.WS_BCK_COLOR)
+ self.modify_bg(gtk.STATE_NORMAL, color)
+
+ self.set_title('TamTam Mini')
+ self.set_resizable(False)
+
+ self.trackpad = Trackpad( self )
+ #self.keyboardWindow = KeyboardWindow(size = 8, popup = True)
+ #self.keyboardWindow.color_piano()
+
+ self.preloadTimeout = None
+
+ self.focusInHandler = self.connect('focus_in_event',self.onFocusIn)
+ self.focusOutHandler = self.connect('focus_out_event',self.onFocusOut)
+ self.connect('notify::active', self.onActive)
+ self.connect('destroy', self.onDestroy)
+ self.connect( "key-press-event", self.onKeyPress )
+ self.connect( "key-release-event", self.onKeyRelease )
+ #self.connect( "key-press-event", self.keyboardWindow.handle_keypress)
+ #self.connect( "key-release-event", self.keyboardWindow.handle_keyrelease)
+ #self.connect( "button-press-event", self.keyboardWindow.handle_mousePress)
+ #self.connect( "button-release-event", self.keyboardWindow.handle_mouseRelease)
+
+ self.mode = None
+ self.modeList = {}
+
+ self.instrumentPanel = InstrumentPanel( force_load = False )
+ self.preloadList = [ self.instrumentPanel ]
+
+ #load the sugar toolbar
+ self.toolbox = activity.ActivityToolbox(self)
+ self.set_toolbox(self.toolbox)
+
+ self.activity_toolbar = self.toolbox.get_activity_toolbar()
+ self.activity_toolbar.share.hide()
+ self.activity_toolbar.keep.hide()
+
+ self.toolbox.show()
+
+ self.set_mode("mini")
+
+ def onPreloadTimeout( self ):
+ if Config.DEBUG > 4: print "TamTam::onPreloadTimeout", self.preloadList
+
+ t = time.time()
+ if self.preloadList[0].load( t + 0.100 ): # finished preloading this object
+ self.preloadList.pop(0)
+ if not len(self.preloadList):
+ if Config.DEBUG > 1: print "TamTam::finished preloading", time.time() - t
+ self.preloadTimeout = False
+ return False # finished preloading everything
+
+ if Config.DEBUG > 4: print "TamTam::preload returned after", time.time() - t
+
+ return True
+
+ def doNothing(): #a callback function to appease SynthLab
+ pass
+
+ def set_mode(self, mode, arg = None):
+ if Config.DEBUG: print 'DEBUG: TamTam::set_mode from', self.mode, 'to', mode
+
+ if self.mode != None:
+ self.modeList[ self.mode ].onDeactivate()
+ if FAKE_ACTIVITY:
+ self.remove( self.modeList[ self.mode ] )
+
+ self.mode = None
+ self.trackpad.setContext(mode)
+
+ if mode == 'welcome':
+ if not (mode in self.modeList):
+ self.modeList[mode] = Welcome(self, self.set_mode)
+ self.mode = mode
+ if len( self.preloadList ):
+ self.preloadTimeout = gobject.timeout_add( 300, self.onPreloadTimeout )
+ elif self.preloadTimeout:
+ gobject.source_remove( self.preloadTimeout )
+ self.predrawTimeout = False
+
+ if mode == 'jam':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Jam'
+ self.modeList[mode] = JamMain(self, self.set_mode)
+ self.mode = mode
+
+ if mode == 'mini':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Mini'
+ self.modeList[mode] = miniTamTamMain(self, self.set_mode)
+ else:
+ self.modeList[mode].regenerate()
+ if self.instrumentPanel in self.preloadList:
+ self.instrumentPanel.load() # finish loading
+ self.modeList[mode].setInstrumentPanel( self.instrumentPanel )
+ self.mode = mode
+
+ if mode == 'edit':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Edit'
+ self.modeList[mode] = MainWindow(self, self.set_mode)
+ if self.instrumentPanel in self.preloadList:
+ self.instrumentPanel.load() # finish loading
+ self.modeList[mode].setInstrumentPanel( self.instrumentPanel )
+ self.mode = mode
+
+ if mode == 'synth':
+ if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam SynthLab'
+ self.modeList[mode] = SynthLabWindow(self, self.set_mode, None)
+ self.mode = mode
+
+ if self.mode == None:
+ print 'DEBUG: TamTam::set_mode invalid mode:', mode
+ else:
+ try: # activity mode
+ self.set_canvas( self.modeList[ self.mode ] )
+ except: # fake mode
+ self.add( self.modeList[ self.mode ] )
+ self.modeList[ self.mode ].onActivate(arg)
+ self.show()
+
+ def onFocusIn(self, event, data=None):
+ if Config.DEBUG > 3: print 'DEBUG: TamTam::onFocusOut in TamTam.py'
+ csnd = new_csound_client()
+ csnd.connect(True)
+ if self.mode == 'synth':
+ self.modeList[ self.mode ].updateSound()
+ self.modeList[ self.mode ].updateTables()
+ #csnd.load_instruments()
+
+ def onFocusOut(self, event, data=None):
+ if Config.DEBUG > 3: print 'DEBUG: TamTam::onFocusOut in TamTam.py'
+ csnd = new_csound_client()
+ csnd.connect(False)
+
+ def onActive(self, widget = None, event = None):
+ pass
+
+ def onKeyPress(self, widget, event):
+ if Config.DEBUG > 5: print 'DEBUG: TamTam::onKeyPress in TamTam.py'
+ if event.state == gtk.gdk.MOD1_MASK:
+ key = event.keyval
+ if key == gtk.keysyms.j:
+ self.set_mode("jam")
+ return
+ elif key == gtk.keysyms.m:
+ self.set_mode('mini')
+ return
+ elif key == gtk.keysyms.s:
+ self.set_mode('synth')
+ return
+ elif key == gtk.keysyms.w:
+ self.set_mode('welcome')
+ return
+ elif key == gtk.keysyms.e:
+ self.set_mode('edit')
+ return
+ elif key == gtk.keysyms.t:
+ self.toolbox.show()
+ return
+ elif key == gtk.keysyms.y:
+ self.toolbox.hide()
+ if self.mode:
+ self.modeList[ self.mode ].onKeyPress(widget, event)
+
+ def onKeyRelease(self, widget, event):
+ if Config.DEBUG > 5: print 'DEBUG: TamTam::onKeyRelease in TamTam.py'
+ self.modeList[ self.mode ].onKeyRelease(widget, event)
+ pass
+
+ def onDestroy(self, arg2):
+ if Config.DEBUG: print 'DEBUG: TamTam::onDestroy()'
+ os.system('rm -f ' + Config.PREF_DIR + '/synthTemp*')
+
+ for m in self.modeList:
+ if self.modeList[m] != None:
+ self.modeList[m].onDestroy()
+
+ csnd = new_csound_client()
+ csnd.connect(False)
+ csnd.destroy()
+
+ gtk.main_quit()
+
+ def ensure_dir(self, dir, perms=0777, rw=os.R_OK|os.W_OK):
+ if not os.path.isdir( dir ):
+ try:
+ os.makedirs(dir, perms)
+ except OSError, e:
+ print 'ERROR: failed to make dir %s: %i (%s)\n' % (dir, e.errno, e.strerror)
+ if not os.access(dir, rw):
+ print 'ERROR: directory %s is missing required r/w access\n' % dir
+
+ def ensure_dirs(self):
+ self.ensure_dir(Config.TUNE_DIR)
+ self.ensure_dir(Config.SYNTH_DIR)
+ self.ensure_dir(Config.SNDS_DIR)
+ self.ensure_dir(Config.SCRATCH_DIR)
+
+ if not os.path.isdir(Config.PREF_DIR):
+ os.mkdir(Config.PREF_DIR)
+ os.system('chmod 0777 ' + Config.PREF_DIR + ' &')
+ for snd in ['mic1','mic2','mic3','mic4','lab1','lab2','lab3','lab4', 'lab5', 'lab6']:
+ shutil.copyfile(Config.SOUNDS_DIR + '/' + snd , Config.SNDS_DIR + '/' + snd)
+ os.system('chmod 0777 ' + Config.SNDS_DIR + '/' + snd + ' &')
+
+ def read_file(self,file_path):
+ self.metadata['tamtam_subactivity'] = 'mini'
+
+ def write_file(self,file_path):
+ f = open(file_path,'w')
+ f.close()
+
+
+
+if __name__ == "__main__":
+ if len(sys.argv) > 1 :
+ mainwin = TamTam(None, sys.argv[1])
+ else:
+ mainwin = TamTam(None, 'welcome')
+
+ gtk.gdk.threads_init()
+ gtk.main()
+
+ sys.exit(0)
+
+
+
+
+
+
+
+
+ def run_edit_mode():
+ tamtam = MainWindow()
+ mainwin = gtk.Window(gtk.WINDOW_TOPLEVEL)
+ mainwin.set_title('TamTam Player')
+ display = mainwin.get_display()
+ screen = gtk.gdk.Display.get_default_screen(display)
+ mainwin.set_geometry_hints( None, screen.get_width(), screen.get_height(), screen.get_width(), screen.get_height(), screen.get_width(), screen.get_height() )
+ #mainwin.fullscreen() # don't need to specify full screen, it seem to sit properly anyway
+ mainwin.set_resizable(False)
+ mainwin.connect('destroy' , tamtam.destroy )
+ #mainwin.connect( "configure-event", tamtam.handleConfigureEvent )
+ mainwin.connect( "key-press-event", tamtam.onKeyPress )
+ mainwin.connect( "key-release-event", tamtam.onKeyRelease )
+ mainwin.connect( "delete_event", tamtam.delete_event )
+ mainwin.add(tamtam)
+ tamtam.show()
+ mainwin.show()
+ gtk.main()
diff --git a/TamTamSynthLab.activity/activity/activity-tamtamsynthlab.svg b/TamTamSynthLab.activity/activity/activity-tamtamsynthlab.svg
new file mode 100644
index 0000000..7e3feb6
--- /dev/null
+++ b/TamTamSynthLab.activity/activity/activity-tamtamsynthlab.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [
+ <!ENTITY stroke_color "#010101">
+ <!ENTITY fill_color "#FFFFFF">
+]><svg enable-background="new 0 0 55 55" height="55px" version="1.1" viewBox="0 0 55 55" width="55px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="0px"><g display="block" id="activity-synthlab">
+ <g display="inline">
+ <path d="M7.729,12.592 c0-2.215,3.275-4.948,5.925-4.948h28.149c2.648,0,5.925,2.734,5.925,4.948v18.347c0,9.233-8.953,16.705-20,16.705 c-11.048,0-19.999-7.475-19.999-16.705V12.592z" fill="&fill_color;" stroke="&stroke_color;" stroke-linecap="square" stroke-width="3.5"/>
+ <g>
+ <path d="M16.743,27.703c5.927-24.441,11.436,0,11.436,0 " fill="none" stroke="&stroke_color;" stroke-linecap="round" stroke-width="3.5"/>
+ <path d="M39.252,25.977 c-5.926,24.444-11.436,0-11.436,0" fill="none" stroke="&stroke_color;" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.5"/>
+ </g>
+ </g>
+</g></svg> \ No newline at end of file
diff --git a/TamTamSynthLab.activity/activity/activity.info b/TamTamSynthLab.activity/activity/activity.info
new file mode 100644
index 0000000..7a64eec
--- /dev/null
+++ b/TamTamSynthLab.activity/activity/activity.info
@@ -0,0 +1,6 @@
+[Activity]
+name = TamTamSynthLab
+service_name = org.laptop.TamTamSynthLab
+icon = activity-tamtamsynthlab
+class = TamTam.TamTamSynthLab
+activity_version = 40
diff --git a/TamTamSynthLab.activity/common b/TamTamSynthLab.activity/common
new file mode 120000
index 0000000..60d3b0a
--- /dev/null
+++ b/TamTamSynthLab.activity/common
@@ -0,0 +1 @@
+../common \ No newline at end of file
diff --git a/TamTamSynthLab.activity/icons/XYBut.svg b/TamTamSynthLab.activity/icons/XYBut.svg
new file mode 100644
index 0000000..54d7563
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/XYBut.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="30px" height="30px" viewBox="0 0 30 30" enable-background="new 0 0 30 30" xml:space="preserve">
+<g>
+ <circle fill="#808284" cx="15" cy="15" r="9.376"/>
+ <g>
+ <path fill="#FFFFFF" stroke="#808284" stroke-width="2.25" d="M21.5,14.998c0,3.584-2.915,6.502-6.499,6.502
+ c-3.584,0-6.501-2.918-6.501-6.502S11.417,8.5,15.001,8.5C18.585,8.5,21.5,11.413,21.5,14.998z M15.003,2
+ C7.832,2,2,7.831,2,14.998C2,22.165,7.832,28,15.003,28C22.168,28,28,22.165,28,14.998C28,7.831,22.168,2,15.003,2z"/>
+ </g>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/XYButDown.svg b/TamTamSynthLab.activity/icons/XYButDown.svg
new file mode 100644
index 0000000..201df5f
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/XYButDown.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="30px" height="30px" viewBox="0 0 30 30" enable-background="new 0 0 30 30" xml:space="preserve">
+<g>
+ <circle cx="15" cy="15" r="6.933"/>
+ <g>
+ <path fill="none" stroke="#808284" stroke-width="2.25" d="M21.5,14.998c0,3.585-2.915,6.502-6.499,6.502
+ c-3.584,0-6.501-2.917-6.501-6.502c0-3.584,2.917-6.498,6.501-6.498C18.585,8.5,21.5,11.414,21.5,14.998z M15.003,2
+ C7.832,2,2,7.831,2,14.998C2,22.165,7.832,28,15.003,28C22.169,28,28,22.165,28,14.998C28,7.831,22.169,2,15.003,2z"/>
+ </g>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/XYButDownClick.svg b/TamTamSynthLab.activity/icons/XYButDownClick.svg
new file mode 100644
index 0000000..9e0d222
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/XYButDownClick.svg
@@ -0,0 +1,12 @@
+<?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="30px" height="30px" viewBox="0 0 30 30" enable-background="new 0 0 30 30" xml:space="preserve">
+<circle fill="none" cx="15" cy="15" r="6.933"/>
+<g>
+ <path fill="none" stroke="#808284" stroke-width="2.25" d="M21.5,14.998c0,3.585-2.915,6.502-6.499,6.502
+ c-3.584,0-6.501-2.917-6.501-6.502c0-3.584,2.917-6.498,6.501-6.498C18.585,8.5,21.5,11.414,21.5,14.998z M15.003,2
+ C7.832,2,2,7.831,2,14.998C2,22.165,7.832,28,15.003,28C22.169,28,28,22.165,28,14.998C28,7.831,22.169,2,15.003,2z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/accept.svg b/TamTamSynthLab.activity/icons/accept.svg
new file mode 100755
index 0000000..a2f9e28
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/accept.svg
@@ -0,0 +1,18 @@
+<?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="45px" height="45px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<g>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#FFFFFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="
+ M5.78,28.079c0-12.43,10.071-22.499,22.499-22.499c12.431,0,22.501,10.069,22.501,22.499c0,12.431-10.07,22.501-22.501,22.501
+ C15.851,50.58,5.78,40.51,5.78,28.079z"/>
+</g>
+<g>
+
+ <line fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#FFFFFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" x1="16.788" y1="26.691" x2="25.781" y2="38.706"/>
+
+ <line fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#FFFFFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" x1="25.781" y1="38.706" x2="39.773" y2="18.704"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/cancel.svg b/TamTamSynthLab.activity/icons/cancel.svg
new file mode 100755
index 0000000..59512eb
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/cancel.svg
@@ -0,0 +1,11 @@
+<?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="45px" height="45px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#FFFFFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="
+ M5.78,28.08c0-12.431,10.071-22.5,22.5-22.5c12.432,0,22.5,10.069,22.5,22.5c0,12.432-10.068,22.5-22.5,22.5
+ C15.851,50.58,5.78,40.512,5.78,28.08z"/>
+<line fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#FFFFFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" x1="20.155" y1="19.956" x2="37.029" y2="36.83"/>
+<line fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#FFFFFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" x1="37.029" y1="19.956" x2="20.155" y2="36.83"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/preset1.svg b/TamTamSynthLab.activity/icons/preset1.svg
new file mode 100644
index 0000000..9673b82
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/preset1.svg
@@ -0,0 +1,12 @@
+<?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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<polygon fill="none" stroke="#FFFFFF" stroke-width="2" points="10.793,6.769 10.793,49.501 44.012,49.501 44.126,15.444
+ 35.45,6.996 "/>
+<polyline fill="#E6E3E1" stroke="#5D6060" stroke-width="2" points="35.334,7.043 35.334,15.753 44.168,15.753 "/>
+<g>
+ <path fill="#FFFFFF" d="M26.749,26.727h-0.036L24.48,27.79l-0.45-2.053l3.097-1.44h2.27V36h-2.647V26.727z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/preset10.svg b/TamTamSynthLab.activity/icons/preset10.svg
new file mode 100644
index 0000000..28e7082
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/preset10.svg
@@ -0,0 +1,15 @@
+<?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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<polygon fill="none" stroke="#FFFFFF" stroke-width="2" points="10.793,6.769 10.793,49.501 44.012,49.501 44.126,15.444
+ 35.45,6.996 "/>
+<polyline fill="#E6E3E1" stroke="#5D6060" stroke-width="2" points="35.334,7.042 35.334,15.753 44.166,15.753 "/>
+<g>
+ <path fill="#FFFFFF" d="M20.719,26.395h-0.036l-2.232,1.062l-0.449-2.053l3.097-1.439h2.27v11.704h-2.646v-9.273H20.719z"/>
+ <path fill="#FFFFFF" d="M35.858,29.762c0,3.619-1.458,6.104-4.447,6.104c-3.023,0-4.356-2.719-4.375-6.031
+ c0-3.386,1.44-6.067,4.467-6.067C34.635,23.766,35.858,26.557,35.858,29.762z M29.791,29.834c-0.018,2.683,0.631,3.962,1.692,3.962
+ c1.062,0,1.639-1.333,1.639-3.998c0-2.593-0.559-3.961-1.655-3.961C30.457,25.836,29.773,27.114,29.791,29.834z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/preset2.svg b/TamTamSynthLab.activity/icons/preset2.svg
new file mode 100644
index 0000000..f376c67
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/preset2.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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<polygon fill="none" stroke="#FFFFFF" stroke-width="2" points="10.793,6.769 10.793,49.501 44.012,49.501 44.126,15.444
+ 35.45,6.996 "/>
+<polyline fill="#E6E3E1" stroke="#5D6060" stroke-width="2" points="35.334,7.042 35.334,15.753 44.166,15.753 "/>
+<g>
+ <path fill="#FFFFFF" d="M22.922,35.168v-1.656l1.513-1.368c2.557-2.287,3.799-3.602,3.835-4.97c0-0.955-0.576-1.711-1.927-1.711
+ c-1.008,0-1.891,0.504-2.502,0.973l-0.774-1.963c0.882-0.666,2.251-1.206,3.835-1.206c2.646,0,4.105,1.548,4.105,3.673
+ c0,1.963-1.423,3.529-3.115,5.042l-1.08,0.9v0.035h4.411v2.251H22.922z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/preset3.svg b/TamTamSynthLab.activity/icons/preset3.svg
new file mode 100644
index 0000000..a22bb3c
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/preset3.svg
@@ -0,0 +1,16 @@
+<?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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<polygon fill="none" stroke="#FFFFFF" stroke-width="2" points="10.793,6.769 10.793,49.501 44.012,49.501 44.126,15.444
+ 35.45,6.996 "/>
+<polyline fill="#E6E3E1" stroke="#5D6060" stroke-width="2" points="35.334,7.042 35.334,15.753 44.166,15.753 "/>
+<g>
+ <path fill="#FFFFFF" d="M23.909,32.65c0.486,0.252,1.604,0.72,2.72,0.72c1.423,0,2.143-0.684,2.143-1.565
+ c0-1.152-1.152-1.674-2.358-1.674h-1.115v-1.963h1.062c0.918-0.019,2.088-0.36,2.088-1.352c0-0.702-0.576-1.224-1.729-1.224
+ c-0.954,0-1.962,0.414-2.448,0.702l-0.559-1.981c0.701-0.45,2.106-0.882,3.618-0.882c2.504,0,3.891,1.313,3.891,2.917
+ c0,1.243-0.702,2.215-2.144,2.719v0.035c1.404,0.253,2.538,1.314,2.538,2.846c0,2.07-1.817,3.583-4.789,3.583
+ c-1.513,0-2.791-0.396-3.475-0.828L23.909,32.65z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/preset4.svg b/TamTamSynthLab.activity/icons/preset4.svg
new file mode 100644
index 0000000..e6cf5e9
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/preset4.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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<polygon fill="none" stroke="#FFFFFF" stroke-width="2" points="10.793,6.769 10.793,49.501 44.012,49.501 44.126,15.444
+ 35.45,6.996 "/>
+<polyline fill="#E6E3E1" stroke="#5D6060" stroke-width="2" points="35.334,7.042 35.334,15.753 44.166,15.753 "/>
+<g>
+ <path fill="#FFFFFF" d="M27.1,35.835v-2.791h-5.186v-1.782l4.431-7.13h3.349v6.859h1.404v2.054h-1.404v2.791L27.1,35.835
+ L27.1,35.835z M27.1,30.991v-2.592c0-0.703,0.037-1.422,0.09-2.179h-0.07c-0.379,0.756-0.685,1.439-1.082,2.179l-1.565,2.557v0.035
+ H27.1z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/preset5.svg b/TamTamSynthLab.activity/icons/preset5.svg
new file mode 100644
index 0000000..53f5b08
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/preset5.svg
@@ -0,0 +1,13 @@
+<?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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<polygon fill="none" stroke="#FFFFFF" stroke-width="2" points="10.793,5.769 10.793,49.834 44.012,49.834 44.126,14.444
+ 35.45,5.996 "/>
+<polyline fill="#E6E3E1" stroke="#5D6060" stroke-width="2" points="35.334,6.042 35.334,14.753 44.166,14.753 "/>
+<path fill="#FFFFFF" d="M31.025,25.407h-4.537l-0.252,1.8c0.252-0.035,0.468-0.035,0.756-0.035c1.117,0,2.251,0.252,3.08,0.846
+ c0.883,0.594,1.422,1.566,1.422,2.936c0,2.179-1.873,4.105-5.022,4.105c-1.423,0-2.611-0.324-3.259-0.666l0.485-2.053
+ c0.522,0.252,1.585,0.575,2.647,0.575c1.134,0,2.34-0.541,2.34-1.782c0-1.207-0.955-1.945-3.295-1.945
+ c-0.648,0-1.098,0.037-1.584,0.109l0.773-6.142h6.445V25.407z"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/preset6.svg b/TamTamSynthLab.activity/icons/preset6.svg
new file mode 100644
index 0000000..4c2493c
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/preset6.svg
@@ -0,0 +1,17 @@
+<?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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<polygon fill="none" stroke="#FFFFFF" stroke-width="2" points="10.793,6.769 10.793,49.501 44.012,49.501 44.126,15.444
+ 35.45,6.996 "/>
+<polyline fill="#E6E3E1" stroke="#5D6060" stroke-width="2" points="35.334,7.043 35.334,15.753 44.168,15.753 "/>
+<g>
+ <path fill="#FFFFFF" d="M30.562,26.575c-0.307,0-0.63,0-1.062,0.036c-2.431,0.198-3.511,1.44-3.815,2.811h0.055
+ c0.576-0.596,1.386-0.938,2.484-0.938c1.963,0,3.619,1.387,3.619,3.817c0,2.32-1.782,4.229-4.321,4.229
+ c-3.115,0-4.646-2.321-4.646-5.112c0-2.196,0.812-4.033,2.07-5.203c1.171-1.062,2.686-1.64,4.521-1.729
+ c0.505-0.036,0.828-0.036,1.099-0.018L30.562,26.575L30.562,26.575z M27.501,34.516c0.952,0,1.564-0.883,1.564-2.07
+ c0-1.081-0.576-2.018-1.747-2.018c-0.738,0-1.351,0.451-1.62,1.045c-0.07,0.145-0.106,0.357-0.106,0.684
+ c0.054,1.242,0.646,2.359,1.891,2.359H27.501z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/preset7.svg b/TamTamSynthLab.activity/icons/preset7.svg
new file mode 100644
index 0000000..d6de26c
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/preset7.svg
@@ -0,0 +1,13 @@
+<?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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<polygon fill="none" stroke="#FFFFFF" stroke-width="2" points="10.793,6.769 10.793,49.501 44.012,49.501 44.126,15.444
+ 35.45,6.996 "/>
+<polyline fill="#E6E3E1" stroke="#5D6060" stroke-width="2" points="35.334,7.042 35.334,15.753 44.166,15.753 "/>
+<g>
+ <path fill="#FFFFFF" d="M32.146,25.296v1.729l-4.825,9.977h-2.898l4.824-9.417v-0.036h-5.365v-2.251L32.146,25.296L32.146,25.296z"
+ />
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/preset8.svg b/TamTamSynthLab.activity/icons/preset8.svg
new file mode 100644
index 0000000..5c4a17f
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/preset8.svg
@@ -0,0 +1,17 @@
+<?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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<polygon fill="none" stroke="#FFFFFF" stroke-width="2" points="11.793,6.769 11.793,49.501 45.012,49.501 45.126,15.444
+ 36.45,6.996 "/>
+<polyline fill="#E6E3E1" stroke="#5D6060" stroke-width="2" points="36.334,7.042 36.334,15.753 45.166,15.753 "/>
+<g>
+ <path fill="#FFFFFF" d="M26.164,29.784c-1.135-0.575-1.691-1.529-1.691-2.557c0-1.98,1.782-3.295,4.123-3.295
+ c2.735,0,3.871,1.584,3.871,3.007c0,1.008-0.54,1.999-1.692,2.574v0.055c1.134,0.433,2.144,1.404,2.144,2.916
+ c0,2.125-1.783,3.548-4.503,3.548c-2.971,0-4.339-1.675-4.339-3.259c0-1.404,0.812-2.377,2.089-2.936L26.164,29.784L26.164,29.784z
+ M30.126,32.684c0-1.027-0.757-1.639-1.838-1.928c-0.898,0.253-1.422,0.899-1.422,1.747c-0.019,0.847,0.63,1.639,1.656,1.639
+ C29.495,34.142,30.126,33.512,30.126,32.684z M27.046,27.138c0,0.792,0.721,1.296,1.655,1.584c0.631-0.18,1.188-0.756,1.188-1.494
+ c0-0.72-0.414-1.44-1.422-1.44C27.532,25.787,27.046,26.399,27.046,27.138z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/preset9.svg b/TamTamSynthLab.activity/icons/preset9.svg
new file mode 100644
index 0000000..4b803e9
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/preset9.svg
@@ -0,0 +1,17 @@
+<?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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<polygon fill="none" stroke="#FFFFFF" stroke-width="2" points="10.793,6.769 10.793,49.501 44.012,49.501 44.126,15.444
+ 35.45,6.996 "/>
+<polyline fill="#E6E3E1" stroke="#5D6060" stroke-width="2" points="35.334,7.042 35.334,15.753 44.166,15.753 "/>
+<g>
+ <path fill="#FFFFFF" d="M24.793,34.164c0.343,0.036,0.647,0.036,1.188,0c0.828-0.055,1.675-0.287,2.305-0.721
+ c0.758-0.521,1.262-1.276,1.478-2.16l-0.054-0.018c-0.522,0.539-1.278,0.846-2.342,0.846c-1.979,0-3.654-1.387-3.654-3.655
+ c0-2.286,1.837-4.213,4.41-4.213c3.008,0,4.431,2.306,4.431,5.042c0,2.431-0.774,4.213-2.053,5.384
+ c-1.116,1.009-2.646,1.565-4.466,1.639c-0.469,0.036-0.937,0.018-1.242,0V34.164z M28.033,26.241c-0.918,0-1.603,0.828-1.584,2.053
+ c0,1.009,0.54,1.873,1.656,1.873c0.738,0,1.261-0.36,1.513-0.774c0.091-0.162,0.145-0.342,0.145-0.684
+ c0-1.243-0.468-2.468-1.71-2.468H28.033z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/rec1.svg b/TamTamSynthLab.activity/icons/rec1.svg
new file mode 100644
index 0000000..4a88eec
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/rec1.svg
@@ -0,0 +1,11 @@
+<?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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<circle fill="#808284" cx="27.501" cy="27.408" r="22.5"/>
+<circle fill="none" stroke="#4C4D4F" stroke-width="2.25" cx="27.499" cy="27.5" r="21.572"/>
+<g enable-background="new ">
+ <path fill="#FFFFFF" d="M26.582,24.229h-0.034l-2.233,1.062l-0.45-2.052l3.099-1.438h2.269v11.703h-2.649V24.229z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/rec2.svg b/TamTamSynthLab.activity/icons/rec2.svg
new file mode 100644
index 0000000..108ea7e
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/rec2.svg
@@ -0,0 +1,13 @@
+<?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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<circle fill="#808284" cx="27.501" cy="27.408" r="22.5"/>
+<circle fill="none" stroke="#4C4D4F" stroke-width="2.25" cx="27.499" cy="27.5" r="21.572"/>
+<g enable-background="new ">
+ <path fill="#FFFFFF" d="M23.09,33.501v-1.656l1.512-1.369c2.557-2.286,3.8-3.603,3.835-4.969c0-0.954-0.576-1.711-1.926-1.711
+ c-1.008,0-1.893,0.504-2.503,0.973l-0.774-1.963c0.882-0.666,2.25-1.206,3.835-1.206c2.647,0,4.105,1.548,4.105,3.673
+ c0,1.963-1.423,3.529-3.115,5.042l-1.08,0.899v0.034h4.411v2.253H23.09z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/rec3.svg b/TamTamSynthLab.activity/icons/rec3.svg
new file mode 100644
index 0000000..2c64c70
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/rec3.svg
@@ -0,0 +1,15 @@
+<?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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<circle fill="#808284" cx="27.501" cy="27.408" r="22.5"/>
+<circle fill="none" stroke="#4C4D4F" stroke-width="2.25" cx="27.499" cy="27.5" r="21.572"/>
+<g enable-background="new ">
+ <path fill="#FFFFFF" d="M23.575,30.818c0.486,0.252,1.604,0.72,2.721,0.72c1.423,0,2.143-0.684,2.143-1.564
+ c0-1.152-1.152-1.674-2.358-1.674h-1.117v-1.963h1.062c0.918-0.021,2.088-0.36,2.088-1.353c0-0.702-0.576-1.224-1.728-1.224
+ c-0.955,0-1.962,0.414-2.449,0.702l-0.558-1.981c0.7-0.45,2.104-0.882,3.617-0.882c2.502,0,3.891,1.312,3.891,2.917
+ c0,1.242-0.702,2.215-2.145,2.719v0.036c1.404,0.252,2.539,1.314,2.539,2.845c0,2.07-1.817,3.583-4.79,3.583
+ c-1.512,0-2.791-0.396-3.475-0.828L23.575,30.818z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/rec4.svg b/TamTamSynthLab.activity/icons/rec4.svg
new file mode 100644
index 0000000..14b2d0a
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/rec4.svg
@@ -0,0 +1,13 @@
+<?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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<circle fill="#808284" cx="27.501" cy="27.408" r="22.5"/>
+<circle fill="none" stroke="#4C4D4F" stroke-width="2.25" cx="27.499" cy="27.5" r="21.572"/>
+<g enable-background="new ">
+ <path fill="#FFFFFF" d="M27.934,33.501V30.71h-5.188v-1.782l4.431-7.13h3.349v6.858h1.404v2.055h-1.404v2.791L27.934,33.501
+ L27.934,33.501z M27.934,28.657v-2.593c0-0.702,0.036-1.422,0.09-2.178h-0.072c-0.378,0.756-0.684,1.438-1.081,2.178l-1.564,2.557
+ v0.036H27.934z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/rec5.svg b/TamTamSynthLab.activity/icons/rec5.svg
new file mode 100644
index 0000000..b5c7b21
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/rec5.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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<circle fill="#808284" cx="27.501" cy="27.408" r="22.5"/>
+<circle fill="none" stroke="#4C4D4F" stroke-width="2.25" cx="27.499" cy="27.5" r="21.572"/>
+<g>
+ <path fill="#FFFFFF" d="M31.522,23.832H26.48l-0.279,2c0.279-0.039,0.521-0.039,0.841-0.039c1.239,0,2.501,0.279,3.421,0.939
+ c0.979,0.66,1.58,1.74,1.58,3.261c0,2.42-2.08,4.562-5.581,4.562c-1.58,0-2.9-0.359-3.621-0.74l0.54-2.281
+ c0.58,0.281,1.761,0.642,2.94,0.642c1.26,0,2.602-0.601,2.602-1.98c0-1.34-1.062-2.16-3.661-2.16c-0.72,0-1.222,0.04-1.761,0.12
+ l0.859-6.822h7.162V23.832z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/rec6.svg b/TamTamSynthLab.activity/icons/rec6.svg
new file mode 100644
index 0000000..6b0ccc0
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/rec6.svg
@@ -0,0 +1,15 @@
+<?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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<circle fill="#808284" cx="27.501" cy="27.408" r="22.5"/>
+<circle fill="none" stroke="#4C4D4F" stroke-width="2.25" cx="27.499" cy="27.5" r="21.572"/>
+<g>
+ <path fill="#FFFFFF" d="M30.809,23.825c-0.34,0-0.7,0-1.18,0.04c-2.701,0.221-3.901,1.601-4.241,3.121h0.061
+ c0.641-0.66,1.54-1.04,2.761-1.04c2.181,0,4.021,1.54,4.021,4.241c0,2.58-1.98,4.7-4.801,4.7c-3.461,0-5.161-2.58-5.161-5.682
+ c0-2.44,0.899-4.48,2.3-5.78c1.301-1.182,2.98-1.821,5.021-1.92c0.56-0.04,0.92-0.04,1.22-0.021V23.825z M27.408,32.647
+ c1.062,0,1.74-0.979,1.74-2.3c0-1.201-0.64-2.241-1.939-2.241c-0.82,0-1.5,0.5-1.801,1.16c-0.08,0.16-0.12,0.4-0.12,0.761
+ c0.061,1.38,0.721,2.62,2.102,2.62H27.408z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-addSynth+.svg b/TamTamSynthLab.activity/icons/sl-addSynth+.svg
new file mode 100755
index 0000000..23d3fbc
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-addSynth+.svg
@@ -0,0 +1,30 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M5.221,13.415c0-3.891,5.639-8.679,10.206-8.679h48.479
+ c4.568,0,10.207,4.789,10.207,8.679v32.205c0,16.188-15.414,29.311-34.446,29.311c-19.033,0-34.446-13.122-34.446-29.311V13.415z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="18.862" y1="17.083" x2="18.862" y2="59.985"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="19.514" y1="45.028" x2="66.32" y2="45.028"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="25.362" y1="23.57" x2="25.362" y2="44.363"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="43.483" y1="30.514" x2="43.569" y2="44.363"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="34.374" y1="27.188" x2="34.471" y2="44.363"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="52.593" y1="33.344" x2="52.667" y2="44.363"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="63.058" y1="37.16" x2="63.069" y2="44.363"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M10.417,5.818
+ c0-2.758,2.326-4.985,5.195-4.985c2.88,0,5.207,2.228,5.207,4.985c0,2.745-2.327,4.986-5.207,4.986
+ C12.743,10.804,10.417,8.563,10.417,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M26.015,5.818
+ c0-2.758,2.326-4.985,5.207-4.985c2.868,0,5.195,2.228,5.195,4.985c0,2.745-2.327,4.986-5.195,4.986
+ C28.34,10.804,26.015,8.563,26.015,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M42.917,5.818
+ c0-2.758,2.326-4.985,5.194-4.985c2.881,0,5.208,2.228,5.208,4.985c0,2.745-2.327,4.986-5.208,4.986
+ C45.243,10.804,42.917,8.563,42.917,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M59.819,5.818
+ c0-2.758,2.327-4.985,5.194-4.985c2.87,0,5.209,2.228,5.209,4.985c0,2.745-2.339,4.986-5.209,4.986
+ C62.146,10.804,59.819,8.563,59.819,5.818z"/>
+<path fill="#DF3800" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M34.299,73.847
+ c0-2.744,2.339-4.984,5.207-4.984c2.869,0,5.195,2.24,5.195,4.984c0,2.758-2.326,4.986-5.195,4.986
+ C36.638,78.833,34.299,76.604,34.299,73.847z"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-addSynth-menu.svg b/TamTamSynthLab.activity/icons/sl-addSynth-menu.svg
new file mode 100644
index 0000000..b26b996
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-addSynth-menu.svg
@@ -0,0 +1,15 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M9.667,16.825c0-3.389,4.911-7.559,8.889-7.559h42.222
+ c3.979,0,8.89,4.171,8.89,7.559v28.048c0,14.1-13.424,25.528-30,25.528c-16.577,0-30-11.429-30-25.528V16.825z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.547" y1="20.02" x2="21.547" y2="57.384"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="22.115" y1="44.357" x2="62.88" y2="44.357"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="27.208" y1="25.669" x2="27.208" y2="43.778"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="42.99" y1="31.717" x2="43.064" y2="43.778"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="35.057" y1="28.82" x2="35.142" y2="43.778"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="50.925" y1="34.182" x2="50.989" y2="43.778"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="60.039" y1="37.505" x2="60.048" y2="43.778"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-adsr+.svg b/TamTamSynthLab.activity/icons/sl-adsr+.svg
new file mode 100755
index 0000000..bbf18d5
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-adsr+.svg
@@ -0,0 +1,21 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <polygon fill="#FFFF33" stroke="#333333" stroke-linecap="round" stroke-miterlimit="8" points="5.5,8.569 9.615,4.812
+ 69.386,4.812 73.5,8.569 73.5,49.617 57.114,72.812 24.151,72.812 5.5,49.617 "/>
+ <circle fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" cx="39.5" cy="73.125" r="5.375"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="28.171" y1="21.042" x2="33.98" y2="30.479"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="20.727" y1="46.264" x2="28.05" y2="20.789"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="34.01" y1="30.533" x2="50.566" y2="30.533"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="51.307" y1="30.533" x2="59.51" y2="46.671"/>
+ <polyline fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" points="67.712,48.695 18.166,48.734
+ 18.61,14.689 "/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-adsr-menu.svg b/TamTamSynthLab.activity/icons/sl-adsr-menu.svg
new file mode 100644
index 0000000..35960ab
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-adsr-menu.svg
@@ -0,0 +1,20 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <polygon fill="#FFFF33" stroke="#333333" stroke-linecap="round" stroke-miterlimit="8" points="9.5,12.127 13.131,8.812
+ 65.871,8.812 69.5,12.127 69.5,48.346 55.041,68.812 25.957,68.812 9.5,48.346 "/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="29.504" y1="23.133" x2="34.629" y2="31.459"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="22.936" y1="45.387" x2="29.397" y2="22.91"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="34.656" y1="31.507" x2="49.265" y2="31.507"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="49.918" y1="31.507" x2="57.155" y2="45.746"/>
+ <polyline fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" points="64.393,47.532 20.676,47.567
+ 21.067,17.527 "/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-buzz+.svg b/TamTamSynthLab.activity/icons/sl-buzz+.svg
new file mode 100755
index 0000000..9ca65f0
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-buzz+.svg
@@ -0,0 +1,30 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M5.221,13.415c0-3.891,5.639-8.679,10.206-8.679h48.479
+ c4.568,0,10.207,4.789,10.207,8.679V45.62c0,16.188-15.414,29.312-34.446,29.312c-19.033,0-34.446-13.123-34.446-29.312V13.415z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="18.862" y1="17.083" x2="18.862" y2="59.984"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M10.417,5.818
+ c0-2.758,2.326-4.985,5.195-4.985c2.88,0,5.207,2.228,5.207,4.985c0,2.745-2.327,4.986-5.207,4.986
+ C12.743,10.804,10.417,8.563,10.417,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M26.015,5.818
+ c0-2.758,2.326-4.985,5.207-4.985c2.868,0,5.195,2.228,5.195,4.985c0,2.745-2.327,4.986-5.195,4.986
+ C28.34,10.804,26.015,8.563,26.015,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M42.917,5.818
+ c0-2.758,2.326-4.985,5.194-4.985c2.881,0,5.207,2.228,5.207,4.985c0,2.745-2.326,4.986-5.207,4.986
+ C45.243,10.804,42.917,8.563,42.917,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M59.818,5.818
+ c0-2.758,2.328-4.985,5.195-4.985c2.869,0,5.209,2.228,5.209,4.985c0,2.745-2.34,4.986-5.209,4.986
+ C62.146,10.804,59.818,8.563,59.818,5.818z"/>
+<path fill="#DF3800" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M34.299,73.848
+ c0-2.744,2.339-4.984,5.207-4.984c2.869,0,5.195,2.24,5.195,4.984c0,2.758-2.326,4.985-5.195,4.985
+ C36.638,78.833,34.299,76.604,34.299,73.848z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="19.014" y1="49.277" x2="65.82" y2="49.277"/>
+<line fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="23.713" y1="28.747" x2="23.713" y2="48.747"/>
+<line fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="43.046" y1="28.747" x2="43.046" y2="48.747"/>
+<line fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="33.38" y1="28.747" x2="33.38" y2="48.747"/>
+<line fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="52.685" y1="28.747" x2="52.685" y2="48.747"/>
+<line fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="63.712" y1="28.747" x2="63.712" y2="48.747"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-buzz-menu.svg b/TamTamSynthLab.activity/icons/sl-buzz-menu.svg
new file mode 100644
index 0000000..570a530
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-buzz-menu.svg
@@ -0,0 +1,15 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M10.224,17.252c0-3.326,4.82-7.418,8.724-7.418h41.438
+ c3.905,0,8.725,4.093,8.725,7.418v27.527c0,13.838-13.175,25.055-29.443,25.055c-16.269,0-29.443-11.217-29.443-25.055V17.252z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.884" y1="20.388" x2="21.884" y2="57.058"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="22.014" y1="47.906" x2="62.021" y2="47.906"/>
+<line fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="26.03" y1="30.357" x2="26.03" y2="47.452"/>
+<line fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="42.555" y1="30.357" x2="42.555" y2="47.452"/>
+<line fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="34.293" y1="30.357" x2="34.293" y2="47.452"/>
+<line fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="50.794" y1="30.357" x2="50.794" y2="47.452"/>
+<line fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="60.22" y1="30.357" x2="60.22" y2="47.452"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-chorus+.svg b/TamTamSynthLab.activity/icons/sl-chorus+.svg
new file mode 100755
index 0000000..e58b602
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-chorus+.svg
@@ -0,0 +1,139 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="
+ M5.598,23.098c0-9.332,7.571-16.902,16.902-16.902h33.804c9.332,0,16.89,7.571,16.89,16.902v33.806
+ c0,9.331-7.558,16.901-16.89,16.901H22.5c-9.332,0-16.902-7.57-16.902-16.901V23.098z"/>
+</g>
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="
+ M68,20.5c0-2.869,2.326-5.195,5.194-5.195c2.881,0,5.208,2.327,5.208,5.195c0,2.868-2.327,5.194-5.208,5.194
+ C70.326,25.695,68,23.369,68,20.5z"/>
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="
+ M68,33.5c0-2.869,2.326-5.195,5.194-5.195c2.881,0,5.208,2.327,5.208,5.195c0,2.868-2.327,5.194-5.208,5.194
+ C70.326,38.695,68,36.368,68,33.5z"/>
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="
+ M68,46.499c0-2.867,2.326-5.193,5.194-5.193c2.881,0,5.208,2.326,5.208,5.193c0,2.868-2.327,5.196-5.208,5.196
+ C70.326,51.695,68,49.367,68,46.499z"/>
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="
+ M68,59.5c0-2.869,2.326-5.195,5.194-5.195c2.881,0,5.208,2.326,5.208,5.195c0,2.868-2.327,5.195-5.208,5.195
+ C70.326,64.695,68,62.368,68,59.5z"/>
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="
+ M34.299,6.195C34.299,3.327,36.638,1,39.507,1c2.868,0,5.194,2.327,5.194,5.195c0,2.88-2.326,5.208-5.194,5.208
+ C36.638,11.403,34.299,9.076,34.299,6.195z"/>
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="
+ M34.299,73.805c0-2.881,2.339-5.207,5.208-5.207c2.868,0,5.194,2.326,5.194,5.207c0,2.868-2.326,5.194-5.194,5.194
+ C36.638,78.999,34.299,76.673,34.299,73.805z"/>
+<line fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="9.008" y1="42.13" x2="68.099" y2="42.13"/>
+<g>
+ <g>
+ <g>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M11.778,41.12c6.118-46.263,11.806,0,11.806,0"/>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M34.712,37.907c-6.119,46.263-11.794,0-11.794,0"/>
+ </g>
+ <g>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M11.778,41.896c3.065-23.131,5.909,0,5.909,0"/>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M23.251,40.283c-3.065,23.131-5.896,0-5.896,0"/>
+ </g>
+ <g>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M34.712,40.283c-3.053,23.131-5.897,0-5.897,0"/>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M23.251,41.896c3.053-23.131,5.897,0,5.897,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M34.528,42.45c6.119-46.263,11.805,0,11.805,0"/>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M57.463,39.237c-6.119,46.263-11.794,0-11.794,0"/>
+ </g>
+ <g>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M34.528,43.226c3.065-23.132,5.909,0,5.909,0"/>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M46.001,41.613c-3.065,23.131-5.897,0-5.897,0"/>
+ </g>
+ <g>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M57.463,41.613c-3.054,23.131-5.898,0-5.898,0"/>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M46.001,43.226c3.054-23.132,5.896,0,5.896,0"/>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M17.687,41.12c6.119-46.263,11.806,0,11.806,0"/>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M40.621,37.907c-6.118,46.263-11.793,0-11.793,0"/>
+ </g>
+ <g>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M17.687,41.896c3.066-23.131,5.909,0,5.909,0"/>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M29.16,40.283c-3.065,23.131-5.896,0-5.896,0"/>
+ </g>
+ <g>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M40.621,40.283c-3.053,23.131-5.897,0-5.897,0"/>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M29.16,41.896c3.053-23.131,5.897,0,5.897,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M40.437,42.45c6.118-46.263,11.806,0,11.806,0"/>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M63.37,39.237c-6.116,46.263-11.793,0-11.793,0"/>
+ </g>
+ <g>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M40.437,43.226c3.066-23.132,5.908,0,5.908,0"/>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M51.91,41.613c-3.064,23.131-5.897,0-5.897,0"/>
+ </g>
+ <g>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M63.37,41.613c-3.052,23.131-5.896,0-5.896,0"/>
+
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="
+ M51.91,43.226c3.052-23.132,5.896,0,5.896,0"/>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-chorus-menu.svg b/TamTamSynthLab.activity/icons/sl-chorus-menu.svg
new file mode 100644
index 0000000..7dcb3f4
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-chorus-menu.svg
@@ -0,0 +1,101 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <g>
+ <path fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M9.396,25c0-8.282,6.72-15,15.003-15
+ h30.006c8.284,0,14.991,6.719,14.991,15v30.001c0,8.28-6.707,14.998-14.991,14.998H24.398c-8.283,0-15.003-6.718-15.003-14.998V25
+ z"/>
+ </g>
+
+ <line fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="14.783" y1="41.923" x2="60.792" y2="41.923"/>
+ <g>
+ <g>
+ <g>
+ <g>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M17.807,40.903
+ c4.737-36.621,9.141,0,9.141,0"/>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M35.563,38.361
+ c-4.738,36.62-9.131,0-9.131,0"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M17.807,41.52
+ c2.373-18.312,4.575,0,4.575,0"/>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M26.689,40.241
+ c-2.373,18.31-4.564,0-4.564,0"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M35.563,40.241
+ c-2.364,18.31-4.565,0-4.565,0"/>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M26.689,41.52
+ c2.364-18.312,4.565,0,4.565,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M35.42,41.957
+ c4.737-36.622,9.14,0,9.14,0"/>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M53.178,39.413
+ c-4.737,36.62-9.133,0-9.133,0"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M35.42,42.571
+ c2.373-18.312,4.575,0,4.575,0"/>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M44.303,41.295
+ c-2.373,18.309-4.565,0-4.565,0"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M53.178,41.295
+ c-2.364,18.309-4.567,0-4.567,0"/>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M44.303,42.571
+ c2.364-18.312,4.565,0,4.565,0"/>
+ </g>
+ </g>
+ </g>
+ <g>
+ <g>
+ <g>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M22.382,40.903
+ c4.737-36.621,9.141,0,9.141,0"/>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M40.138,38.361
+ c-4.737,36.62-9.13,0-9.13,0"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M22.382,41.52
+ c2.374-18.312,4.575,0,4.575,0"/>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M31.265,40.241
+ c-2.373,18.31-4.565,0-4.565,0"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M40.138,40.241
+ c-2.364,18.31-4.566,0-4.566,0"/>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M31.265,41.52
+ c2.363-18.312,4.565,0,4.565,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M39.996,41.957
+ c4.737-36.622,9.14,0,9.14,0"/>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M57.751,39.413
+ c-4.735,36.62-9.131,0-9.131,0"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M39.996,42.571
+ c2.375-18.312,4.574,0,4.574,0"/>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M48.878,41.295
+ c-2.373,18.309-4.565,0-4.565,0"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M57.751,41.295
+ c-2.362,18.309-4.565,0-4.565,0"/>
+ <path fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" d="M48.878,42.571
+ c2.363-18.312,4.565,0,4.565,0"/>
+ </g>
+ </g>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-distort+.svg b/TamTamSynthLab.activity/icons/sl-distort+.svg
new file mode 100644
index 0000000..12c99a1
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-distort+.svg
@@ -0,0 +1,30 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <path fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M3.598,23.098
+ c0-9.332,7.571-16.902,16.902-16.902h33.805c9.332,0,16.889,7.571,16.889,16.902v33.806c0,9.33-7.557,16.9-16.889,16.9H20.5
+ c-9.332,0-16.902-7.57-16.902-16.9V23.098z"/>
+</g>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,20.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.327,5.209,5.195s-2.327,5.194-5.209,5.194C68.326,25.695,66,23.369,66,20.5z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,33.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.327,5.209,5.195s-2.327,5.194-5.209,5.194C68.326,38.695,66,36.368,66,33.5z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,46.499
+ c0-2.867,2.326-5.192,5.193-5.192c2.882,0,5.209,2.325,5.209,5.192c0,2.868-2.327,5.196-5.209,5.196
+ C68.326,51.695,66,49.367,66,46.499z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,59.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.326,5.209,5.195c0,2.868-2.327,5.195-5.209,5.195C68.326,64.695,66,62.368,66,59.5z"/>
+<path fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M32.299,6.195
+ C32.299,3.327,34.638,1,37.507,1c2.868,0,5.194,2.327,5.194,5.195c0,2.88-2.326,5.208-5.194,5.208
+ C34.638,11.403,32.299,9.076,32.299,6.195z"/>
+<path fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M32.299,73.805
+ c0-2.881,2.339-5.207,5.208-5.207c2.868,0,5.194,2.326,5.194,5.207c0,2.868-2.326,5.194-5.194,5.194
+ C34.638,78.999,32.299,76.673,32.299,73.805z"/>
+<line fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="14.054" y1="41.664" x2="59.055" y2="41.664"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="37.712" y1="29.043" x2="37.712" y2="54.624"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="37.232" y1="28.376" x2="16.055" y2="28.376"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="59.055" y1="54.874" x2="37.878" y2="54.874"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-distort-menu.svg b/TamTamSynthLab.activity/icons/sl-distort-menu.svg
new file mode 100644
index 0000000..bc7bca9
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-distort-menu.svg
@@ -0,0 +1,21 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <g>
+ <path fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M9.396,25c0-8.282,6.72-15,15.003-15
+ h30.006c8.284,0,14.991,6.719,14.991,15v30.001c0,8.28-6.707,14.998-14.991,14.998H24.398c-8.283,0-15.003-6.718-15.003-14.998V25
+ z"/>
+ </g>
+
+ <line fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="18.677" y1="41.477" x2="58.621" y2="41.477"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="39.676" y1="30.276" x2="39.676" y2="52.979"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="39.25" y1="29.684" x2="20.453" y2="29.684"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="58.621" y1="53.2" x2="39.824" y2="53.2"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-eq4band+.svg b/TamTamSynthLab.activity/icons/sl-eq4band+.svg
new file mode 100644
index 0000000..3684361
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-eq4band+.svg
@@ -0,0 +1,51 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <path fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M3.598,23.098
+ c0-9.332,7.571-16.902,16.902-16.902h33.805c9.332,0,16.889,7.571,16.889,16.902v33.806c0,9.33-7.557,16.9-16.889,16.9H20.5
+ c-9.332,0-16.902-7.57-16.902-16.9V23.098z"/>
+</g>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,20.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.327,5.209,5.195s-2.327,5.194-5.209,5.194C68.326,25.695,66,23.369,66,20.5z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,33.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.327,5.209,5.195s-2.327,5.194-5.209,5.194C68.326,38.695,66,36.368,66,33.5z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,46.499
+ c0-2.867,2.326-5.192,5.193-5.192c2.882,0,5.209,2.325,5.209,5.192c0,2.868-2.327,5.196-5.209,5.196
+ C68.326,51.695,66,49.367,66,46.499z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,59.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.326,5.209,5.195c0,2.868-2.327,5.195-5.209,5.195C68.326,64.695,66,62.368,66,59.5z"/>
+<path fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M32.299,6.195
+ C32.299,3.327,34.638,1,37.507,1c2.868,0,5.194,2.327,5.194,5.195c0,2.88-2.326,5.208-5.194,5.208
+ C34.638,11.403,32.299,9.076,32.299,6.195z"/>
+<path fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M32.299,73.805
+ c0-2.881,2.339-5.207,5.208-5.207c2.868,0,5.194,2.326,5.194,5.207c0,2.868-2.326,5.194-5.194,5.194
+ C34.638,78.999,32.299,76.673,32.299,73.805z"/>
+<line fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="11.5" y1="54.664" x2="56.5" y2="54.664"/>
+<g>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M13.386,55.637
+ c4.614,0,3.671-27.935,7.045-26.991"/>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M27.525,55.637
+ c-4.638,0-3.671-27.935-7.045-26.991"/>
+</g>
+<g>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M23.655,55.637
+ c4.639,0,3.672-33.242,7.07-32.126"/>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M37.823,55.637
+ c-4.641,0-3.673-33.242-7.072-32.126"/>
+</g>
+<g>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M33.951,55.637
+ c4.637,0,3.672-18.604,7.068-17.986"/>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M48.09,55.637
+ c-4.613,0-3.67-18.604-7.045-17.986"/>
+</g>
+<g>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M44.248,55.637
+ c4.637,0,3.67-25.279,7.045-24.411"/>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M58.385,55.637
+ c-4.637,0-3.672-25.279-7.045-24.411"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-eq4band-menu.svg b/TamTamSynthLab.activity/icons/sl-eq4band-menu.svg
new file mode 100644
index 0000000..36928a5
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-eq4band-menu.svg
@@ -0,0 +1,38 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <g>
+ <path fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M10.006,25c0-8.282,6.72-15,15-15h30
+ c8.283,0,14.988,6.719,14.988,15v30.001C69.994,63.282,63.289,70,55.006,70h-30c-8.281,0-15-6.718-15-14.999V25z"/>
+ </g>
+
+ <line fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="17.021" y1="53.014" x2="56.957" y2="53.014"/>
+ <g>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M18.693,53.876
+ c4.095,0,3.258-24.79,6.252-23.952"/>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M31.241,53.876
+ c-4.117,0-3.258-24.79-6.251-23.952"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M27.808,53.876
+ c4.116,0,3.259-29.5,6.274-28.51"/>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M40.381,53.876
+ c-4.119,0-3.261-29.5-6.276-28.51"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M36.944,53.876
+ c4.116,0,3.261-16.511,6.272-15.96"/>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M49.492,53.876
+ c-4.095,0-3.257-16.511-6.25-15.96"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M46.082,53.876
+ c4.115,0,3.258-22.434,6.252-21.663"/>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M58.629,53.876
+ c-4.115,0-3.26-22.434-6.252-21.663"/>
+ </g>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-filter+.svg b/TamTamSynthLab.activity/icons/sl-filter+.svg
new file mode 100644
index 0000000..c86b558
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-filter+.svg
@@ -0,0 +1,32 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <path fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M3.598,23.098
+ c0-9.332,7.571-16.902,16.902-16.902h33.805c9.332,0,16.889,7.571,16.889,16.902v33.806c0,9.33-7.557,16.9-16.889,16.9H20.5
+ c-9.332,0-16.902-7.57-16.902-16.9V23.098z"/>
+</g>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,20.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.327,5.209,5.195s-2.327,5.194-5.209,5.194C68.326,25.695,66,23.369,66,20.5z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,33.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.327,5.209,5.195s-2.327,5.194-5.209,5.194C68.326,38.695,66,36.368,66,33.5z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,46.499
+ c0-2.867,2.326-5.192,5.193-5.192c2.882,0,5.209,2.325,5.209,5.192c0,2.868-2.327,5.196-5.209,5.196
+ C68.326,51.695,66,49.367,66,46.499z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,59.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.326,5.209,5.195c0,2.868-2.327,5.195-5.209,5.195C68.326,64.695,66,62.368,66,59.5z"/>
+<path fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M32.299,6.195
+ C32.299,3.327,34.638,1,37.507,1c2.868,0,5.194,2.327,5.194,5.195c0,2.88-2.326,5.208-5.194,5.208
+ C34.638,11.403,32.299,9.076,32.299,6.195z"/>
+<path fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M32.299,73.805
+ c0-2.881,2.339-5.207,5.208-5.207c2.868,0,5.194,2.326,5.194,5.207c0,2.868-2.326,5.194-5.194,5.194
+ C34.638,78.999,32.299,76.673,32.299,73.805z"/>
+<line fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="14.054" y1="49.664" x2="59.055" y2="49.664"/>
+<path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M18.319,48.688
+ c12.197,0,9.664-22.544,18.569-21.765"/>
+<path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M55.552,48.688
+ c-12.196,0-9.663-22.544-18.569-21.765"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="36.889" y1="27.469" x2="36.889" y2="49.188"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-filter-menu.svg b/TamTamSynthLab.activity/icons/sl-filter-menu.svg
new file mode 100644
index 0000000..1dca673
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-filter-menu.svg
@@ -0,0 +1,21 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <g>
+ <path fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M9.396,25c0-8.282,6.72-15,15.003-15
+ h30.006c8.284,0,14.991,6.719,14.991,15v30.001c0,8.28-6.707,14.998-14.991,14.998H24.398c-8.283,0-15.003-6.718-15.003-14.998V25
+ z"/>
+ </g>
+
+ <line fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="18.677" y1="48.576" x2="58.621" y2="48.576"/>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M22.462,47.71
+ c10.827,0,8.578-20.007,16.483-19.315"/>
+ <path fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M55.512,47.71
+ c-10.826,0-8.577-20.007-16.482-19.315"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="38.946" y1="28.879" x2="38.946" y2="48.153"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-fm+.svg b/TamTamSynthLab.activity/icons/sl-fm+.svg
new file mode 100755
index 0000000..b517986
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-fm+.svg
@@ -0,0 +1,43 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M5.221,13.415c0-3.891,5.639-8.679,10.206-8.679h48.479
+ c4.568,0,10.207,4.789,10.207,8.679V45.62c0,16.188-15.414,29.312-34.446,29.312c-19.033,0-34.446-13.123-34.446-29.312V13.415z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="18.862" y1="17.083" x2="18.862" y2="59.984"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M10.417,5.818
+ c0-2.758,2.326-4.985,5.195-4.985c2.88,0,5.207,2.228,5.207,4.985c0,2.745-2.327,4.986-5.207,4.986
+ C12.743,10.804,10.417,8.563,10.417,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M26.015,5.818
+ c0-2.758,2.326-4.985,5.207-4.985c2.868,0,5.195,2.228,5.195,4.985c0,2.745-2.327,4.986-5.195,4.986
+ C28.34,10.804,26.015,8.563,26.015,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M42.917,5.818
+ c0-2.758,2.326-4.985,5.194-4.985c2.881,0,5.207,2.228,5.207,4.985c0,2.745-2.326,4.986-5.207,4.986
+ C45.243,10.804,42.917,8.563,42.917,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M59.818,5.818
+ c0-2.758,2.328-4.985,5.195-4.985c2.869,0,5.209,2.228,5.209,4.985c0,2.745-2.34,4.986-5.209,4.986
+ C62.146,10.804,59.818,8.563,59.818,5.818z"/>
+<path fill="#DF3800" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M34.299,73.848
+ c0-2.744,2.339-4.984,5.207-4.984c2.869,0,5.195,2.24,5.195,4.984c0,2.758-2.326,4.985-5.195,4.985
+ C36.638,78.833,34.299,76.604,34.299,73.848z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="19.014" y1="39.278" x2="65.82" y2="39.278"/>
+<g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#2D3238" stroke-width="2" stroke-linecap="round" d="
+ M19.98,40.324c12-48.823,23.172,0,23.172,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#2D3238" stroke-width="2" stroke-linecap="round" d="
+ M64.979,36.926c-11.996,48.822-23.129,0-23.129,0"/>
+</g>
+<g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#2D3238" stroke-width="2" stroke-linecap="round" d="
+ M19.98,41.132c6-24.411,11.566,0,11.566,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#2D3238" stroke-width="2" stroke-linecap="round" d="
+ M42.481,39.447c-6.001,24.415-11.567,0-11.567,0"/>
+</g>
+<g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#2D3238" stroke-width="2" stroke-linecap="round" d="
+ M64.979,39.447c-5.998,24.415-11.564,0-11.564,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#2D3238" stroke-width="2" stroke-linecap="round" d="
+ M42.481,41.132c5.998-24.411,11.604,0,11.604,0"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-fm-menu.svg b/TamTamSynthLab.activity/icons/sl-fm-menu.svg
new file mode 100644
index 0000000..94cb8e3
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-fm-menu.svg
@@ -0,0 +1,30 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M9.667,17.252c0-3.326,4.911-7.418,8.889-7.418h42.222
+ c3.979,0,8.89,4.093,8.89,7.418v27.527c0,13.838-13.424,25.055-30,25.055c-16.577,0-30-11.217-30-25.055V17.252z"/>
+
+ <line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.547" y1="20.388" x2="21.547" y2="57.058"/>
+
+ <line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.68" y1="39.358" x2="62.444" y2="39.358"/>
+ <g>
+ <path fill="none" stroke="#2D3238" stroke-width="2" stroke-linecap="round" d="M22.521,40.253c10.451-41.732,20.181,0,20.181,0"
+ />
+ <path fill="none" stroke="#2D3238" stroke-width="2" stroke-linecap="round" d="M61.712,37.348c-10.448,41.731-20.144,0-20.144,0"
+ />
+ </g>
+ <g>
+ <path fill="none" stroke="#2D3238" stroke-width="2" stroke-linecap="round" d="M22.521,40.943c5.226-20.865,10.073,0,10.073,0"/>
+ <path fill="none" stroke="#2D3238" stroke-width="2" stroke-linecap="round" d="M42.117,39.503c-5.226,20.868-10.073,0-10.073,0"
+ />
+ </g>
+ <g>
+ <path fill="none" stroke="#2D3238" stroke-width="2" stroke-linecap="round" d="M61.712,39.503c-5.225,20.868-10.071,0-10.071,0"
+ />
+ <path fill="none" stroke="#2D3238" stroke-width="2" stroke-linecap="round" d="M42.117,40.943c5.224-20.865,10.106,0,10.106,0"/>
+ </g>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-grain+.svg b/TamTamSynthLab.activity/icons/sl-grain+.svg
new file mode 100755
index 0000000..1a270cf
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-grain+.svg
@@ -0,0 +1,205 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M5.221,13.415c0-3.891,5.639-8.679,10.206-8.679h48.479
+ c4.568,0,10.207,4.789,10.207,8.679V45.62c0,16.188-15.414,29.312-34.446,29.312c-19.033,0-34.446-13.123-34.446-29.312V13.415z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="18.862" y1="17.083" x2="18.862" y2="59.984"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M10.417,5.818
+ c0-2.758,2.326-4.985,5.195-4.985c2.88,0,5.207,2.228,5.207,4.985c0,2.745-2.327,4.986-5.207,4.986
+ C12.743,10.804,10.417,8.563,10.417,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M26.015,5.818
+ c0-2.758,2.326-4.985,5.207-4.985c2.868,0,5.195,2.228,5.195,4.985c0,2.745-2.327,4.986-5.195,4.986
+ C28.34,10.804,26.015,8.563,26.015,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M42.917,5.818
+ c0-2.758,2.326-4.985,5.194-4.985c2.881,0,5.207,2.228,5.207,4.985c0,2.745-2.326,4.986-5.207,4.986
+ C45.243,10.804,42.917,8.563,42.917,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M59.818,5.818
+ c0-2.758,2.328-4.985,5.195-4.985c2.868,0,5.209,2.228,5.209,4.985c0,2.745-2.341,4.986-5.209,4.986
+ C62.146,10.804,59.818,8.563,59.818,5.818z"/>
+<path fill="#DF3800" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M34.299,73.848
+ c0-2.744,2.339-4.983,5.207-4.983c2.869,0,5.195,2.239,5.195,4.983c0,2.758-2.326,4.985-5.195,4.985
+ C36.638,78.833,34.299,76.604,34.299,73.848z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="19.014" y1="39.278" x2="65.82" y2="39.278"/>
+<g>
+ <g>
+ <g id="XMLID_1_">
+ <g>
+ <path fill="#0A0A0A" d="M26.16,34.95c3.34-0.1,2.38,3.18,6.95,3.18v0.15c-4.57,0-3.61,3.28-6.95,3.18h-0.05
+ c-3.33,0.1-2.38-3.18-6.95-3.18v-0.15c4.57,0,3.62-3.28,6.95-3.18H26.16z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M19.16,38.13
+ c4.57,0,3.62-3.28,6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M33.11,38.13
+ c-4.57,0-3.61-3.28-6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M33.11,38.28
+ c-4.57,0-3.61,3.28-6.95,3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M19.16,38.28
+ c4.57,0,3.62,3.28,6.95,3.18"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_2_">
+ <g>
+ <path fill="#0A0A0A" d="M40.11,35.296v0.15c-4.57,0-3.61,3.28-6.95,3.18h-0.05c-3.33,0.1-2.38-3.18-6.95-3.18v-0.15
+ c4.57,0,3.62-3.28,6.95-3.18h0.05C36.5,32.016,35.54,35.296,40.11,35.296z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M26.16,35.296
+ c4.57,0,3.62-3.28,6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M40.11,35.296
+ c-4.57,0-3.61-3.28-6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M40.11,35.446
+ c-4.57,0-3.61,3.28-6.95,3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M26.16,35.446
+ c4.57,0,3.62,3.28,6.95,3.18"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_3_">
+ <g>
+ <path fill="#0A0A0A" d="M42.568,41.129v0.15c-4.57,0-3.61,3.279-6.95,3.18h-0.05c-3.33,0.1-2.38-3.18-6.95-3.18v-0.15
+ c4.57,0,3.62-3.28,6.95-3.18h0.05C38.958,37.849,37.998,41.129,42.568,41.129z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M28.618,41.129
+ c4.57,0,3.62-3.28,6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M42.568,41.129
+ c-4.57,0-3.61-3.28-6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M42.568,41.279
+ c-4.57,0-3.61,3.279-6.95,3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M28.618,41.279
+ c4.57,0,3.62,3.279,6.95,3.18"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_4_">
+ <g>
+ <path fill="#0A0A0A" d="M49.61,36.879v0.15c-4.57,0-3.61,3.28-6.95,3.18h-0.05c-3.331,0.1-2.38-3.18-6.95-3.18v-0.15
+ c4.57,0,3.62-3.28,6.95-3.18h0.05C46,33.599,45.04,36.879,49.61,36.879z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M35.66,36.879
+ c4.57,0,3.62-3.28,6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M49.61,36.879
+ c-4.57,0-3.61-3.28-6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M49.61,37.029
+ c-4.57,0-3.61,3.28-6.95,3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M35.66,37.029
+ c4.57,0,3.62,3.28,6.95,3.18"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_5_">
+ <g>
+ <path fill="#0A0A0A" d="M53.61,42.754v0.15c-4.57,0-3.61,3.279-6.95,3.18h-0.05c-3.33,0.1-2.38-3.18-6.95-3.18v-0.15
+ c4.57,0,3.62-3.28,6.95-3.18h0.05C50,39.474,49.04,42.754,53.61,42.754z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M39.66,42.754
+ c4.57,0,3.62-3.28,6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M53.61,42.754
+ c-4.57,0-3.61-3.28-6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M53.61,42.904
+ c-4.57,0-3.61,3.279-6.95,3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M39.66,42.904
+ c4.57,0,3.62,3.279,6.95,3.18"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_6_">
+ <g>
+ <path fill="#0A0A0A" d="M49.319,32.629v0.15c-4.57,0-3.61,3.28-6.95,3.18h-0.05c-3.331,0.1-2.38-3.18-6.95-3.18v-0.15
+ c4.57,0,3.62-3.28,6.95-3.18h0.05C45.709,29.349,44.749,32.629,49.319,32.629z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M35.369,32.629
+ c4.57,0,3.62-3.28,6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M49.319,32.629
+ c-4.57,0-3.61-3.28-6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M49.319,32.779
+ c-4.57,0-3.61,3.28-6.95,3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M35.369,32.779
+ c4.57,0,3.62,3.28,6.95,3.18"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_7_">
+ <g>
+ <path fill="#0A0A0A" d="M58.652,37.17v0.15c-4.57,0-3.61,3.28-6.95,3.18h-0.05c-3.33,0.1-2.38-3.18-6.95-3.18v-0.15
+ c4.57,0,3.62-3.28,6.95-3.18h0.05C55.042,33.89,54.082,37.17,58.652,37.17z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M44.702,37.17
+ c4.57,0,3.62-3.28,6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M58.652,37.17
+ c-4.57,0-3.61-3.28-6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M58.652,37.32
+ c-4.57,0-3.61,3.28-6.95,3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M44.702,37.32
+ c4.57,0,3.62,3.28,6.95,3.18"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_8_">
+ <g>
+ <path fill="#0A0A0A" d="M64.277,41.587v0.15c-4.57,0-3.61,3.279-6.95,3.18h-0.05c-3.33,0.1-2.38-3.18-6.95-3.18v-0.15
+ c4.57,0,3.62-3.28,6.95-3.18h0.05C60.667,38.307,59.707,41.587,64.277,41.587z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M50.327,41.587
+ c4.57,0,3.62-3.28,6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M64.277,41.587
+ c-4.57,0-3.61-3.28-6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M64.277,41.737
+ c-4.57,0-3.61,3.279-6.95,3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M50.327,41.737
+ c4.57,0,3.62,3.279,6.95,3.18"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_9_">
+ <g>
+ <path fill="#0A0A0A" d="M60.485,33.671v0.15c-4.57,0-3.61,3.28-6.95,3.18h-0.05c-3.33,0.1-2.38-3.18-6.95-3.18v-0.15
+ c4.57,0,3.62-3.28,6.95-3.18h0.05C56.875,30.391,55.915,33.671,60.485,33.671z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M46.535,33.671
+ c4.57,0,3.62-3.28,6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M60.485,33.671
+ c-4.57,0-3.61-3.28-6.95-3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M60.485,33.821
+ c-4.57,0-3.61,3.28-6.95,3.18"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M46.535,33.821
+ c4.57,0,3.62,3.28,6.95,3.18"/>
+ </g>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-grain-menu.svg b/TamTamSynthLab.activity/icons/sl-grain-menu.svg
new file mode 100644
index 0000000..fa772a1
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-grain-menu.svg
@@ -0,0 +1,190 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M9.667,16.825c0-3.389,4.911-7.559,8.888-7.559h42.222
+ c3.979,0,8.89,4.171,8.89,7.559v28.048c0,14.099-13.424,25.528-30,25.528c-16.577,0-30-11.43-30-25.528V16.825z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.547" y1="20.02" x2="21.547" y2="57.383"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.68" y1="39.35" x2="62.444" y2="39.35"/>
+<g>
+ <g>
+ <g id="XMLID_1_">
+ <g>
+ <path fill="#0A0A0A" d="M27.903,35.58c2.909-0.087,2.073,2.77,6.053,2.77v0.131c-3.98,0-3.144,2.856-6.053,2.77H27.86
+ c-2.9,0.087-2.073-2.77-6.053-2.77V38.35c3.98,0,3.153-2.856,6.053-2.77H27.903z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M21.807,38.35
+ c3.98,0,3.153-2.856,6.053-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M33.956,38.35
+ c-3.98,0-3.144-2.856-6.053-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M33.956,38.48
+ c-3.98,0-3.144,2.856-6.053,2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M21.807,38.48
+ c3.98,0,3.153,2.856,6.053,2.77"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_2_">
+ <g>
+ <path fill="#0A0A0A" d="M40.053,35.882v0.13c-3.98,0-3.144,2.857-6.053,2.77h-0.044c-2.9,0.087-2.073-2.77-6.053-2.77v-0.13
+ c3.98,0,3.153-2.857,6.053-2.77H34C36.909,33.025,36.073,35.882,40.053,35.882z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M27.903,35.882
+ c3.98,0,3.153-2.857,6.053-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M40.053,35.882
+ c-3.98,0-3.144-2.857-6.053-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M40.053,36.012
+ c-3.98,0-3.144,2.857-6.053,2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M27.903,36.012
+ c3.98,0,3.153,2.857,6.053,2.77"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_3_">
+ <g>
+ <path fill="#0A0A0A" d="M42.193,40.962v0.131c-3.98,0-3.144,2.856-6.053,2.77h-0.043c-2.9,0.087-2.073-2.77-6.053-2.77v-0.131
+ c3.98,0,3.153-2.857,6.053-2.77h0.043C39.049,38.105,38.213,40.962,42.193,40.962z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M30.044,40.962
+ c3.98,0,3.153-2.857,6.053-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M42.193,40.962
+ c-3.98,0-3.144-2.857-6.053-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M42.193,41.093
+ c-3.98,0-3.144,2.856-6.053,2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M30.044,41.093
+ c3.98,0,3.153,2.856,6.053,2.77"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_4_">
+ <g>
+ <path fill="#0A0A0A" d="M48.326,37.26v0.131c-3.979,0-3.144,2.856-6.053,2.77H42.23c-2.9,0.087-2.073-2.77-6.053-2.77V37.26
+ c3.98,0,3.153-2.856,6.053-2.77h0.043C45.183,34.404,44.347,37.26,48.326,37.26z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M36.177,37.26
+ c3.98,0,3.153-2.856,6.053-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M48.326,37.26
+ c-3.979,0-3.144-2.856-6.053-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M48.326,37.391
+ c-3.979,0-3.144,2.856-6.053,2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M36.177,37.391
+ c3.98,0,3.153,2.856,6.053,2.77"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_5_">
+ <g>
+ <path fill="#0A0A0A" d="M51.811,42.377v0.131c-3.98,0-3.145,2.856-6.054,2.77h-0.043c-2.9,0.087-2.073-2.77-6.053-2.77v-0.131
+ c3.98,0,3.153-2.856,6.053-2.77h0.043C48.666,39.521,47.83,42.377,51.811,42.377z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M39.661,42.377
+ c3.98,0,3.153-2.856,6.053-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M51.811,42.377
+ c-3.98,0-3.145-2.856-6.054-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M51.811,42.508
+ c-3.98,0-3.145,2.856-6.054,2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M39.661,42.508
+ c3.98,0,3.153,2.856,6.053,2.77"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_6_">
+ <g>
+ <path fill="#0A0A0A" d="M48.073,33.559v0.13c-3.98,0-3.145,2.857-6.053,2.77h-0.044c-2.9,0.087-2.073-2.77-6.053-2.77v-0.13
+ c3.98,0,3.152-2.857,6.053-2.77h0.044C44.929,30.702,44.093,33.559,48.073,33.559z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M35.924,33.559
+ c3.98,0,3.152-2.857,6.053-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M48.073,33.559
+ c-3.98,0-3.145-2.857-6.053-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M48.073,33.689
+ c-3.98,0-3.145,2.857-6.053,2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M35.924,33.689
+ c3.98,0,3.152,2.857,6.053,2.77"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_7_">
+ <g>
+ <path fill="#0A0A0A" d="M56.201,37.514v0.131c-3.979,0-3.144,2.856-6.053,2.77h-0.044c-2.899,0.087-2.072-2.77-6.053-2.77
+ v-0.131c3.98,0,3.153-2.856,6.053-2.77h0.044C53.058,34.657,52.222,37.514,56.201,37.514z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M44.052,37.514
+ c3.98,0,3.153-2.856,6.053-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M56.201,37.514
+ c-3.979,0-3.144-2.856-6.053-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M56.201,37.645
+ c-3.979,0-3.144,2.856-6.053,2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M44.052,37.645
+ c3.98,0,3.153,2.856,6.053,2.77"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_8_">
+ <g>
+ <path fill="#0A0A0A" d="M61.101,41.36v0.131c-3.98,0-3.145,2.856-6.053,2.77h-0.044c-2.9,0.087-2.073-2.77-6.053-2.77V41.36
+ c3.979,0,3.152-2.856,6.053-2.769h0.044C57.956,38.504,57.12,41.36,61.101,41.36z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M48.951,41.36
+ c3.979,0,3.152-2.856,6.053-2.769"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M61.101,41.36
+ c-3.98,0-3.145-2.856-6.053-2.769"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M61.101,41.491
+ c-3.98,0-3.145,2.856-6.053,2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M48.951,41.491
+ c3.979,0,3.152,2.856,6.053,2.77"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g>
+ <g>
+ <g id="XMLID_9_">
+ <g>
+ <path fill="#0A0A0A" d="M57.798,34.466v0.131c-3.98,0-3.144,2.856-6.053,2.77h-0.044c-2.9,0.087-2.072-2.77-6.053-2.77v-0.131
+ c3.98,0,3.152-2.856,6.053-2.77h0.044C54.654,31.61,53.817,34.466,57.798,34.466z"/>
+ </g>
+ <g>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M45.648,34.466
+ c3.98,0,3.152-2.856,6.053-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M57.798,34.466
+ c-3.98,0-3.144-2.856-6.053-2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M57.798,34.597
+ c-3.98,0-3.144,2.856-6.053,2.77"/>
+ <path fill="none" stroke="#666666" stroke-width="0.36" stroke-linecap="square" stroke-linejoin="round" d="M45.648,34.597
+ c3.98,0,3.152,2.856,6.053,2.77"/>
+ </g>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-harmon+.svg b/TamTamSynthLab.activity/icons/sl-harmon+.svg
new file mode 100644
index 0000000..ef4f968
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-harmon+.svg
@@ -0,0 +1,30 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <path fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M3.598,23.098
+ c0-9.332,7.571-16.902,16.902-16.902h33.805c9.332,0,16.889,7.571,16.889,16.902v33.806c0,9.33-7.557,16.9-16.889,16.9H20.5
+ c-9.332,0-16.902-7.57-16.902-16.9V23.098z"/>
+</g>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,20.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.327,5.209,5.195s-2.327,5.194-5.209,5.194C68.326,25.695,66,23.369,66,20.5z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,33.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.327,5.209,5.195s-2.327,5.194-5.209,5.194C68.326,38.695,66,36.368,66,33.5z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,46.499
+ c0-2.867,2.326-5.192,5.193-5.192c2.882,0,5.209,2.325,5.209,5.192c0,2.868-2.327,5.196-5.209,5.196
+ C68.326,51.695,66,49.367,66,46.499z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,59.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.326,5.209,5.195c0,2.868-2.327,5.195-5.209,5.195C68.326,64.695,66,62.368,66,59.5z"/>
+<path fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M32.299,6.195
+ C32.299,3.327,34.638,1,37.507,1c2.868,0,5.194,2.327,5.194,5.195c0,2.88-2.326,5.208-5.194,5.208
+ C34.638,11.403,32.299,9.076,32.299,6.195z"/>
+<path fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M32.299,73.805
+ c0-2.881,2.339-5.207,5.208-5.207c2.868,0,5.194,2.326,5.194,5.207c0,2.868-2.326,5.194-5.194,5.194
+ C34.638,78.999,32.299,76.673,32.299,73.805z"/>
+<line fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="14.054" y1="54.664" x2="59.055" y2="54.664"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="18.525" y1="44.484" x2="53.525" y2="44.484"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="24.036" y1="35.757" x2="49.979" y2="35.757"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="29.546" y1="26.998" x2="45.122" y2="26.998"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-harmon-menu.svg b/TamTamSynthLab.activity/icons/sl-harmon-menu.svg
new file mode 100644
index 0000000..de11295
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-harmon-menu.svg
@@ -0,0 +1,21 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <g>
+ <path fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M9.396,25c0-8.282,6.72-15,15.003-15
+ h30.006c8.284,0,14.991,6.719,14.991,15v30.001c0,8.28-6.707,14.998-14.991,14.998H24.398c-8.283,0-15.003-6.718-15.003-14.998V25
+ z"/>
+ </g>
+
+ <line fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="18.677" y1="53.014" x2="58.621" y2="53.014"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="22.646" y1="43.979" x2="53.713" y2="43.979"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="27.537" y1="36.234" x2="50.564" y2="36.234"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="32.428" y1="28.461" x2="46.254" y2="28.461"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-lfo+.svg b/TamTamSynthLab.activity/icons/sl-lfo+.svg
new file mode 100755
index 0000000..4bdaa74
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-lfo+.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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<polygon fill="#FFFF33" stroke="#333333" stroke-linecap="round" stroke-miterlimit="8" points="5.5,9.569 9.615,5.812
+ 69.386,5.812 73.5,9.569 73.5,50.617 57.114,73.812 24.151,73.812 5.5,50.617 "/>
+<circle fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" cx="39.5" cy="73.125" r="5.375"/>
+<line fill="none" stroke="#333333" stroke-width="1.08" stroke-linecap="round" stroke-linejoin="round" x1="18.11" y1="23.482" x2="18.11" y2="52.688"/>
+<line fill="none" stroke="#333333" stroke-width="1.08" stroke-linecap="round" stroke-linejoin="round" x1="18.11" y1="38.122" x2="63.109" y2="38.072"/>
+<line fill="none" stroke="#2D2B2B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="50.443" y1="26.607" x2="62.411" y2="38.607"/>
+<line fill="none" stroke="#2D2B2B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="28.451" y1="48.413" x2="50.337" y2="26.528"/>
+<line fill="none" stroke="#2D2B2B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="18.725" y1="38.688" x2="28.451" y2="48.413"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-lfo-menu.svg b/TamTamSynthLab.activity/icons/sl-lfo-menu.svg
new file mode 100644
index 0000000..e340173
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-lfo-menu.svg
@@ -0,0 +1,20 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <polygon fill="#FFFF33" stroke="#333333" stroke-linecap="round" stroke-miterlimit="8" points="9.5,13.127 13.131,9.812
+ 65.871,9.812 69.5,13.127 69.5,49.346 55.041,69.812 25.957,69.812 9.5,49.346 "/>
+
+ <line fill="none" stroke="#333333" stroke-width="1.08" stroke-linecap="round" stroke-linejoin="round" x1="20.626" y1="25.403" x2="20.626" y2="51.173"/>
+
+ <line fill="none" stroke="#333333" stroke-width="1.08" stroke-linecap="round" stroke-linejoin="round" x1="20.626" y1="38.321" x2="60.332" y2="38.276"/>
+
+ <line fill="none" stroke="#2D2B2B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="49.156" y1="28.161" x2="59.716" y2="38.749"/>
+
+ <line fill="none" stroke="#2D2B2B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="29.751" y1="47.401" x2="49.062" y2="28.091"/>
+
+ <line fill="none" stroke="#2D2B2B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="21.169" y1="38.82" x2="29.751" y2="47.401"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-noise+.svg b/TamTamSynthLab.activity/icons/sl-noise+.svg
new file mode 100755
index 0000000..abe48a5
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-noise+.svg
@@ -0,0 +1,233 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M5.221,13.415c0-3.891,5.639-8.679,10.206-8.679h48.479
+ c4.568,0,10.207,4.789,10.207,8.679V45.62c0,16.188-15.414,29.312-34.446,29.312c-19.033,0-34.446-13.123-34.446-29.312V13.415z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="18.862" y1="17.083" x2="18.862" y2="59.984"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M10.417,5.818
+ c0-2.758,2.326-4.985,5.195-4.985c2.88,0,5.207,2.228,5.207,4.985c0,2.745-2.327,4.986-5.207,4.986
+ C12.743,10.804,10.417,8.563,10.417,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M26.015,5.818
+ c0-2.758,2.326-4.985,5.207-4.985c2.868,0,5.195,2.228,5.195,4.985c0,2.745-2.327,4.986-5.195,4.986
+ C28.34,10.804,26.015,8.563,26.015,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M42.917,5.818
+ c0-2.758,2.326-4.985,5.194-4.985c2.881,0,5.207,2.228,5.207,4.985c0,2.745-2.326,4.986-5.207,4.986
+ C45.243,10.804,42.917,8.563,42.917,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M59.818,5.818
+ c0-2.758,2.328-4.985,5.195-4.985c2.869,0,5.209,2.228,5.209,4.985c0,2.745-2.34,4.986-5.209,4.986
+ C62.146,10.804,59.818,8.563,59.818,5.818z"/>
+<path fill="#DF3800" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M34.299,73.848
+ c0-2.744,2.339-4.984,5.207-4.984c2.869,0,5.195,2.24,5.195,4.984c0,2.758-2.326,4.985-5.195,4.985
+ C36.638,78.833,34.299,76.604,34.299,73.848z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="19.014" y1="39.278" x2="65.82" y2="39.278"/>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M19.695,36.961c2.058-33.71,3.979,0,3.979,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M27.407,34.635c-2.056,33.712-3.978,0-3.978,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M41.56,40.429c2.058-33.737,3.95,0,3.95,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M49.271,38.076c-2.057,33.735-3.979,0-3.979,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M24.836,40.429c2.057-33.737,3.979,0,3.979,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M32.548,38.076c-2.056,33.735-3.977,0-3.977,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M49.271,38.123c2.056-33.734,3.977,0,3.977,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M56.983,35.775c-2.057,33.735-3.978,0-3.978,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M33.847,39.264c2.057-33.711,3.951,0,3.951,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M41.56,36.938c-2.056,33.709-3.977,0-3.977,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M26.135,36.499c2.057-20.235,3.952,0,3.952,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M33.847,35.094c-2.056,20.238-3.977,0-3.977,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M20.968,39.967c2.083-20.262,3.977,0,3.977,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M28.706,38.561c-2.083,20.238-3.977,0-3.977,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M40.261,42.27c2.058-20.262,3.979,0,3.979,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M47.974,40.863c-2.058,20.236-3.951,0-3.951,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M54.412,43.408c2.058-20.238,3.978,0,3.978,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M62.126,42.002c-2.059,20.238-3.979,0-3.979,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M35.12,46.875c2.055-20.237,3.977,0,3.977,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M42.832,45.47c-2.057,20.235-3.951,0-3.951,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M37.689,29.594c2.058-20.236,3.979,0,3.979,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M45.402,28.188c-2.057,20.235-3.951,0-3.951,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M53.113,34.199c2.083-20.236,3.979,0,3.979,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M60.852,32.793c-2.081,20.235-3.977,0-3.977,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M20.968,46.875c2.083-20.237,3.977,0,3.977,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M28.706,45.47c-2.083,20.235-3.977,0-3.977,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M38.988,48.012c2.057-20.236,3.951,0,3.951,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M46.7,46.605c-2.057,20.238-3.978,0-3.978,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M45.402,36.499c2.057-20.235,3.978,0,3.978,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M53.113,35.094c-2.056,20.238-3.951,0-3.951,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M29.978,32.77c2.056-12.142,3.977,0,3.977,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M37.689,31.92c-2.056,12.144-3.977,0-3.977,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M54.412,32.77c2.058-12.142,3.978,0,3.978,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M62.126,31.92c-2.059,12.144-3.979,0-3.979,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M33.847,39.676c2.057-12.142,3.951,0,3.951,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M41.56,38.828c-2.056,12.142-3.977,0-3.977,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M51.842,39.676c2.057-12.142,3.978,0,3.978,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M59.553,38.828c-2.057,12.142-3.977,0-3.977,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M37.689,40.816c2.058-12.144,3.979,0,3.979,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M45.402,39.99c-2.057,12.144-3.951,0-3.951,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M42.832,47.746c2.055-12.142,3.977,0,3.977,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M50.542,46.899c-2.057,12.141-3.949,0-3.949,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M40.261,36.04c2.058-7.271,3.979,0,3.979,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M47.974,35.555c-2.058,7.271-3.951,0-3.951,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M38.988,32.599c2.057-7.294,3.951,0,3.951,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M46.7,32.09c-2.057,7.295-3.978,0-3.978,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M47.974,35.943c2.056-4.362,3.977,0,3.977,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M55.686,35.652c-2.059,4.364-3.951,0-3.951,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M45.402,40.547c2.057-4.359,3.978,0,3.978,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M53.113,40.258c-2.056,4.362-3.951,0-3.951,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M56.983,35.894c2.057-2.642,3.978,0,3.978,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="
+ M64.695,35.699c-2.057,2.618-3.978,0-3.978,0"/>
+ </g>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-noise-menu.svg b/TamTamSynthLab.activity/icons/sl-noise-menu.svg
new file mode 100644
index 0000000..3157316
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-noise-menu.svg
@@ -0,0 +1,222 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M9.667,17.252c0-3.326,4.911-7.418,8.889-7.418h42.222
+ c3.979,0,8.89,4.093,8.89,7.418v27.527c0,13.838-13.424,25.055-30,25.055c-16.577,0-30-11.217-30-25.055V17.252z"/>
+
+ <line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.547" y1="20.388" x2="21.547" y2="57.058"/>
+
+ <line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.68" y1="39.358" x2="62.444" y2="39.358"/>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M22.273,37.378
+ c1.792-28.814,3.465,0,3.465,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M28.99,35.39
+ c-1.791,28.816-3.465,0-3.465,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M41.316,40.343
+ c1.792-28.837,3.439,0,3.439,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M48.032,38.332
+ c-1.792,28.834-3.466,0-3.466,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M26.75,40.343
+ c1.792-28.837,3.465,0,3.465,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M33.467,38.332
+ c-1.791,28.834-3.464,0-3.464,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M48.032,38.372
+ c1.79-28.834,3.463,0,3.463,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M54.747,36.364
+ c-1.791,28.835-3.464,0-3.464,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M34.598,39.347
+ c1.792-28.814,3.441,0,3.441,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M41.316,37.358
+ c-1.792,28.812-3.464,0-3.464,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M27.881,36.983
+ c1.792-17.296,3.442,0,3.442,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M34.598,35.782
+ c-1.791,17.299-3.463,0-3.463,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M23.381,39.947
+ c1.814-17.318,3.464,0,3.464,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M30.121,38.746
+ c-1.814,17.298-3.463,0-3.463,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M40.185,41.916
+ c1.792-17.319,3.466,0,3.466,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M46.902,40.714
+ c-1.793,17.297-3.441,0-3.441,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M52.509,42.889
+ c1.793-17.298,3.465,0,3.465,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M59.228,41.688
+ c-1.794,17.298-3.466,0-3.466,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M35.707,45.853
+ c1.79-17.298,3.464,0,3.464,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M42.424,44.652
+ c-1.791,17.295-3.441,0-3.441,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M37.944,31.081
+ c1.792-17.296,3.466,0,3.466,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M44.662,29.879
+ c-1.791,17.296-3.441,0-3.441,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M51.378,35.018
+ c1.813-17.297,3.465,0,3.465,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M58.117,33.815
+ c-1.812,17.296-3.463,0-3.463,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M23.381,45.853
+ c1.814-17.298,3.464,0,3.464,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M30.121,44.652
+ c-1.814,17.295-3.463,0-3.463,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M39.076,46.824
+ c1.792-17.297,3.442,0,3.442,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M45.792,45.622
+ c-1.792,17.298-3.464,0-3.464,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M44.662,36.983
+ c1.791-17.296,3.464,0,3.464,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M51.378,35.782
+ c-1.791,17.299-3.441,0-3.441,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M31.229,33.796
+ c1.791-10.378,3.464,0,3.464,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M37.944,33.069
+ c-1.791,10.381-3.464,0-3.464,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M52.509,33.796
+ c1.793-10.378,3.465,0,3.465,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M59.228,33.069
+ c-1.794,10.381-3.466,0-3.466,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M34.598,39.699
+ c1.792-10.378,3.441,0,3.441,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M41.316,38.974
+ c-1.792,10.379-3.464,0-3.464,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M50.271,39.699
+ c1.791-10.378,3.465,0,3.465,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M56.986,38.974
+ c-1.791,10.379-3.464,0-3.464,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M37.944,40.674
+ c1.792-10.381,3.466,0,3.466,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M44.662,39.967
+ c-1.791,10.38-3.441,0-3.441,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M42.424,46.597
+ c1.789-10.378,3.463,0,3.463,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M49.139,45.872
+ c-1.792,10.378-3.439,0-3.439,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M40.185,36.591
+ c1.792-6.215,3.466,0,3.466,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M46.902,36.177
+ c-1.793,6.215-3.441,0-3.441,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M39.076,33.65
+ c1.792-6.234,3.442,0,3.442,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M45.792,33.215
+ c-1.792,6.235-3.464,0-3.464,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M46.902,36.508
+ c1.789-3.728,3.463,0,3.463,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M53.618,36.259
+ c-1.793,3.73-3.441,0-3.441,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M44.662,40.443
+ c1.791-3.726,3.464,0,3.464,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M51.378,40.196
+ c-1.791,3.729-3.441,0-3.441,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M54.747,36.466
+ c1.792-2.258,3.466,0,3.466,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M61.465,36.3
+ c-1.791,2.237-3.465,0-3.465,0"/>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-pluck+.svg b/TamTamSynthLab.activity/icons/sl-pluck+.svg
new file mode 100755
index 0000000..01bbf3d
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-pluck+.svg
@@ -0,0 +1,73 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M5.221,13.415c0-3.891,5.639-8.679,10.206-8.679h48.479
+ c4.568,0,10.207,4.789,10.207,8.679V45.62c0,16.188-15.414,29.312-34.446,29.312c-19.033,0-34.446-13.123-34.446-29.312V13.415z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="18.862" y1="17.083" x2="18.862" y2="59.984"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M10.417,5.818
+ c0-2.758,2.326-4.985,5.195-4.985c2.88,0,5.207,2.228,5.207,4.985c0,2.745-2.327,4.986-5.207,4.986
+ C12.743,10.804,10.417,8.563,10.417,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M26.015,5.818
+ c0-2.758,2.326-4.985,5.207-4.985c2.868,0,5.195,2.228,5.195,4.985c0,2.745-2.327,4.986-5.195,4.986
+ C28.34,10.804,26.015,8.563,26.015,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M42.917,5.818
+ c0-2.758,2.326-4.985,5.194-4.985c2.881,0,5.207,2.228,5.207,4.985c0,2.745-2.326,4.986-5.207,4.986
+ C45.243,10.804,42.917,8.563,42.917,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M59.818,5.818
+ c0-2.758,2.328-4.985,5.195-4.985c2.869,0,5.209,2.228,5.209,4.985c0,2.745-2.34,4.986-5.209,4.986
+ C62.146,10.804,59.818,8.563,59.818,5.818z"/>
+<path fill="#DF3800" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M34.299,73.848
+ c0-2.744,2.339-4.984,5.207-4.984c2.869,0,5.195,2.24,5.195,4.984c0,2.758-2.326,4.985-5.195,4.985
+ C36.638,78.833,34.299,76.604,34.299,73.848z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="19.014" y1="39.278" x2="65.82" y2="39.278"/>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="
+ M19.5,40.962c2.063-41.685,3.948,0,3.948,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="
+ M27.182,38.037c-2.063,41.688-3.948,0-3.948,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="
+ M26.939,40.206c2.062-25.012,3.948,0,3.948,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="
+ M34.621,38.465c-2.062,25.012-3.949,0-3.949,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="
+ M34.527,39.518c2.062-14.971,3.943,0,3.943,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="
+ M42.204,38.492c-2.059,14.979-3.944,0-3.944,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="
+ M41.761,39.159c2.063-9.009,3.948,0,3.948,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="
+ M49.442,38.527c-2.063,9.009-3.945,0-3.945,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="
+ M48.997,39.696c2.063-5.41,3.949,0,3.949,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="
+ M56.679,39.302c-2.062,5.414-3.948,0-3.948,0"/>
+ </g>
+</g>
+<g>
+ <g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="
+ M56.818,39.488c2.063-3.242,3.945,0,3.945,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="
+ M64.5,39.249c-2.063,3.241-3.948,0-3.948,0"/>
+ </g>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-pluck-menu.svg b/TamTamSynthLab.activity/icons/sl-pluck-menu.svg
new file mode 100644
index 0000000..3131019
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-pluck-menu.svg
@@ -0,0 +1,62 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M9.667,17.252c0-3.326,4.911-7.418,8.889-7.418h42.222
+ c3.979,0,8.89,4.093,8.89,7.418v27.527c0,13.838-13.424,25.055-30,25.055c-16.577,0-30-11.217-30-25.055V17.252z"/>
+
+ <line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.547" y1="20.388" x2="21.547" y2="57.058"/>
+
+ <line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.68" y1="39.358" x2="62.444" y2="39.358"/>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="M22.103,40.798
+ c1.797-35.63,3.438,0,3.438,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="M28.793,38.298
+ c-1.796,35.633-3.438,0-3.438,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="M28.582,40.152
+ c1.796-21.379,3.438,0,3.438,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="M35.272,38.664
+ c-1.796,21.379-3.439,0-3.439,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="M35.19,39.564
+ c1.796-12.797,3.434,0,3.434,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="M41.877,38.687
+ c-1.793,12.803-3.436,0-3.436,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="M41.491,39.257
+ c1.797-7.701,3.438,0,3.438,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="M48.18,38.717
+ c-1.796,7.7-3.436,0-3.436,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="M47.793,39.716
+ c1.797-4.624,3.438,0,3.438,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="M54.483,39.379
+ c-1.796,4.628-3.439,0-3.439,0"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="M54.604,39.538
+ c1.797-2.771,3.437,0,3.437,0"/>
+ <path fill="none" stroke="#000000" stroke-linecap="square" stroke-linejoin="round" d="M61.295,39.334
+ c-1.797,2.771-3.438,0-3.438,0"/>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-rand+.svg b/TamTamSynthLab.activity/icons/sl-rand+.svg
new file mode 100755
index 0000000..62d89d1
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-rand+.svg
@@ -0,0 +1,17 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<polygon fill="#FFFF33" stroke="#333333" stroke-linecap="round" stroke-miterlimit="8" points="5.5,8.569 9.615,4.812
+ 69.386,4.812 73.5,8.569 73.5,49.617 57.114,72.812 24.151,72.812 5.5,49.617 "/>
+<circle fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" cx="39.5" cy="73.125" r="5.375"/>
+<line fill="none" stroke="#333333" stroke-width="1.08" stroke-linecap="round" stroke-linejoin="round" x1="18.11" y1="19.482" x2="18.11" y2="48.688"/>
+<line fill="none" stroke="#333333" stroke-width="1.08" stroke-linecap="round" stroke-linejoin="round" x1="18.11" y1="34.122" x2="63.109" y2="34.072"/>
+<polyline fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" points="29.849,22.684
+ 26.539,41.294 19.04,26.295 "/>
+<polyline fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" points="45.152,24.78
+ 39.747,46.977 31.062,22.684 "/>
+<polyline fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" points="64.04,50.893
+ 59.241,20.589 51.16,29.881 45.454,25.083 "/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-rand-menu.svg b/TamTamSynthLab.activity/icons/sl-rand-menu.svg
new file mode 100644
index 0000000..e02bc99
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-rand-menu.svg
@@ -0,0 +1,20 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <polygon fill="#FFFF33" stroke="#333333" stroke-linecap="round" stroke-miterlimit="8" points="9.5,12.127 13.131,8.812
+ 65.871,8.812 69.5,12.127 69.5,48.346 55.041,68.812 25.957,68.812 9.5,48.346 "/>
+
+ <line fill="none" stroke="#333333" stroke-width="1.08" stroke-linecap="round" stroke-linejoin="round" x1="20.626" y1="21.756" x2="20.626" y2="47.525"/>
+
+ <line fill="none" stroke="#333333" stroke-width="1.08" stroke-linecap="round" stroke-linejoin="round" x1="20.626" y1="34.674" x2="60.332" y2="34.629"/>
+ <polyline fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" points="30.984,24.582
+ 28.064,41.002 21.447,27.768 "/>
+ <polyline fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" points="44.487,26.431
+ 39.718,46.016 32.055,24.582 "/>
+ <polyline fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" points="61.153,49.472
+ 56.919,22.733 49.788,30.932 44.754,26.698 "/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-reset.svg b/TamTamSynthLab.activity/icons/sl-reset.svg
new file mode 100644
index 0000000..833e85b
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-reset.svg
@@ -0,0 +1,13 @@
+<?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="55px" height="55px" viewBox="0 0 55 55" enable-background="new 0 0 55 55" xml:space="preserve">
+<polygon fill="none" stroke="#FFFFFF" stroke-width="2" points="36.668,46.959 17.384,46.671 13.751,19.147 40.626,19.147 "/>
+<path fill="none" stroke="#FFFFFF" stroke-width="2" d="M13.751,17.312c18.998-2.13,21.875-2.374,25.436-3.021
+ c3.561-0.647-8.347-2.808-12.054-2.375c-1.729,0.201-9.713,1.618-13.275,5.396"/>
+<path fill="none" stroke="#FFFFFF" stroke-width="2" d="M22.709,11.557l6.691-1.476c0,0-4.209-3.13-6.691,1.296"/>
+<line fill="none" stroke="#FFFFFF" x1="27.457" y1="24.652" x2="27.457" y2="39.763"/>
+<line fill="none" stroke="#FFFFFF" x1="35.229" y1="25.084" x2="33.502" y2="39.763"/>
+<line fill="none" stroke="#FFFFFF" x1="19.038" y1="25.731" x2="20.55" y2="39.763"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-reverb+.svg b/TamTamSynthLab.activity/icons/sl-reverb+.svg
new file mode 100644
index 0000000..44faefc
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-reverb+.svg
@@ -0,0 +1,39 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <path fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M3.598,23.098
+ c0-9.332,7.571-16.902,16.902-16.902h33.805c9.332,0,16.889,7.571,16.889,16.902v33.806c0,9.33-7.557,16.9-16.889,16.9H20.5
+ c-9.332,0-16.902-7.57-16.902-16.9V23.098z"/>
+</g>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,20.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.327,5.209,5.195s-2.327,5.194-5.209,5.194C68.326,25.695,66,23.369,66,20.5z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,33.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.327,5.209,5.195s-2.327,5.194-5.209,5.194C68.326,38.695,66,36.368,66,33.5z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,46.499
+ c0-2.867,2.326-5.192,5.193-5.192c2.882,0,5.209,2.325,5.209,5.192c0,2.868-2.327,5.196-5.209,5.196
+ C68.326,51.695,66,49.367,66,46.499z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,59.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.326,5.209,5.195c0,2.868-2.327,5.195-5.209,5.195C68.326,64.695,66,62.368,66,59.5z"/>
+<path fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M32.299,6.195
+ C32.299,3.327,34.638,1,37.507,1c2.868,0,5.194,2.327,5.194,5.195c0,2.88-2.326,5.208-5.194,5.208
+ C34.638,11.403,32.299,9.076,32.299,6.195z"/>
+<path fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M32.299,73.805
+ c0-2.881,2.339-5.207,5.208-5.207c2.868,0,5.194,2.326,5.194,5.207c0,2.868-2.326,5.194-5.194,5.194
+ C34.638,78.999,32.299,76.673,32.299,73.805z"/>
+<line fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="14.054" y1="59.664" x2="59.055" y2="59.664"/>
+<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="300.7227" y1="-327.5078" x2="330.7227" y2="-327.5078" gradientTransform="matrix(1 0 0 -1 -278.5 -288.5)">
+ <stop offset="0" style="stop-color:#FFFFFF"/>
+ <stop offset="0.0799" style="stop-color:#DBDBDB"/>
+ <stop offset="0.2375" style="stop-color:#999999"/>
+ <stop offset="0.3876" style="stop-color:#636363"/>
+ <stop offset="0.526" style="stop-color:#383838"/>
+ <stop offset="0.6501" style="stop-color:#191919"/>
+ <stop offset="0.7555" style="stop-color:#070707"/>
+ <stop offset="0.8297" style="stop-color:#000000"/>
+</linearGradient>
+<path fill="url(#SVGID_1_)" stroke="#000000" d="M22.222,38.996c0-8.283,6.707-14.987,14.987-14.987
+ c8.311,0,15.014,6.704,15.014,14.987c0,8.307-6.703,15.011-15.014,15.011C28.928,54.007,22.222,47.303,22.222,38.996z"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-reverb-menu.svg b/TamTamSynthLab.activity/icons/sl-reverb-menu.svg
new file mode 100644
index 0000000..c14a445
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-reverb-menu.svg
@@ -0,0 +1,28 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <g>
+ <path fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M9.396,25c0-8.282,6.72-15,15.003-15
+ h30.006c8.284,0,14.991,6.719,14.991,15v30.001c0,8.28-6.707,14.998-14.991,14.998H24.398c-8.283,0-15.003-6.718-15.003-14.998V25
+ z"/>
+ </g>
+
+ <line fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="18.677" y1="57.451" x2="58.621" y2="57.451"/>
+
+ <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="291.9277" y1="-316.1196" x2="318.5566" y2="-316.1196" gradientTransform="matrix(1 0 0 -1 -266 -277)">
+ <stop offset="0" style="stop-color:#FFFFFF"/>
+ <stop offset="0.0799" style="stop-color:#DBDBDB"/>
+ <stop offset="0.2375" style="stop-color:#999999"/>
+ <stop offset="0.3876" style="stop-color:#636363"/>
+ <stop offset="0.526" style="stop-color:#383838"/>
+ <stop offset="0.6501" style="stop-color:#191919"/>
+ <stop offset="0.7555" style="stop-color:#070707"/>
+ <stop offset="0.8297" style="stop-color:#000000"/>
+ </linearGradient>
+ <path fill="url(#SVGID_1_)" stroke="#000000" d="M25.927,39.109c0-7.351,5.953-13.3,13.303-13.3c7.376,0,13.327,5.95,13.327,13.3
+ c0,7.372-5.95,13.322-13.327,13.322C31.88,52.431,25.927,46.48,25.927,39.109z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-ring+.svg b/TamTamSynthLab.activity/icons/sl-ring+.svg
new file mode 100644
index 0000000..7fd5495
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-ring+.svg
@@ -0,0 +1,30 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <path fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M3.598,23.098
+ c0-9.332,7.571-16.902,16.902-16.902h33.805c9.332,0,16.889,7.571,16.889,16.902v33.806c0,9.33-7.557,16.9-16.889,16.9H20.5
+ c-9.332,0-16.902-7.57-16.902-16.9V23.098z"/>
+</g>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,20.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.327,5.209,5.195s-2.327,5.194-5.209,5.194C68.326,25.695,66,23.369,66,20.5z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,33.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.327,5.209,5.195s-2.327,5.194-5.209,5.194C68.326,38.695,66,36.368,66,33.5z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,46.499
+ c0-2.867,2.326-5.192,5.193-5.192c2.882,0,5.209,2.325,5.209,5.192c0,2.868-2.327,5.196-5.209,5.196
+ C68.326,51.695,66,49.367,66,46.499z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,59.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.326,5.209,5.195c0,2.868-2.327,5.195-5.209,5.195C68.326,64.695,66,62.368,66,59.5z"/>
+<path fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M32.299,6.195
+ C32.299,3.327,34.638,1,37.507,1c2.868,0,5.194,2.327,5.194,5.195c0,2.88-2.326,5.208-5.194,5.208
+ C34.638,11.403,32.299,9.076,32.299,6.195z"/>
+<path fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M32.299,73.805
+ c0-2.881,2.339-5.207,5.208-5.207c2.868,0,5.194,2.326,5.194,5.207c0,2.868-2.326,5.194-5.194,5.194
+ C34.638,78.999,32.299,76.673,32.299,73.805z"/>
+<line fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="14.054" y1="59.664" x2="59.055" y2="59.664"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="37.777" y1="21.95" x2="37.777" y2="55.3"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="50.295" y1="30.297" x2="50.295" y2="50.286"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="25.295" y1="30.297" x2="25.295" y2="50.286"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-ring-menu.svg b/TamTamSynthLab.activity/icons/sl-ring-menu.svg
new file mode 100644
index 0000000..731f2d2
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-ring-menu.svg
@@ -0,0 +1,21 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <g>
+ <path fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M9.396,25c0-8.282,6.72-15,15.003-15
+ h30.006c8.284,0,14.991,6.719,14.991,15v30.001c0,8.28-6.707,14.998-14.991,14.998H24.398c-8.283,0-15.003-6.718-15.003-14.998V25
+ z"/>
+ </g>
+
+ <line fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="18.677" y1="57.451" x2="58.621" y2="57.451"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="39.734" y1="23.981" x2="39.734" y2="53.578"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="50.846" y1="31.389" x2="50.846" y2="49.129"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="28.655" y1="31.389" x2="28.655" y2="49.129"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-sample+.svg b/TamTamSynthLab.activity/icons/sl-sample+.svg
new file mode 100755
index 0000000..fdca11a
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-sample+.svg
@@ -0,0 +1,34 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M5.221,13.415c0-3.891,5.639-8.679,10.206-8.679h48.479
+ c4.568,0,10.207,4.789,10.207,8.679V45.62c0,16.188-15.414,29.312-34.446,29.312c-19.033,0-34.446-13.123-34.446-29.312V13.415z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="18.862" y1="17.083" x2="18.862" y2="59.984"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M10.417,5.818
+ c0-2.758,2.326-4.985,5.195-4.985c2.88,0,5.207,2.228,5.207,4.985c0,2.745-2.327,4.986-5.207,4.986
+ C12.743,10.804,10.417,8.563,10.417,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M26.015,5.818
+ c0-2.758,2.326-4.985,5.207-4.985c2.868,0,5.195,2.228,5.195,4.985c0,2.745-2.327,4.986-5.195,4.986
+ C28.34,10.804,26.015,8.563,26.015,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M42.917,5.818
+ c0-2.758,2.326-4.985,5.194-4.985c2.881,0,5.207,2.228,5.207,4.985c0,2.745-2.326,4.986-5.207,4.986
+ C45.243,10.804,42.917,8.563,42.917,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M59.818,5.818
+ c0-2.758,2.328-4.985,5.195-4.985c2.869,0,5.209,2.228,5.209,4.985c0,2.745-2.34,4.986-5.209,4.986
+ C62.146,10.804,59.818,8.563,59.818,5.818z"/>
+<path fill="#DF3800" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M34.299,73.848
+ c0-2.744,2.339-4.984,5.207-4.984c2.869,0,5.195,2.24,5.195,4.984c0,2.758-2.326,4.985-5.195,4.985
+ C36.638,78.833,34.299,76.604,34.299,73.848z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="19.014" y1="39.278" x2="65.82" y2="39.278"/>
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#333333" d="M42.689,38.583c-0.818,1.25-3.273,1.25-3.273,5
+ c-0.818,3.75,0,7.5-1.636,11.25c0-5,0-10-0.818-15c-0.818,0-1.636,2.5-2.455,5c-0.818-2.5-2.455-5-4.909-5
+ c-1.636,0-2.455,6.25-3.272,10c-1.636-2.5-2.455-6.25-4.909-10c0.818-1.25,2.455-5,3.273-8.75c4.091,2.5,1.636,7.5,5.727,7.5
+ c2.455,0,3.273-1.25,4.091-3.75c0.818,0,0.818,2.5,2.455,5c1.636-5-1.636-11.25,2.455-13.75
+ C39.417,29.833,36.962,37.333,42.689,38.583z"/>
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#333333" d="M45.963,24.833c0,3.75,0,8.75,1.635,12.5
+ c4.092-1.25,0.818-8.75,5.729-12.5c0,3.75-1.637,10,4.908,13.75c0-3.75-1.637-10,3.273-13.75c0,3.75-0.818,7.5,0.818,11.25
+ c0.818,1.25,3.271,2.5,4.09,3.75c-8.182-1.25-3.271,11.25-7.363,13.75c0-3.75-0.818-8.75-0.818-12.5c0,0,0-1.25-1.637-1.25
+ c-4.09,0-4.09,12.5-4.09,15c-1.637-5-2.455-10-3.273-15c-5.727,2.5-1.637,8.75-5.727,13.75c0-2.5-0.818-6.25,0-28.75H45.963z"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-sample-menu.svg b/TamTamSynthLab.activity/icons/sl-sample-menu.svg
new file mode 100644
index 0000000..d1fb3ed
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-sample-menu.svg
@@ -0,0 +1,24 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M9.667,17.252c0-3.326,4.911-7.418,8.889-7.418h42.222
+ c3.979,0,8.89,4.093,8.89,7.418v27.527c0,13.838-13.424,25.055-30,25.055c-16.577,0-30-11.217-30-25.055V17.252z"/>
+
+ <line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.547" y1="20.388" x2="21.547" y2="57.058"/>
+
+ <line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.68" y1="39.358" x2="62.444" y2="39.358"/>
+ <path fill="#333333" d="M42.3,38.765c-0.713,1.068-2.852,1.068-2.852,4.273c-0.712,3.206,0,6.411-1.425,9.616
+ c0-4.273,0-8.548-0.712-12.821c-0.712,0-1.424,2.137-2.138,4.273c-0.712-2.137-2.138-4.273-4.275-4.273
+ c-1.425,0-2.138,5.343-2.85,8.548c-1.425-2.137-2.138-5.343-4.276-8.548c0.712-1.068,2.138-4.273,2.851-7.479
+ c3.563,2.137,1.425,6.411,4.988,6.411c2.138,0,2.851-1.068,3.563-3.205c0.713,0,0.713,2.137,2.138,4.273
+ c1.425-4.273-1.425-9.616,2.138-11.753C39.449,31.286,37.311,37.696,42.3,38.765z"/>
+ <path fill="#333333" d="M45.15,27.012c0,3.206,0,7.479,1.424,10.685c3.563-1.068,0.713-7.479,4.99-10.685
+ c0,3.206-1.427,8.548,4.273,11.753c0-3.205-1.426-8.547,2.851-11.753c0,3.206-0.713,6.411,0.713,9.616
+ c0.713,1.068,2.85,2.137,3.562,3.205c-7.126-1.068-2.85,9.616-6.413,11.753c0-3.205-0.713-7.479-0.713-10.685
+ c0,0,0-1.068-1.426-1.068c-3.562,0-3.562,10.685-3.562,12.821c-1.426-4.273-2.139-8.548-2.851-12.821
+ c-4.988,2.137-1.426,7.479-4.988,11.753c0-2.137-0.712-5.342,0-24.574H45.15z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-speaker.svg b/TamTamSynthLab.activity/icons/sl-speaker.svg
new file mode 100755
index 0000000..b0d38a5
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-speaker.svg
@@ -0,0 +1,13 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#FF0000" stroke="#333333" stroke-linecap="square" d="M29.528,20.354h23.383
+ c0,0,15.076,31.692,15.125,31.841c0.906,2.764-2.504,4.239-2.372,4.239c2.787,0-31.64-0.082-49.519-0.109
+ c-4.499-0.007-1.047-5.316-1.12-5.175C13.697,53.729,29.528,20.354,29.528,20.354z"/>
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#FF0000" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="
+ M65.648,5.702c3.083,0,5.57,1.493,5.57,3.358v11.194c0,1.866-2.487,3.358-5.57,3.358H16.792c-3.084,0-5.572-1.493-5.572-3.358V9.061
+ c0-1.866,2.488-3.358,5.572-3.358H65.648z"/>
+<circle fill-rule="evenodd" clip-rule="evenodd" fill="#FF0000" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" cx="41.816" cy="5.479" r="4.726"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-trackpadX+.svg b/TamTamSynthLab.activity/icons/sl-trackpadX+.svg
new file mode 100755
index 0000000..8122fed
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-trackpadX+.svg
@@ -0,0 +1,22 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<polygon fill="#FFFF33" stroke="#333333" stroke-linecap="round" stroke-miterlimit="8" points="5.5,8.569 9.615,4.812
+ 69.386,4.812 73.5,8.569 73.5,49.617 57.114,72.812 24.151,72.812 5.5,49.617 "/>
+<circle fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" cx="39.5" cy="73.125" r="5.375"/>
+<rect x="19.5" y="14.499" fill="none" stroke="#333333" stroke-width="2" stroke-linecap="square" stroke-linejoin="round" width="40" height="40.002"/>
+<g>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="39.641" y1="22.411" x2="39.641" y2="49.913"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="39.363" y1="21.411" x2="31.861" y2="28.91"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="39.363" y1="49.438" x2="31.861" y2="41.938"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="39.641" y1="21.16" x2="47.139" y2="28.661"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="39.641" y1="49.689" x2="47.139" y2="42.188"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-trackpadX-menu.svg b/TamTamSynthLab.activity/icons/sl-trackpadX-menu.svg
new file mode 100644
index 0000000..45e555c
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-trackpadX-menu.svg
@@ -0,0 +1,21 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<polygon fill="#FFFF33" stroke="#333333" stroke-linecap="round" stroke-miterlimit="8" points="9.5,12.127 13.131,8.812
+ 65.871,8.812 69.5,12.127 69.5,48.346 55.041,68.812 25.957,68.812 9.5,48.346 "/>
+<rect x="21.853" y="17.359" fill="none" stroke="#333333" stroke-width="2" stroke-linecap="square" stroke-linejoin="round" width="35.294" height="35.296"/>
+<g>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="39.625" y1="24.341" x2="39.625" y2="48.607"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="39.379" y1="23.458" x2="32.76" y2="30.075"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="39.379" y1="48.188" x2="32.76" y2="41.569"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="39.625" y1="23.237" x2="46.24" y2="29.855"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="39.625" y1="48.41" x2="46.24" y2="41.79"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-trackpadY+.svg b/TamTamSynthLab.activity/icons/sl-trackpadY+.svg
new file mode 100755
index 0000000..51bac2e
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-trackpadY+.svg
@@ -0,0 +1,22 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<polygon fill="#FFFF33" stroke="#333333" stroke-linecap="round" stroke-miterlimit="8" points="5.5,8.569 9.615,4.812
+ 69.386,4.812 73.5,8.569 73.5,49.617 57.114,72.812 24.151,72.812 5.5,49.617 "/>
+<circle fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" cx="39.5" cy="73.125" r="5.375"/>
+<rect x="17.001" y="10.8" fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="44.998" height="45"/>
+<g>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="24.734" y1="34.017" x2="55.7" y2="34.017"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="22.734" y1="34.396" x2="31.203" y2="42.831"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="55.859" y1="34.396" x2="47.451" y2="42.831"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="23.327" y1="34.017" x2="31.796" y2="25.549"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="56.266" y1="34.017" x2="47.857" y2="25.549"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-trackpadY-menu.svg b/TamTamSynthLab.activity/icons/sl-trackpadY-menu.svg
new file mode 100644
index 0000000..0d6598b
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-trackpadY-menu.svg
@@ -0,0 +1,21 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<polygon fill="#FFFF33" stroke="#333333" stroke-linecap="round" stroke-miterlimit="8" points="9.5,12.127 13.131,8.812
+ 65.871,8.812 69.5,12.127 69.5,48.346 55.041,68.812 25.957,68.812 9.5,48.346 "/>
+<rect x="22" y="19" fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="35" height="35"/>
+<g>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="28.491" y1="36.581" x2="51.578" y2="36.581"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="27" y1="36.916" x2="33.314" y2="44.358"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="51.697" y1="36.916" x2="45.428" y2="44.358"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="27.442" y1="36.581" x2="33.756" y2="29.109"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="52" y1="36.581" x2="45.73" y2="29.109"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-vco+.svg b/TamTamSynthLab.activity/icons/sl-vco+.svg
new file mode 100755
index 0000000..6b20870
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-vco+.svg
@@ -0,0 +1,31 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M5.221,13.415c0-3.891,5.639-8.679,10.206-8.679h48.479
+ c4.568,0,10.207,4.789,10.207,8.679V45.62c0,16.188-15.414,29.312-34.446,29.312c-19.033,0-34.446-13.123-34.446-29.312V13.415z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="18.862" y1="17.083" x2="18.862" y2="59.984"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M10.417,5.818
+ c0-2.758,2.326-4.985,5.195-4.985c2.88,0,5.207,2.228,5.207,4.985c0,2.745-2.327,4.986-5.207,4.986
+ C12.743,10.804,10.417,8.563,10.417,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M26.015,5.818
+ c0-2.758,2.326-4.985,5.207-4.985c2.868,0,5.195,2.228,5.195,4.985c0,2.745-2.327,4.986-5.195,4.986
+ C28.34,10.804,26.015,8.563,26.015,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M42.917,5.818
+ c0-2.758,2.326-4.985,5.194-4.985c2.881,0,5.207,2.228,5.207,4.985c0,2.745-2.326,4.986-5.207,4.986
+ C45.243,10.804,42.917,8.563,42.917,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M59.818,5.818
+ c0-2.758,2.328-4.985,5.195-4.985c2.869,0,5.209,2.228,5.209,4.985c0,2.745-2.34,4.986-5.209,4.986
+ C62.146,10.804,59.818,8.563,59.818,5.818z"/>
+<path fill="#DF3800" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M34.299,73.848
+ c0-2.744,2.339-4.984,5.207-4.984c2.869,0,5.195,2.24,5.195,4.984c0,2.758-2.326,4.985-5.195,4.985
+ C36.638,78.833,34.299,76.604,34.299,73.848z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="19.014" y1="39.278" x2="65.82" y2="39.278"/>
+<g>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#26282D" stroke-width="3" stroke-linecap="round" d="
+ M22.407,39.34c10.059-38.507,18.869,0,18.869,0"/>
+ <path fill-rule="evenodd" clip-rule="evenodd" fill="none" stroke="#26282D" stroke-width="3" stroke-linecap="round" d="
+ M60.407,40.167c-9.323,34.622-19.21-0.667-19.21-0.667"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-vco-menu.svg b/TamTamSynthLab.activity/icons/sl-vco-menu.svg
new file mode 100644
index 0000000..c73b410
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-vco-menu.svg
@@ -0,0 +1,19 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M9.667,17.252c0-3.326,4.911-7.418,8.889-7.418h42.222
+ c3.979,0,8.89,4.093,8.89,7.418v27.527c0,13.838-13.424,25.055-30,25.055c-16.577,0-30-11.217-30-25.055V17.252z"/>
+
+ <line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.547" y1="20.388" x2="21.547" y2="57.058"/>
+
+ <line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.68" y1="39.358" x2="62.444" y2="39.358"/>
+ <g>
+ <path fill="none" stroke="#26282D" stroke-width="3" stroke-linecap="round" d="M24.635,39.412c8.76-32.914,16.432,0,16.432,0"/>
+ <path fill="none" stroke="#26282D" stroke-width="3" stroke-linecap="round" d="M57.73,40.119C49.61,69.712,41,39.548,41,39.548"
+ />
+ </g>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-voice+.svg b/TamTamSynthLab.activity/icons/sl-voice+.svg
new file mode 100755
index 0000000..3e19ef1
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-voice+.svg
@@ -0,0 +1,28 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M5.221,13.415c0-3.891,5.639-8.679,10.206-8.679h48.479
+ c4.568,0,10.207,4.789,10.207,8.679v32.205c0,16.188-15.414,29.311-34.446,29.311c-19.033,0-34.446-13.122-34.446-29.311V13.415z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="18.862" y1="17.083" x2="18.862" y2="59.985"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M10.417,5.818
+ c0-2.758,2.326-4.985,5.195-4.985c2.88,0,5.207,2.228,5.207,4.985c0,2.745-2.327,4.986-5.207,4.986
+ C12.743,10.804,10.417,8.563,10.417,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M26.015,5.818
+ c0-2.758,2.326-4.985,5.207-4.985c2.868,0,5.195,2.228,5.195,4.985c0,2.745-2.327,4.986-5.195,4.986
+ C28.34,10.804,26.015,8.563,26.015,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M42.917,5.818
+ c0-2.758,2.326-4.985,5.194-4.985c2.881,0,5.208,2.228,5.208,4.985c0,2.745-2.327,4.986-5.208,4.986
+ C45.243,10.804,42.917,8.563,42.917,5.818z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M59.819,5.818
+ c0-2.758,2.327-4.985,5.194-4.985c2.87,0,5.209,2.228,5.209,4.985c0,2.745-2.339,4.986-5.209,4.986
+ C62.146,10.804,59.819,8.563,59.819,5.818z"/>
+<path fill="#DF3800" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M34.299,73.847
+ c0-2.744,2.339-4.984,5.207-4.984c2.869,0,5.195,2.24,5.195,4.984c0,2.758-2.326,4.986-5.195,4.986
+ C36.638,78.833,34.299,76.604,34.299,73.847z"/>
+<path fill-rule="evenodd" clip-rule="evenodd" fill="#333333" d="M25.582,25.87c1,2,2.25,4,3.25,7c3-2,4-5,5-8c2,1,4,6,6,8
+ c2-2,3-5,4-8c3,2,3,5,6,8c2-2,3-5,4-8h3c0,2,2,5,3,8c1,0,2-2,3-3v16c-1-1-1-2-2-3c-2,3-4,7-5,10c-2-2-3-6-6-10c-2,3-3,7-5,10
+ c-2-3-3-7-5-10c-2,3-3,7-5,10c-2-3-3-7-5-10c-2,3-4,7-5,10c-5-5-4-10-4-15v-3c0.25-6.12,3.75-10.12,2.62-11.62L25.582,25.87z"/>
+<line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="19.014" y1="39.278" x2="65.82" y2="39.278"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-voice-menu.svg b/TamTamSynthLab.activity/icons/sl-voice-menu.svg
new file mode 100644
index 0000000..525b290
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-voice-menu.svg
@@ -0,0 +1,21 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <path fill="#51A425" stroke="#333333" stroke-linecap="square" d="M9.667,17.252c0-3.326,4.911-7.418,8.889-7.418h42.222
+ c3.979,0,8.89,4.093,8.89,7.418v27.527c0,13.838-13.424,25.055-30,25.055c-16.577,0-30-11.217-30-25.055V17.252z"/>
+
+ <line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.547" y1="20.388" x2="21.547" y2="57.058"/>
+ <path fill="#333333" d="M27.4,27.898c0.871,1.709,1.96,3.419,2.831,5.983c2.613-1.709,3.484-4.273,4.354-6.838
+ c1.742,0.855,3.484,5.128,5.226,6.838c1.742-1.709,2.613-4.273,3.484-6.838c2.612,1.709,2.612,4.274,5.226,6.838
+ c1.741-1.709,2.612-4.273,3.483-6.838h2.612c0,1.709,1.742,4.274,2.613,6.838c0.871,0,1.741-1.709,2.612-2.564v13.676
+ c-0.871-0.854-0.871-1.709-1.741-2.564c-1.742,2.564-3.484,5.983-4.355,8.548c-1.741-1.709-2.612-5.129-5.225-8.548
+ c-1.742,2.564-2.613,5.983-4.355,8.548c-1.741-2.564-2.612-5.983-4.354-8.548c-1.742,2.564-2.613,5.983-4.354,8.548
+ c-1.742-2.564-2.613-5.983-4.354-8.548c-1.742,2.564-3.484,5.983-4.354,8.548c-4.355-4.273-3.484-8.548-3.484-12.821v-2.564
+ c0.218-5.231,3.266-8.65,2.282-9.933L27.4,27.898z"/>
+
+ <line fill="none" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" x1="21.68" y1="39.358" x2="62.444" y2="39.358"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-wguide+.svg b/TamTamSynthLab.activity/icons/sl-wguide+.svg
new file mode 100644
index 0000000..3dcf5a8
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-wguide+.svg
@@ -0,0 +1,32 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <path fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M3.598,23.098
+ c0-9.332,7.571-16.902,16.902-16.902h33.805c9.332,0,16.889,7.571,16.889,16.902v33.806c0,9.33-7.557,16.9-16.889,16.9H20.5
+ c-9.332,0-16.902-7.57-16.902-16.9V23.098z"/>
+</g>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,20.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.327,5.209,5.195s-2.327,5.194-5.209,5.194C68.326,25.695,66,23.369,66,20.5z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,33.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.327,5.209,5.195s-2.327,5.194-5.209,5.194C68.326,38.695,66,36.368,66,33.5z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,46.499
+ c0-2.867,2.326-5.192,5.193-5.192c2.882,0,5.209,2.325,5.209,5.192c0,2.868-2.327,5.196-5.209,5.196
+ C68.326,51.695,66,49.367,66,46.499z"/>
+<path fill="#F5D04E" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M66,59.5c0-2.869,2.326-5.195,5.193-5.195
+ c2.882,0,5.209,2.326,5.209,5.195c0,2.868-2.327,5.195-5.209,5.195C68.326,64.695,66,62.368,66,59.5z"/>
+<path fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M32.299,6.195
+ C32.299,3.327,34.638,1,37.507,1c2.868,0,5.194,2.327,5.194,5.195c0,2.88-2.326,5.208-5.194,5.208
+ C34.638,11.403,32.299,9.076,32.299,6.195z"/>
+<path fill="#DF0040" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M32.299,73.805
+ c0-2.881,2.339-5.207,5.208-5.207c2.868,0,5.194,2.326,5.194,5.207c0,2.868-2.326,5.194-5.194,5.194
+ C34.638,78.999,32.299,76.673,32.299,73.805z"/>
+<line fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="14.054" y1="59.664" x2="59.055" y2="59.664"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="18.729" y1="20.275" x2="18.729" y2="55.5"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="30.693" y1="26.461" x2="30.693" y2="51.094"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="40.771" y1="29.98" x2="40.771" y2="47.575"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="50.88" y1="33.501" x2="50.88" y2="44.057"/>
+<line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="58.729" y1="37.021" x2="58.729" y2="40.539"/>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/sl-wguide-menu.svg b/TamTamSynthLab.activity/icons/sl-wguide-menu.svg
new file mode 100644
index 0000000..6326493
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/sl-wguide-menu.svg
@@ -0,0 +1,25 @@
+<?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="80px" height="80px" viewBox="0 0 80 80" enable-background="new 0 0 80 80" xml:space="preserve">
+<g>
+ <g>
+ <path fill="#3399FF" stroke="#333333" stroke-linecap="round" stroke-linejoin="round" d="M9.396,25c0-8.282,6.72-15,15.003-15
+ h30.006c8.284,0,14.991,6.719,14.991,15v30.001c0,8.28-6.707,14.998-14.991,14.998H24.398c-8.283,0-15.003-6.718-15.003-14.998V25
+ z"/>
+ </g>
+
+ <line fill="none" stroke="#333333" stroke-linecap="square" stroke-linejoin="round" x1="18.677" y1="57.451" x2="58.621" y2="57.451"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="22.827" y1="22.495" x2="22.827" y2="53.756"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="33.446" y1="27.985" x2="33.446" y2="49.846"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="42.393" y1="31.108" x2="42.393" y2="46.723"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="51.365" y1="34.232" x2="51.365" y2="43.601"/>
+
+ <line fill="none" stroke="#333333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" x1="58.331" y1="37.356" x2="58.331" y2="40.479"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/icons/tam-help.svg b/TamTamSynthLab.activity/icons/tam-help.svg
new file mode 100644
index 0000000..2923bb3
--- /dev/null
+++ b/TamTamSynthLab.activity/icons/tam-help.svg
@@ -0,0 +1,18 @@
+<?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="45.395px" height="45.395px" viewBox="0 0 45.395 45.395" enable-background="new 0 0 45.395 45.395" xml:space="preserve">
+<circle fill="#808284" cx="22.297" cy="23.037" r="22.5"/>
+<circle fill="none" stroke="#4C4D4F" stroke-width="2.25" cx="22.295" cy="23.129" r="21.572"/>
+<circle fill="none" stroke="#4C4D4F" cx="22.628" cy="22.89" r="17.085"/>
+<g>
+ <path fill="#FFFFFF" stroke="#FFFFFF" d="M18.717,15.967c1.383-0.625,2.621-0.938,3.715-0.938c1.477,0,2.617,0.332,3.422,0.996
+ s1.207,1.645,1.207,2.941c0,1.344-0.871,2.738-2.613,4.184c-0.758,0.625-1.221,1.041-1.389,1.248s-0.303,0.459-0.404,0.756
+ s-0.152,0.668-0.152,1.113v0.645h-1.605v-0.668c0-1.359,0.434-2.418,1.301-3.176l1.547-1.359c0.5-0.422,0.867-0.85,1.102-1.283
+ s0.352-0.896,0.352-1.389c0-0.812-0.258-1.436-0.773-1.869s-1.219-0.65-2.109-0.65c-0.805,0-1.82,0.289-3.047,0.867L18.717,15.967z
+ M21.905,29.198c0.414,0,0.762,0.141,1.043,0.422s0.422,0.629,0.422,1.043c0,0.422-0.143,0.783-0.428,1.084
+ s-0.631,0.451-1.037,0.451c-0.398,0-0.738-0.15-1.02-0.451s-0.422-0.662-0.422-1.084s0.139-0.771,0.416-1.049
+ S21.498,29.198,21.905,29.198z"/>
+</g>
+</svg>
diff --git a/TamTamSynthLab.activity/setup.py b/TamTamSynthLab.activity/setup.py
new file mode 100644
index 0000000..5b21f11
--- /dev/null
+++ b/TamTamSynthLab.activity/setup.py
@@ -0,0 +1,21 @@
+#!/usr/bin/python
+
+# Copyright (C) 2006, Red Hat, Inc.
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from sugar.activity import bundlebuilder
+
+bundlebuilder.start('TamTam')