Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGary Martin <gary@garycmartin.com>2010-02-01 23:58:39 (GMT)
committer Gary Martin <gary@garycmartin.com>2010-02-01 23:58:39 (GMT)
commit62cfb4a105505f435b4fb3b7e3e936d289cebd90 (patch)
treeb4218910246bceabef5ca322310c7e0f9dc6eddb
parent2ea1cfff91fee38029967fa0aa332b67c3d1c549 (diff)
Push of latest work from Art (CRLF changes, font sizes etc).
-rw-r--r--MANIFEST18
-rw-r--r--MyMusicASCII.csd348
-rw-r--r--MyMusicMIDI.csd158
-rw-r--r--OurMusicASCII.csd624
-rw-r--r--OurMusicMIDI.csd320
-rw-r--r--activity/activity.info22
-rw-r--r--csndsugui.py1581
-rw-r--r--ourmusic.py565
-rw-r--r--setup.py7
9 files changed, 1838 insertions, 1805 deletions
diff --git a/MANIFEST b/MANIFEST
index 3a71842..37cebba 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,9 +1,9 @@
-setup.py
-MyMusicMIDI.csd
-MyMusicASCII.csd
-OurMusicMIDI.csd
-OurMusicASCII.csd
-activity/activity.info
-activity/activity-ourmusic.svg
-csndsugui.py
-ourmusic.py
+setup.py
+MyMusicMIDI.csd
+MyMusicASCII.csd
+OurMusicMIDI.csd
+OurMusicASCII.csd
+activity/activity.info
+activity/activity-ourmusic.svg
+csndsugui.py
+ourmusic.py
diff --git a/MyMusicASCII.csd b/MyMusicASCII.csd
index 51b6f7e..22ab690 100644
--- a/MyMusicASCII.csd
+++ b/MyMusicASCII.csd
@@ -1,174 +1,174 @@
-; OurMusic (2009) for Sugar and Sugar-on-a-Stick - by Arthur B. Hunkins
-; MyMusicASCII.csd - performed on 1 or more ASCII keyboards (no MIDI).
-
-<CsoundSynthesizer>
-<CsOptions>
-
--odac -+rtaudio=alsa -m0d --expression-opt -b128 -B2048
-
-</CsOptions>
-<CsInstruments>
-
-sr = 32000
-ksmps = 100
-nchnls = 2
-
- seed 0
-
-gipan chnexport "pan", 1
-gkasc chnexport "ascii", 1
-
-gkpan init 0
-gkasc init 0
-gktime init 6
-
- instr 1
-
-gkoff = 0
- if gkasc > 0 goto next
-gkinst = 0
- kgoto end
-next:
- if ((gkasc < 48) || (gkasc > 57)) goto skip
-gktime = gkasc - 48
-gktime = (gkasc == 48? gktime + 10: gktime)
- kgoto end
-skip:
- if (gkasc != 113) goto skip2
-gkinst = 2
- kgoto end
-skip2:
- if (gkasc != 119) goto skip3
-gkinst = 3
- kgoto end
-skip3:
- if (gkasc != 101) goto skip4
-gkinst = 4
- kgoto end
-skip4:
- if (gkasc != 114) goto skip5
-gkinst = 5
- kgoto end
-skip5:
- if (gkasc != 116) goto skip6
-gkinst = 6
- kgoto end
-skip6:
- if (gkasc != 121) goto skip7
-gkinst = 7
- kgoto end
-skip7:
- if (gkasc != 117) goto skip8
-gkinst = 8
- kgoto end
-skip8:
- if (gkasc != 105) goto skip9
-gkinst = 9
- kgoto end
-skip9:
- if gipan == 0 goto skip19
- if (gkasc != 122) goto skip10
-gkpan = -.5
- goto end
-skip10:
- if (gkasc != 120) goto skip11
-gkpan = -.4
- goto end
-skip11:
- if (gkasc != 99) goto skip12
-gkpan = -.3
- goto end
-skip12:
- if (gkasc != 118) goto skip13
-gkpan = -.2
- goto end
-skip13:
- if (gkasc != 98) goto skip14
-gkpan = -.1
- goto end
-skip14:
- if (gkasc != 110) goto skip15
-gkpan = .1
- goto end
-skip15:
- if (gkasc != 109) goto skip16
-gkpan = .2
- goto end
-skip16:
- if (gkasc != 44) goto skip17
-gkpan = .3
- goto end
-skip17:
- if (gkasc != 46) goto skip18
-gkpan = .4
- goto end
-skip18:
- if (gkasc != 47) goto skip19
-gkpan = .5
- goto end
-skip19:
- if (gkasc != 45) goto end
-gkoff = 1
-end:
-gkasc = 0
-
- endin
-
- instr 2, 3, 4, 5, 6, 7, 8, 9
-
-k1 init 0
-indx = p1 - 2
- if p1 != gkinst goto skip
-ktime = gktime
-k1 = (k1 == 0? 1: 0)
-skip:
- if gkoff == 0 goto skip2
-k1 = 0
-ktime = gktime
-skip2:
-kamp2 lineto k1, ktime
-kamp table kamp2 * 512, 1
-kamp = (kamp2 < .007? 0: kamp)
-kamp port kamp, .01
-ktrig trigger kamp2, .01, 0
- if ktrig == 0 goto skip3
- if gipan == 1 goto skip4
-kpan rnd31 .5, .7
-kpan = (p1 > 2? kpan: 0)
-gkpan = kpan
- kgoto skip3
-skip4:
-gkpan = (p1 == 2? 0: gkpan)
-kpan = gkpan
-skip3:
-kmod2 rspline 1.4, 2, 1.5, 2.5
-kmod rspline .85, 1, 20, 25
-kfreq jspline .25, 1, 2
-kpw jspline p7, 1, 2
-aout vco2 p4 * kamp * kmod * kmod2, 440 + kfreq, p5, p6 + kpw
-kamp2 port kamp2, .01
-a1,a2,a3,a4 pan aout, .5 + (kamp2 * kpan), 1, 2, 1
- outs a1 - (.02 * a2), a2 - (.02 * a1)
-
- endin
-
-</CsInstruments>
-
-<CsScore>
-
-f1 0 512 16 1 511 2.2 1000
-f2 0 8193 7 0 8193 1
-i1 0 3600
-i2 0 3600 6000 4 .5 .015
-i3 0 3600 3000 4 .7 .02
-i4 0 3600 4200 4 .8 .017
-i5 0 3600 2000 4 .95 .01
-i6 0 3600 1300 2 .6 .02
-i7 0 3600 1500 2 .7 .02
-i8 0 3600 2100 2 .8 .02
-i9 0 3600 2200 2 .95 .014
-
-e
-
-</CsScore>
-</CsoundSynthesizer>
+; OurMusic (2009) for Sugar and Sugar-on-a-Stick - by Arthur B. Hunkins
+; MyMusicASCII.csd - performed on 1 or more ASCII keyboards (no MIDI).
+
+<CsoundSynthesizer>
+<CsOptions>
+
+-odac -+rtaudio=alsa -m0d --expression-opt -b128 -B2048
+
+</CsOptions>
+<CsInstruments>
+
+sr = 32000
+ksmps = 100
+nchnls = 2
+
+ seed 0
+
+gipan chnexport "pan", 1
+gkasc chnexport "ascii", 1
+
+gkpan init 0
+gkasc init 0
+gktime init 6
+
+ instr 1
+
+gkoff = 0
+ if gkasc > 0 goto next
+gkinst = 0
+ kgoto end
+next:
+ if ((gkasc < 48) || (gkasc > 57)) goto skip
+gktime = gkasc - 48
+gktime = (gkasc == 48? gktime + 10: gktime)
+ kgoto end
+skip:
+ if (gkasc != 113) goto skip2
+gkinst = 2
+ kgoto end
+skip2:
+ if (gkasc != 119) goto skip3
+gkinst = 3
+ kgoto end
+skip3:
+ if (gkasc != 101) goto skip4
+gkinst = 4
+ kgoto end
+skip4:
+ if (gkasc != 114) goto skip5
+gkinst = 5
+ kgoto end
+skip5:
+ if (gkasc != 116) goto skip6
+gkinst = 6
+ kgoto end
+skip6:
+ if (gkasc != 121) goto skip7
+gkinst = 7
+ kgoto end
+skip7:
+ if (gkasc != 117) goto skip8
+gkinst = 8
+ kgoto end
+skip8:
+ if (gkasc != 105) goto skip9
+gkinst = 9
+ kgoto end
+skip9:
+ if gipan == 0 goto skip19
+ if (gkasc != 122) goto skip10
+gkpan = -.5
+ goto end
+skip10:
+ if (gkasc != 120) goto skip11
+gkpan = -.4
+ goto end
+skip11:
+ if (gkasc != 99) goto skip12
+gkpan = -.3
+ goto end
+skip12:
+ if (gkasc != 118) goto skip13
+gkpan = -.2
+ goto end
+skip13:
+ if (gkasc != 98) goto skip14
+gkpan = -.1
+ goto end
+skip14:
+ if (gkasc != 110) goto skip15
+gkpan = .1
+ goto end
+skip15:
+ if (gkasc != 109) goto skip16
+gkpan = .2
+ goto end
+skip16:
+ if (gkasc != 44) goto skip17
+gkpan = .3
+ goto end
+skip17:
+ if (gkasc != 46) goto skip18
+gkpan = .4
+ goto end
+skip18:
+ if (gkasc != 47) goto skip19
+gkpan = .5
+ goto end
+skip19:
+ if (gkasc != 45) goto end
+gkoff = 1
+end:
+gkasc = 0
+
+ endin
+
+ instr 2, 3, 4, 5, 6, 7, 8, 9
+
+k1 init 0
+indx = p1 - 2
+ if p1 != gkinst goto skip
+ktime = gktime
+k1 = (k1 == 0? 1: 0)
+skip:
+ if gkoff == 0 goto skip2
+k1 = 0
+ktime = gktime
+skip2:
+kamp2 lineto k1, ktime
+kamp table kamp2 * 512, 1
+kamp = (kamp2 < .007? 0: kamp)
+kamp port kamp, .01
+ktrig trigger kamp2, .01, 0
+ if ktrig == 0 goto skip3
+ if gipan == 1 goto skip4
+kpan rnd31 .5, .7
+kpan = (p1 > 2? kpan: 0)
+gkpan = kpan
+ kgoto skip3
+skip4:
+gkpan = (p1 == 2? 0: gkpan)
+kpan = gkpan
+skip3:
+kmod2 rspline 1.4, 2, 1.5, 2.5
+kmod rspline .85, 1, 20, 25
+kfreq jspline .25, 1, 2
+kpw jspline p7, 1, 2
+aout vco2 p4 * kamp * kmod * kmod2, 440 + kfreq, p5, p6 + kpw
+kamp2 port kamp2, .01
+a1,a2,a3,a4 pan aout, .5 + (kamp2 * kpan), 1, 2, 1
+ outs a1 - (.02 * a2), a2 - (.02 * a1)
+
+ endin
+
+</CsInstruments>
+
+<CsScore>
+
+f1 0 512 16 1 511 2.2 1000
+f2 0 8193 7 0 8193 1
+i1 0 3600
+i2 0 3600 6000 4 .5 .015
+i3 0 3600 3000 4 .7 .02
+i4 0 3600 4200 4 .8 .017
+i5 0 3600 2000 4 .95 .01
+i6 0 3600 1300 2 .6 .02
+i7 0 3600 1500 2 .7 .02
+i8 0 3600 2100 2 .8 .02
+i9 0 3600 2200 2 .95 .014
+
+e
+
+</CsScore>
+</CsoundSynthesizer>
diff --git a/MyMusicMIDI.csd b/MyMusicMIDI.csd
index d7e41f9..bda55e6 100644
--- a/MyMusicMIDI.csd
+++ b/MyMusicMIDI.csd
@@ -1,79 +1,79 @@
-; OurMusic (2009) for Sugar and Sugar-on-a-Stick - by Arthur B. Hunkins
-; MyMusicMIDI.csd - requires MIDI device with 8 or 9 pots/sliders
-
-<CsoundSynthesizer>
-<CsOptions>
-
--odac -+rtaudio=alsa -+rtmidi=alsa -M hw:1,0 -m0d --expression-opt -b128 -B2048 -+raw_controller_mode=1
-
-</CsOptions>
-<CsInstruments>
-
-sr = 32000
-ksmps = 100
-nchnls = 2
-
- seed 0
-
-gichan chnexport "chan", 1
-gictrl1 chnexport "ctrl", 1
-gipan chnexport "pan", 1
-gipctrl chnexport "panctrl", 1
-
- instr 1, 2, 3, 4, 5, 6, 7, 8
-
-kpan init 0
-indx = p1 - 1
-ictrl = gictrl1 + indx
-kamp2 ctrl7 (gichan > 0? gichan: p1), (gichan > 0? ictrl: 7), 0, 1
-kamp table kamp2 * 512, 1
-kamp = (kamp2 == 0? 0: kamp)
-kamp port kamp, .01
-ktrig trigger kamp2, .01, 0
- if ktrig == 0 goto skip
- if gipan == 1 goto skip2
-kpan rnd31 .5, .7
-kpan = (p1 > 1? kpan: 0)
- kgoto skip
-skip2:
-gkpan ctrl7 (gichan > 0? gichan: 9), (gichan > 0? gipctrl: 7), -.5, .5
- if p1 > 1 goto skip3
-kpan = 0
-gkpan2 = gkpan
-gkflag = 1
- kgoto skip
-skip3:
-kpan = (((gkpan2 == gkpan) && (gkflag == 1))? 0: gkpan)
-gkpan2 = gkpan
-gkflag = (kpan == 0? 1: 0)
-skip:
-kmod2 rspline 1.4, 2, 1.5, 2.5
-kmod rspline .85, 1, 20, 25
-kfreq jspline .25, 1, 2
-kpw jspline p7, 1, 2
-aout vco2 p4 * kamp * kmod * kmod2, 440 + (p1 > 1? kfreq: 0), p5, p6 + kpw
-kamp2 port kamp2, .01
-a1,a2,a3,a4 pan aout, .5 + (kamp2 * kpan), 1, 2, 1
- outs a1 - (.02 * a2), a2 - (.02 * a1)
-
- endin
-
-</CsInstruments>
-
-<CsScore>
-
-f1 0 512 16 1 511 2.2 1000
-f2 0 8193 7 0 8193 1
-i1 0 3600 6000 4 .5 .015
-i2 0 3600 3000 4 .7 .02
-i3 0 3600 4200 4 .8 .017
-i4 0 3600 2000 4 .95 .01
-i5 0 3600 1300 2 .6 .02
-i6 0 3600 1500 2 .7 .02
-i7 0 3600 2100 2 .8 .02
-i8 0 3600 2200 2 .95 .014
-
-e
-
-</CsScore>
-</CsoundSynthesizer>
+; OurMusic (2009) for Sugar and Sugar-on-a-Stick - by Arthur B. Hunkins
+; MyMusicMIDI.csd - requires MIDI device with 8 or 9 pots/sliders
+
+<CsoundSynthesizer>
+<CsOptions>
+
+-odac -+rtaudio=alsa -+rtmidi=alsa -M hw:1,0 -m0d --expression-opt -b128 -B2048 -+raw_controller_mode=1
+
+</CsOptions>
+<CsInstruments>
+
+sr = 32000
+ksmps = 100
+nchnls = 2
+
+ seed 0
+
+gichan chnexport "chan", 1
+gictrl1 chnexport "ctrl", 1
+gipan chnexport "pan", 1
+gipctrl chnexport "panctrl", 1
+
+ instr 1, 2, 3, 4, 5, 6, 7, 8
+
+kpan init 0
+indx = p1 - 1
+ictrl = gictrl1 + indx
+kamp2 ctrl7 (gichan > 0? gichan: p1), (gichan > 0? ictrl: 7), 0, 1
+kamp table kamp2 * 512, 1
+kamp = (kamp2 == 0? 0: kamp)
+kamp port kamp, .01
+ktrig trigger kamp2, .01, 0
+ if ktrig == 0 goto skip
+ if gipan == 1 goto skip2
+kpan rnd31 .5, .7
+kpan = (p1 > 1? kpan: 0)
+ kgoto skip
+skip2:
+gkpan ctrl7 (gichan > 0? gichan: 9), (gichan > 0? gipctrl: 7), -.5, .5
+ if p1 > 1 goto skip3
+kpan = 0
+gkpan2 = gkpan
+gkflag = 1
+ kgoto skip
+skip3:
+kpan = (((gkpan2 == gkpan) && (gkflag == 1))? 0: gkpan)
+gkpan2 = gkpan
+gkflag = (kpan == 0? 1: 0)
+skip:
+kmod2 rspline 1.4, 2, 1.5, 2.5
+kmod rspline .85, 1, 20, 25
+kfreq jspline .25, 1, 2
+kpw jspline p7, 1, 2
+aout vco2 p4 * kamp * kmod * kmod2, 440 + (p1 > 1? kfreq: 0), p5, p6 + kpw
+kamp2 port kamp2, .01
+a1,a2,a3,a4 pan aout, .5 + (kamp2 * kpan), 1, 2, 1
+ outs a1 - (.02 * a2), a2 - (.02 * a1)
+
+ endin
+
+</CsInstruments>
+
+<CsScore>
+
+f1 0 512 16 1 511 2.2 1000
+f2 0 8193 7 0 8193 1
+i1 0 3600 6000 4 .5 .015
+i2 0 3600 3000 4 .7 .02
+i3 0 3600 4200 4 .8 .017
+i4 0 3600 2000 4 .95 .01
+i5 0 3600 1300 2 .6 .02
+i6 0 3600 1500 2 .7 .02
+i7 0 3600 2100 2 .8 .02
+i8 0 3600 2200 2 .95 .014
+
+e
+
+</CsScore>
+</CsoundSynthesizer>
diff --git a/OurMusicASCII.csd b/OurMusicASCII.csd
index 4a4ce26..d476b90 100644
--- a/OurMusicASCII.csd
+++ b/OurMusicASCII.csd
@@ -1,312 +1,312 @@
-; OurMusic (2009) for Sugar and Sugar-on-a-Stick - by Arthur B. Hunkins
-; OurMusicASCII.csd - performed on 1 or more ASCII keyboards (no MIDI).
-
-<CsoundSynthesizer>
-<CsOptions>
-
--odac -+rtaudio=alsa -m0d --expression-opt -b128 -B2048
-
-</CsOptions>
-<CsInstruments>
-
-sr = 32000
-ksmps = 100
-nchnls = 2
-
- seed 0
-
-giharm chnexport "harm", 1
-gipan chnexport "pan", 1
-gidepth chnexport "depth", 1
-gkasc chnexport "ascii", 1
-
-ga1 init 0
-ga2 init 0
-gkpan init 0
-gkasc init 0
-gkharm init 1
-gkdepth init 0
-gktime init 6
-
- instr 1
-
-gkoff = 0
- if gkasc > 0 goto next
-gkinst = 0
- kgoto end
-next:
- if ((gkasc < 48) || (gkasc > 57)) goto skip
-gktime = gkasc - 48
-gktime = (gkasc == 48? gktime + 10: gktime)
- kgoto end
-skip:
- if (gkasc != 113) goto skip2
-gkinst = 2
- kgoto end
-skip2:
- if (gkasc != 119) goto skip3
-gkinst = 3
- kgoto end
-skip3:
- if (gkasc != 101) goto skip4
-gkinst = 4
- kgoto end
-skip4:
- if (gkasc != 114) goto skip5
-gkinst = 5
- kgoto end
-skip5:
- if (gkasc != 116) goto skip6
-gkinst = 6
- kgoto end
-skip6:
- if (gkasc != 121) goto skip7
-gkinst = 7
- kgoto end
-skip7:
- if (gkasc != 117) goto skip8
-gkinst = 8
- kgoto end
-skip8:
- if (gkasc != 105) goto skip9
-gkinst = 9
- kgoto end
-skip9:
- if gipan == 0 goto skip19
- if (gkasc != 122) goto skip10
-gkpan = -.5
- kgoto end
-skip10:
- if (gkasc != 120) goto skip11
-gkpan = -.4
- kgoto end
-skip11:
- if (gkasc != 99) goto skip12
-gkpan = -.3
- kgoto end
-skip12:
- if (gkasc != 118) goto skip13
-gkpan = -.2
- kgoto end
-skip13:
- if (gkasc != 98) goto skip14
-gkpan = -.1
- kgoto end
-skip14:
- if (gkasc != 110) goto skip15
-gkpan = .1
- kgoto end
-skip15:
- if (gkasc != 109) goto skip16
-gkpan = .2
- kgoto end
-skip16:
- if (gkasc != 44) goto skip17
-gkpan = .3
- kgoto end
-skip17:
- if (gkasc != 46) goto skip18
-gkpan = .4
- kgoto end
-skip18:
- if (gkasc != 47) goto skip19
-gkpan = .5
- kgoto end
-skip19:
- if (gkasc != 45) goto skip20
-gkoff = 1
- kgoto end
-skip20:
- if giharm < 2 goto skip30
- if (gkasc != 97) goto skip21
-gkharm = 1
- kgoto end
-skip21:
- if (gkasc != 115) goto skip22
-gkharm = 2
- kgoto end
-skip22:
- if (gkasc != 100) goto skip23
-gkharm = 3
- kgoto end
-skip23:
- if (gkasc != 102) goto skip24
-gkharm = 4
- kgoto end
-skip24:
- if (gkasc != 103) goto skip25
-gkharm = 5
- kgoto end
-skip25:
- if (gkasc != 104) goto skip26
-gkharm = 6
- kgoto end
-skip26:
- if (gkasc != 106) goto skip27
-gkharm = 7
- kgoto end
-skip27:
- if (gkasc != 107) goto skip28
-gkharm = 8
- kgoto end
-skip28:
- if (gkasc != 108) goto skip29
-gkharm = 9
- kgoto end
-skip29:
- if (gkasc != 59) goto skip30
-gkharm = 10
- kgoto end
-skip30:
- if gidepth < 2 goto end
- if (gkasc != 33) goto skip31
-gkdepth = .1
- goto end
-skip31:
- if (gkasc != 64) goto skip32
-gkdepth = .2
- goto end
-skip32:
- if (gkasc != 35) goto skip33
-gkdepth = .3
- goto end
-skip33:
- if (gkasc != 36) goto skip34
-gkdepth = .4
- goto end
-skip34:
- if (gkasc != 37) goto skip35
-gkdepth = .5
- goto end
-skip35:
- if (gkasc != 94) goto skip36
-gkdepth = .6
- goto end
-skip36:
- if (gkasc != 38) goto skip37
-gkdepth = .7
- goto end
-skip37:
- if (gkasc != 42) goto skip38
-gkdepth = .8
- goto end
-skip38:
- if (gkasc != 40) goto skip39
-gkdepth = .9
- goto end
-skip39:
- if ((gkasc != 41) && (gkasc != 96) && (gkasc != 126)) goto end
-gkdepth = 0
-end:
-gkasc = 0
-
- endin
-
- instr 2, 3, 4, 5, 6, 7, 8, 9
-
- if (gidepth == 0) || (p1 > 2) goto skip
- event_i "i", 10, 0, 3600
-skip:
-k1 init 0
-kold init 0
-indx = p1 - 2
- if p1 != gkinst goto skip2
-ktime = gktime
-k1 = (k1 == 0? 1: 0)
-skip2:
- if gkoff == 0 goto skip3
-k1 = 0
-ktime = gktime
-skip3:
-kamp2 lineto k1, ktime
-kamp table kamp2 * 512, 1
-kamp = (kamp2 < .007? 0: kamp)
-kamp port kamp, .01
-ktrig trigger kamp2, .01, 0
- if ktrig == 0 goto skip4
- if giharm == 1 goto back
- if giharm == 2 goto skip5
-imult tab_i indx, 3
-kmult = imult
- kgoto skip6
-back:
-kmult random 1, 10.99
-kmult = (p1 == 2? 1: int(kmult))
- if (kmult == kold) && (p1 > 2) goto back
-kold = kmult
- kgoto skip6
-skip5:
-kmult = (p1 == 2? 1: gkharm)
-skip6:
- if gipan == 1 goto skip7
-kpan rnd31 .5, .7
-kpan = (p1 > 2? kpan: 0)
-gkpan = kpan
- kgoto skip8
-skip7:
-gkpan = (p1 == 2? 0: gkpan)
-kpan = gkpan
-skip8:
- if gidepth == 0 goto skip4
- if gidepth == 1 goto skip10
-gkdepth = (p1 == 2? 0: gkdepth)
-kdepth = gkdepth
- kgoto skip4
-skip10:
-kdepth unirand .9
-kdepth = (p1 == 2? 0: kdepth)
-gkdepth = kdepth
-skip4:
-kmod2 rspline 1.4, 2, 1.5, 2.5
-kmod rspline .85, 1, 20, 25
-kfreq jspline .25, 1, 2
-kpw jspline p7, 1, 2
- if (gidepth == 0) || (p1 == 2) goto skip11
-kamp = kamp * (1 - (kdepth * .3))
-skip11:
-aout vco2 p4 * kamp * kmod * kmod2, (kmult * 55) + kfreq, p5, p6 + kpw
-kamp2 port kamp2, .01
-a1,a2,a3,a4 pan aout, .5 + (kamp2 * kpan), 1, 2, 1
- if (gidepth == 0) || (p1 == 2) goto skip12
-ga1 = ga1 + (a1 * kdepth)
-ga2 = ga2 + (a2 * kdepth)
-a1a = a1 * (1 - kdepth)
-a2a = a2 * (1 - kdepth)
- outs a1a - (.02 * a2a), a2a - (.02 * a1a)
- goto fin
-skip12:
- outs a1 - (.02 * a2), a2 - (.02 * a1)
-
-fin: endin
-
- instr 10
-
-aL, aR reverbsc ga1, ga2, .95, 800, sr, .25
- outs aL * .4, aR * .4
-
-ga1 = 0
-ga2 = 0
-
- endin
-
-</CsInstruments>
-
-<CsScore>
-
-f1 0 512 16 1 511 2.2 1000
-f2 0 8193 7 0 8193 1
-f3 0 8 -2 1 2 3 5 7 8 9 10
-i1 0 3600
-i2 0 3600 6000 4 .5 .015
-i3 0 3600 800 2 .6 .02
-i4 0 3600 1400 2 .7 .02
-i5 0 3600 1400 2 .8 .02
-i6 0 3600 3100 4 .6 .028
-i7 0 3600 3500 4 .7 .028
-i8 0 3600 2800 4 .8 .028
-i9 0 3600 2400 4 .9 .028
-
-e
-
-</CsScore>
-</CsoundSynthesizer>
+; OurMusic (2009) for Sugar and Sugar-on-a-Stick - by Arthur B. Hunkins
+; OurMusicASCII.csd - performed on 1 or more ASCII keyboards (no MIDI).
+
+<CsoundSynthesizer>
+<CsOptions>
+
+-odac -+rtaudio=alsa -m0d --expression-opt -b128 -B2048
+
+</CsOptions>
+<CsInstruments>
+
+sr = 32000
+ksmps = 100
+nchnls = 2
+
+ seed 0
+
+giharm chnexport "harm", 1
+gipan chnexport "pan", 1
+gidepth chnexport "depth", 1
+gkasc chnexport "ascii", 1
+
+ga1 init 0
+ga2 init 0
+gkpan init 0
+gkasc init 0
+gkharm init 1
+gkdepth init 0
+gktime init 6
+
+ instr 1
+
+gkoff = 0
+ if gkasc > 0 goto next
+gkinst = 0
+ kgoto end
+next:
+ if ((gkasc < 48) || (gkasc > 57)) goto skip
+gktime = gkasc - 48
+gktime = (gkasc == 48? gktime + 10: gktime)
+ kgoto end
+skip:
+ if (gkasc != 113) goto skip2
+gkinst = 2
+ kgoto end
+skip2:
+ if (gkasc != 119) goto skip3
+gkinst = 3
+ kgoto end
+skip3:
+ if (gkasc != 101) goto skip4
+gkinst = 4
+ kgoto end
+skip4:
+ if (gkasc != 114) goto skip5
+gkinst = 5
+ kgoto end
+skip5:
+ if (gkasc != 116) goto skip6
+gkinst = 6
+ kgoto end
+skip6:
+ if (gkasc != 121) goto skip7
+gkinst = 7
+ kgoto end
+skip7:
+ if (gkasc != 117) goto skip8
+gkinst = 8
+ kgoto end
+skip8:
+ if (gkasc != 105) goto skip9
+gkinst = 9
+ kgoto end
+skip9:
+ if gipan == 0 goto skip19
+ if (gkasc != 122) goto skip10
+gkpan = -.5
+ kgoto end
+skip10:
+ if (gkasc != 120) goto skip11
+gkpan = -.4
+ kgoto end
+skip11:
+ if (gkasc != 99) goto skip12
+gkpan = -.3
+ kgoto end
+skip12:
+ if (gkasc != 118) goto skip13
+gkpan = -.2
+ kgoto end
+skip13:
+ if (gkasc != 98) goto skip14
+gkpan = -.1
+ kgoto end
+skip14:
+ if (gkasc != 110) goto skip15
+gkpan = .1
+ kgoto end
+skip15:
+ if (gkasc != 109) goto skip16
+gkpan = .2
+ kgoto end
+skip16:
+ if (gkasc != 44) goto skip17
+gkpan = .3
+ kgoto end
+skip17:
+ if (gkasc != 46) goto skip18
+gkpan = .4
+ kgoto end
+skip18:
+ if (gkasc != 47) goto skip19
+gkpan = .5
+ kgoto end
+skip19:
+ if (gkasc != 45) goto skip20
+gkoff = 1
+ kgoto end
+skip20:
+ if giharm < 2 goto skip30
+ if (gkasc != 97) goto skip21
+gkharm = 1
+ kgoto end
+skip21:
+ if (gkasc != 115) goto skip22
+gkharm = 2
+ kgoto end
+skip22:
+ if (gkasc != 100) goto skip23
+gkharm = 3
+ kgoto end
+skip23:
+ if (gkasc != 102) goto skip24
+gkharm = 4
+ kgoto end
+skip24:
+ if (gkasc != 103) goto skip25
+gkharm = 5
+ kgoto end
+skip25:
+ if (gkasc != 104) goto skip26
+gkharm = 6
+ kgoto end
+skip26:
+ if (gkasc != 106) goto skip27
+gkharm = 7
+ kgoto end
+skip27:
+ if (gkasc != 107) goto skip28
+gkharm = 8
+ kgoto end
+skip28:
+ if (gkasc != 108) goto skip29
+gkharm = 9
+ kgoto end
+skip29:
+ if (gkasc != 59) goto skip30
+gkharm = 10
+ kgoto end
+skip30:
+ if gidepth < 2 goto end
+ if (gkasc != 33) goto skip31
+gkdepth = .1
+ goto end
+skip31:
+ if (gkasc != 64) goto skip32
+gkdepth = .2
+ goto end
+skip32:
+ if (gkasc != 35) goto skip33
+gkdepth = .3
+ goto end
+skip33:
+ if (gkasc != 36) goto skip34
+gkdepth = .4
+ goto end
+skip34:
+ if (gkasc != 37) goto skip35
+gkdepth = .5
+ goto end
+skip35:
+ if (gkasc != 94) goto skip36
+gkdepth = .6
+ goto end
+skip36:
+ if (gkasc != 38) goto skip37
+gkdepth = .7
+ goto end
+skip37:
+ if (gkasc != 42) goto skip38
+gkdepth = .8
+ goto end
+skip38:
+ if (gkasc != 40) goto skip39
+gkdepth = .9
+ goto end
+skip39:
+ if ((gkasc != 41) && (gkasc != 96) && (gkasc != 126)) goto end
+gkdepth = 0
+end:
+gkasc = 0
+
+ endin
+
+ instr 2, 3, 4, 5, 6, 7, 8, 9
+
+ if (gidepth == 0) || (p1 > 2) goto skip
+ event_i "i", 10, 0, 3600
+skip:
+k1 init 0
+kold init 0
+indx = p1 - 2
+ if p1 != gkinst goto skip2
+ktime = gktime
+k1 = (k1 == 0? 1: 0)
+skip2:
+ if gkoff == 0 goto skip3
+k1 = 0
+ktime = gktime
+skip3:
+kamp2 lineto k1, ktime
+kamp table kamp2 * 512, 1
+kamp = (kamp2 < .007? 0: kamp)
+kamp port kamp, .01
+ktrig trigger kamp2, .01, 0
+ if ktrig == 0 goto skip4
+ if giharm == 1 goto back
+ if giharm == 2 goto skip5
+imult tab_i indx, 3
+kmult = imult
+ kgoto skip6
+back:
+kmult random 1, 10.99
+kmult = (p1 == 2? 1: int(kmult))
+ if (kmult == kold) && (p1 > 2) goto back
+kold = kmult
+ kgoto skip6
+skip5:
+kmult = (p1 == 2? 1: gkharm)
+skip6:
+ if gipan == 1 goto skip7
+kpan rnd31 .5, .7
+kpan = (p1 > 2? kpan: 0)
+gkpan = kpan
+ kgoto skip8
+skip7:
+gkpan = (p1 == 2? 0: gkpan)
+kpan = gkpan
+skip8:
+ if gidepth == 0 goto skip4
+ if gidepth == 1 goto skip10
+gkdepth = (p1 == 2? 0: gkdepth)
+kdepth = gkdepth
+ kgoto skip4
+skip10:
+kdepth unirand .9
+kdepth = (p1 == 2? 0: kdepth)
+gkdepth = kdepth
+skip4:
+kmod2 rspline 1.4, 2, 1.5, 2.5
+kmod rspline .85, 1, 20, 25
+kfreq jspline .25, 1, 2
+kpw jspline p7, 1, 2
+ if (gidepth == 0) || (p1 == 2) goto skip11
+kamp = kamp * (1 - (kdepth * .3))
+skip11:
+aout vco2 p4 * kamp * kmod * kmod2, (kmult * 55) + kfreq, p5, p6 + kpw
+kamp2 port kamp2, .01
+a1,a2,a3,a4 pan aout, .5 + (kamp2 * kpan), 1, 2, 1
+ if (gidepth == 0) || (p1 == 2) goto skip12
+ga1 = ga1 + (a1 * kdepth)
+ga2 = ga2 + (a2 * kdepth)
+a1a = a1 * (1 - kdepth)
+a2a = a2 * (1 - kdepth)
+ outs a1a - (.02 * a2a), a2a - (.02 * a1a)
+ goto fin
+skip12:
+ outs a1 - (.02 * a2), a2 - (.02 * a1)
+
+fin: endin
+
+ instr 10
+
+aL, aR reverbsc ga1, ga2, .95, 800, sr, .25
+ outs aL * .4, aR * .4
+
+ga1 = 0
+ga2 = 0
+
+ endin
+
+</CsInstruments>
+
+<CsScore>
+
+f1 0 512 16 1 511 2.2 1000
+f2 0 8193 7 0 8193 1
+f3 0 8 -2 1 2 3 5 7 8 9 10
+i1 0 3600
+i2 0 3600 6000 4 .5 .015
+i3 0 3600 800 2 .6 .02
+i4 0 3600 1400 2 .7 .02
+i5 0 3600 1400 2 .8 .02
+i6 0 3600 3100 4 .6 .028
+i7 0 3600 3500 4 .7 .028
+i8 0 3600 2800 4 .8 .028
+i9 0 3600 2400 4 .9 .028
+
+e
+
+</CsScore>
+</CsoundSynthesizer>
diff --git a/OurMusicMIDI.csd b/OurMusicMIDI.csd
index d1b311e..54e011a 100644
--- a/OurMusicMIDI.csd
+++ b/OurMusicMIDI.csd
@@ -1,160 +1,160 @@
-; OurMusic (2009) for Sugar and Sugar-on-a-Stick - by Arthur B. Hunkins
-; OurMusicMIDI.csd - requires MIDI device with 8 - 11 pots/sliders,
-; alternatively, 8 - 10 pots/sliders with 10 MIDI notes
-
-<CsoundSynthesizer>
-<CsOptions>
-
--odac -+rtaudio=alsa -+rtmidi=alsa -M hw:1,0 -m0d --expression-opt -b128 -B2048 -+raw_controller_mode=1
-
-</CsOptions>
-<CsInstruments>
-
-sr = 32000
-ksmps = 100
-nchnls = 2
-
- massign 0, 0
- seed 0
-
-gichan chnexport "chan", 1
-gictrl1 chnexport "ctrl", 1
-giharm chnexport "harm", 1
-gihctrl chnexport "harctrl", 1
-gihmidi chnexport "harmidi", 1
-gipan chnexport "pan", 1
-gipctrl chnexport "panctrl", 1
-gidepth chnexport "depth", 1
-gidctrl chnexport "depctrl", 1
-
-ga1 init 0
-ga2 init 0
-gkharm init 1
-
- instr 1, 2, 3, 4, 5, 6, 7, 8
-
- if (gidepth == 0) || (p1 > 1) goto skip
- event_i "i", 9, 0, 3600
-skip:
- if (giharm != 3) || (p1 > 1) || (gichan == 0) goto skip2
-kstat,kchan,kd1,kd2 midiin
- if kchan != gichan goto skip2
- if ((kstat != 144) || (kd2 == 0)) goto skip2
- if ((kd1 < gihmidi) || (kd1 > (gihmidi + 9))) goto skip2
-gkharm = kd1 - gihmidi + 1
-skip2:
-kpan init 0
-kold init 0
-indx = p1 - 1
-ictrl = gictrl1 + indx
-kamp2 ctrl7 (gichan > 0? gichan: p1), (gichan > 0? ictrl: 7), 0, 1
-kamp table kamp2 * 512, 1
-kamp = (kamp2 == 0? 0: kamp)
-kamp port kamp, .01
-ktrig trigger kamp2, .01, 0
- if ktrig == 0 goto skip3
- if giharm == 1 goto back
- if giharm == 2 goto skip4
- if giharm == 3 goto skip5
-imult tab_i indx, 3
-kmult = imult
- kgoto skip6
-back:
-kmult random 1, 10.99
-kmult = (p1 == 1? 1: int(kmult))
- if (kmult == kold) && (p1 > 1) goto back
-kold = kmult
- kgoto skip6
-skip4:
-kmult ctrl7 (gichan > 0? gichan: 9), (gichan > 0? gihctrl: 7), 1, 10.99
-kmult = (p1 == 1? 1: int(kmult))
- kgoto skip6
-skip5:
-kmult = (p1 == 1? 1: gkharm)
-gkharm = kmult
-skip6:
- if gipan == 1 goto skip7
-kpan rnd31 .5, .7
-kpan = (p1 > 1? kpan: 0)
- kgoto skip8
-skip7:
-gkpan ctrl7 (gichan > 0? gichan: 10), (gichan > 0? gipctrl: 7), -.5, .5
- if p1 > 1 goto skip9
-kpan = 0
-gkpan2 = gkpan
-gkflag = 1
- kgoto skip8
-skip9:
-kpan = (((gkpan2 == gkpan) && (gkflag == 1))? 0: gkpan)
-gkpan2 = gkpan
-gkflag = (kpan == 0? 1: 0)
-skip8:
- if gidepth == 0 goto skip3
- if gidepth == 1 goto skip10
-gkdepth ctrl7 (gichan > 0? gichan: 11), (gichan > 0? gidctrl: 7), 0, .9
- if p1 > 1 goto skip11
-kdepth = 0
-gkdep2 = gkdepth
-gkflag2 = 1
- kgoto skip3
-skip11:
-kdepth = (((gkdep2 == gkdepth) && (gkflag2 == 1))? 0: gkdepth)
-gkdep2 = gkdepth
-gkflag2 = (kdepth == 0? 1: 0)
- kgoto skip3
-skip10:
-kdepth unirand .9
-kdepth = (p1 > 1? kdepth: 0)
-skip3:
-kmod2 rspline 1.4, 2, 1.5, 2.5
-kmod rspline .85, 1, 20, 25
-kfreq jspline .25, 1, 2
-kpw jspline p7, 1, 2
- if (gidepth == 0) || (p1 == 1) goto skip12
-kamp = kamp * (1 - (kdepth * .3))
-skip12:
-aout vco2 p4 * kamp * kmod * kmod2, (kmult * 55) + (p1 > 1? kfreq: 0), p5, p6 + kpw
-kamp2 port kamp2, .01
-a1,a2,a3,a4 pan aout, .5 + (kamp2 * kpan), 1, 2, 1
- if (gidepth == 0) || (p1 == 1) goto skip13
-ga1 = ga1 + (a1 * kdepth)
-ga2 = ga2 + (a2 * kdepth)
-a1a = a1 * (1 - kdepth)
-a2a = a2 * (1 - kdepth)
- outs a1a - (.02 * a2a), a2a - (.02 * a1a)
- goto fin
-skip13:
- outs a1 - (.02 * a2), a2 - (.02 * a1)
-
-fin: endin
-
- instr 9
-
-aL, aR reverbsc ga1, ga2, .95, 800, sr, .25
- outs aL * .4, aR * .4
-
-ga1 = 0
-ga2 = 0
-
- endin
-
-</CsInstruments>
-
-<CsScore>
-
-f1 0 512 16 1 511 2.2 1000
-f2 0 8193 7 0 8193 1
-f3 0 8 -2 1 2 3 5 7 8 9 10
-i1 0 3600 6000 4 .5 .015
-i2 0 3600 800 2 .6 .02
-i3 0 3600 1400 2 .7 .02
-i4 0 3600 1400 2 .8 .02
-i5 0 3600 3100 4 .6 .028
-i6 0 3600 3500 4 .7 .028
-i7 0 3600 2800 4 .8 .028
-i8 0 3600 2400 4 .9 .028
-
-e
-
-</CsScore>
-</CsoundSynthesizer>
+; OurMusic (2009) for Sugar and Sugar-on-a-Stick - by Arthur B. Hunkins
+; OurMusicMIDI.csd - requires MIDI device with 8 - 11 pots/sliders,
+; alternatively, 8 - 10 pots/sliders with 10 MIDI notes
+
+<CsoundSynthesizer>
+<CsOptions>
+
+-odac -+rtaudio=alsa -+rtmidi=alsa -M hw:1,0 -m0d --expression-opt -b128 -B2048 -+raw_controller_mode=1
+
+</CsOptions>
+<CsInstruments>
+
+sr = 32000
+ksmps = 100
+nchnls = 2
+
+ massign 0, 0
+ seed 0
+
+gichan chnexport "chan", 1
+gictrl1 chnexport "ctrl", 1
+giharm chnexport "harm", 1
+gihctrl chnexport "harctrl", 1
+gihmidi chnexport "harmidi", 1
+gipan chnexport "pan", 1
+gipctrl chnexport "panctrl", 1
+gidepth chnexport "depth", 1
+gidctrl chnexport "depctrl", 1
+
+ga1 init 0
+ga2 init 0
+gkharm init 1
+
+ instr 1, 2, 3, 4, 5, 6, 7, 8
+
+ if (gidepth == 0) || (p1 > 1) goto skip
+ event_i "i", 9, 0, 3600
+skip:
+ if (giharm != 3) || (p1 > 1) || (gichan == 0) goto skip2
+kstat,kchan,kd1,kd2 midiin
+ if kchan != gichan goto skip2
+ if ((kstat != 144) || (kd2 == 0)) goto skip2
+ if ((kd1 < gihmidi) || (kd1 > (gihmidi + 9))) goto skip2
+gkharm = kd1 - gihmidi + 1
+skip2:
+kpan init 0
+kold init 0
+indx = p1 - 1
+ictrl = gictrl1 + indx
+kamp2 ctrl7 (gichan > 0? gichan: p1), (gichan > 0? ictrl: 7), 0, 1
+kamp table kamp2 * 512, 1
+kamp = (kamp2 == 0? 0: kamp)
+kamp port kamp, .01
+ktrig trigger kamp2, .01, 0
+ if ktrig == 0 goto skip3
+ if giharm == 1 goto back
+ if giharm == 2 goto skip4
+ if giharm == 3 goto skip5
+imult tab_i indx, 3
+kmult = imult
+ kgoto skip6
+back:
+kmult random 1, 10.99
+kmult = (p1 == 1? 1: int(kmult))
+ if (kmult == kold) && (p1 > 1) goto back
+kold = kmult
+ kgoto skip6
+skip4:
+kmult ctrl7 (gichan > 0? gichan: 9), (gichan > 0? gihctrl: 7), 1, 10.99
+kmult = (p1 == 1? 1: int(kmult))
+ kgoto skip6
+skip5:
+kmult = (p1 == 1? 1: gkharm)
+gkharm = kmult
+skip6:
+ if gipan == 1 goto skip7
+kpan rnd31 .5, .7
+kpan = (p1 > 1? kpan: 0)
+ kgoto skip8
+skip7:
+gkpan ctrl7 (gichan > 0? gichan: 10), (gichan > 0? gipctrl: 7), -.5, .5
+ if p1 > 1 goto skip9
+kpan = 0
+gkpan2 = gkpan
+gkflag = 1
+ kgoto skip8
+skip9:
+kpan = (((gkpan2 == gkpan) && (gkflag == 1))? 0: gkpan)
+gkpan2 = gkpan
+gkflag = (kpan == 0? 1: 0)
+skip8:
+ if gidepth == 0 goto skip3
+ if gidepth == 1 goto skip10
+gkdepth ctrl7 (gichan > 0? gichan: 11), (gichan > 0? gidctrl: 7), 0, .9
+ if p1 > 1 goto skip11
+kdepth = 0
+gkdep2 = gkdepth
+gkflag2 = 1
+ kgoto skip3
+skip11:
+kdepth = (((gkdep2 == gkdepth) && (gkflag2 == 1))? 0: gkdepth)
+gkdep2 = gkdepth
+gkflag2 = (kdepth == 0? 1: 0)
+ kgoto skip3
+skip10:
+kdepth unirand .9
+kdepth = (p1 > 1? kdepth: 0)
+skip3:
+kmod2 rspline 1.4, 2, 1.5, 2.5
+kmod rspline .85, 1, 20, 25
+kfreq jspline .25, 1, 2
+kpw jspline p7, 1, 2
+ if (gidepth == 0) || (p1 == 1) goto skip12
+kamp = kamp * (1 - (kdepth * .3))
+skip12:
+aout vco2 p4 * kamp * kmod * kmod2, (kmult * 55) + (p1 > 1? kfreq: 0), p5, p6 + kpw
+kamp2 port kamp2, .01
+a1,a2,a3,a4 pan aout, .5 + (kamp2 * kpan), 1, 2, 1
+ if (gidepth == 0) || (p1 == 1) goto skip13
+ga1 = ga1 + (a1 * kdepth)
+ga2 = ga2 + (a2 * kdepth)
+a1a = a1 * (1 - kdepth)
+a2a = a2 * (1 - kdepth)
+ outs a1a - (.02 * a2a), a2a - (.02 * a1a)
+ goto fin
+skip13:
+ outs a1 - (.02 * a2), a2 - (.02 * a1)
+
+fin: endin
+
+ instr 9
+
+aL, aR reverbsc ga1, ga2, .95, 800, sr, .25
+ outs aL * .4, aR * .4
+
+ga1 = 0
+ga2 = 0
+
+ endin
+
+</CsInstruments>
+
+<CsScore>
+
+f1 0 512 16 1 511 2.2 1000
+f2 0 8193 7 0 8193 1
+f3 0 8 -2 1 2 3 5 7 8 9 10
+i1 0 3600 6000 4 .5 .015
+i2 0 3600 800 2 .6 .02
+i3 0 3600 1400 2 .7 .02
+i4 0 3600 1400 2 .8 .02
+i5 0 3600 3100 4 .6 .028
+i6 0 3600 3500 4 .7 .028
+i7 0 3600 2800 4 .8 .028
+i8 0 3600 2400 4 .9 .028
+
+e
+
+</CsScore>
+</CsoundSynthesizer>
diff --git a/activity/activity.info b/activity/activity.info
index ae9c649..d39ca23 100644
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -1,8 +1,14 @@
-[Activity]
-name = OurMusic
-bundle_id = org.laptop.OurMusic
-class = ourmusic.OurMusic
-icon = activity-ourmusic
-activity_version = 1
-host_version = 1
-show_launcher = yes
+[Activity]
+
+name = OurMusic
+
+bundle_id = org.laptop.OurMusic
+icon = activity-ourmusic
+
+activity_version = 2
+
+host_version = 1
+
+show_launcher = yes
+exec = sugar-activity ourmusic.OurMusic
+license = CC-by-SA 3.0
diff --git a/csndsugui.py b/csndsugui.py
index 47edcc5..d7c72f5 100644
--- a/csndsugui.py
+++ b/csndsugui.py
@@ -1,784 +1,797 @@
-# sugar-aware GUI classes
-# with boxes, sliders, spinbuttons, buttons, etc
-#
-# (c) Victor Lazzarini, 2006-08
-#
-# This library is free software; you can redistribute it
-# and/or modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# csndsugui 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with csndsugui; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-# 02111-1307 USA
-#
-# As a special exception, if other files instantiate templates or
-# use macros or inline functions from this file, this file does not
-# by itself cause the resulting executable or library to be covered
-# by the GNU Lesser General Public License. This exception does not
-# however invalidate any other reasons why the library or executable
-# file might be covered by the GNU Lesser General Public License.
-#
-#
-# version 0.1.3 06/08/08
-
-import pygtk
-pygtk.require('2.0')
-from sugar.activity import activity
-import gtk, gobject
-import sys
-import csnd
-import math
-import locale
-import os
-import sugar.logger
-import time
-
-class BasicGUI:
- """Basic GUI with boxes, sliders, spins, buttons etc
- using pygtk/sugar, from which GUI classes
- can be derived for Csound use."""
-
- def set_channel(self,name, val):
- """basic bus channel setting method,
- should be overriden for full-functionality."""
- self.logger.debug("channel:%s, value:%.1f" % (name,val))
-
- def set_filechannel(self,chan,name):
- """basic filename channel setting method
- should be overriden for full-functionality."""
- self.logger.debug("channel:%s, filename:%s" % (chan,name))
-
- def set_message(self, mess):
- """basic message setting method
- should be overriden for full-functionality."""
- self.logger.debug(mess)
-
- def get_slider_value(self,name):
- """returns the slider value
- name: slider name (which should also be the attached bus channel name"""
- for i in self.sliders:
- if i[1] == name:
- return i[2]
- return 0
-
- def get_button_value(self,name):
- """returns the button value (0 or 1)
- name: button name (which should also be the attached bus channel name)"""
- for i in self.buttons:
- if i[1] == name:
- return i[2]
- return 0
-
- def get_slider(self,name):
- """returns the slider widget instance
- name: slider name"""
- for i in self.sliders:
- if i[1] == name:
- return i[0]
- return 0
-
- def get_button(self,name):
- """returns the button widget instance
- name: button name"""
- for i in self.sliders:
- if i[1] == name:
- return i[0]
- return 0
-
- def set_focus(self):
- """ called whenever the focus changes """
- self.logger.debug(self.focus)
-
- def focus_out(self, widget, event):
- if(self.focus):
- self.focus = False
- self.set_focus()
-
- def focus_in(self, widget, event):
- if(not self.focus):
- self.focus = True
- self.set_focus()
-
- def focus_back(self, widget, event):
- self.window.disconnect(self.fback)
- self.focus_connect()
-
- def buttcallback(self, widget, data=None):
- for i in self.buttons:
- if i[0] == widget:
- if i[2]:
- i[2] = 0
- i[0].modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0x8000,0x8000,0x8000, 2))
- i[0].modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0x8000,0x8000,0x8000, 2))
- else:
- i[2] = 1
- i[0].modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0xFFFF,0,0, 1))
- i[0].modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF,0,0, 2))
- self.set_channel(i[1], i[2])
-
- def button_setvalue(self, widget, value):
- if not value:
- widget.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0x0FFF,0,0x00FF, 2))
- widget.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF,0,0xFFFF, 2))
- else:
- widget.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0xFFFF,0,0, 1))
- widget.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF,0,0, 2))
-
- def mbuttcallback(self, widget, data=None):
- for i in self.mbuttons:
- if i[0] == widget:
- self.set_message(i[2])
-
- def slidcallback(self,adj,widget):
- for i in self.sliders:
- if i[0] == widget:
- i[2] = adj.value
- if i[4]:
- self.set_channel(i[1],i[2])
- i[3].set_text("%f" % i[2])
- pass
- else:
- value = i[5]*pow(i[6]/i[5], i[2]/i[6])
- self.set_channel(i[1], value)
- i[3].set_text("%.3f" % value)
- pass
-
- def spincallback(self,adj,widget):
- for i in self.spins:
- if i[0] == widget:
- i[2] = adj.value
- self.set_channel(i[1],i[2])
-
- def filecallback(self,widget):
- name = self.curfile[0].get_filename()
- self.set_filechannel(self.curfile[2], name)
- for i in self.buttons:
- if i[0] == self.curfile[1]:
- i[2] = name
- self.filenames.update({self.curfile[2] : name})
- self.curfile[0].destroy()
- self.fback = self.window.connect('focus_out_event', self.focus_back)
-
- def destroy_chooser(self,widget):
- self.curfile[0].destroy()
-
- def fbuttcallback(self, widget, data=None):
- self.focus_disconnect()
- for i in self.buttons:
- if i[0] == widget:
- chooser = gtk.FileSelection(i[1])
- self.curfile = (chooser, i[0], i[1])
- chooser.set_filename(self.data_path)
- chooser.ok_button.connect("clicked", self.filecallback)
- chooser.cancel_button.connect("clicked", self.destroy_chooser)
- chooser.show()
-
- def cbbutton(self,box,callback,title=""):
- """Creates a callbackbutton
- box: parent box
- callback: click callback
- title: if given, the button name
- returns the widget instance"""
- self.cbbutts = self.cbbutts + 1
- butt = gtk.Button(title)
- butt.child.set_use_markup(True)
- box.pack_start(butt, False, False, 2)
- self.cbbuttons.append([butt,title,0])
- butt.connect("clicked", callback)
- butt.show()
- return butt
-
- def button(self,box, title="",label=""):
- """Creates a button (on/off)
- box: parent box
- title: if given, the button name,
- which will also be the bus channel
- name. Otherwise a default name is
- given, BN, where N is button number
- in order of creation.
- label: if given, an alternative button name,
- which will be displayed instead of title
- returns the widget instance"""
- self.butts = self.butts + 1
- if title == "":
- title = "B%d" % self.butts
- if label == "": name = title
- else: name = label
- butt = gtk.Button(" %s " % name)
- butt.child.set_use_markup(True)
- butt.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0x8000,0x8000,0x8000, 2))
- box.pack_start(butt, False, False, 1)
- self.buttons.append([butt,title,0])
- butt.connect("clicked", self.buttcallback)
- butt.show()
- return butt
-
- def mbutton(self,box,mess,title=""):
- """Creates a mbutton (for sending a message)
- box: parent box
- title: if given, the button name, otherwise a default name is
- given, BN, where N is button number
- in order of creation.
- mess: message to be sent when button is clicked
- returns the widget instance"""
- self.mbutts = self.mbutts + 1
- if title == "":
- title = "B%d" % self.mbutts
- butt = gtk.Button(title)
- butt.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0x0FFF,0,0x00FF, 1))
- butt.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF,0xFFFF,0x0000, 2))
- box.pack_start(butt, False, False, 5)
- self.mbuttons.append([butt,title,mess])
- butt.connect("clicked", self.mbuttcallback)
- butt.show()
- return butt
-
- def box(self,vert=True, parent=None, padding=3):
- """creates a box
- vert: True, creates a vertical box; horiz.
- otherwise
- parent: parent box, None if this is a toplevel box
- padding: box padding
- returns the widget instance"""
- if vert:
- box = gtk.VBox()
- else:
- box = gtk.HBox()
- if parent:
- parent.pack_start(box, False, False, padding)
- else:
- self.outbox.pack_start(box, False, False, padding)
- self.boxes.append(box)
- box.show()
- return box
-
- def filechooser(self,box,title,label=""):
- """Creates a filechooser button
- title: button name, also file bus channel name
- box: parent box
- label: if given, alternative name, for display purposes only
- otherwise button will display its title."""
- if label == "": name = title
- else: name = label
- butt = gtk.Button(name)
- box.pack_start(butt, False, False, 5)
- self.buttons.append([butt,title,"0"])
- butt.connect("clicked", self.fbuttcallback)
- self.set_filechannel(title,"0")
- self.filenames.update({title:"0"})
- butt.show()
- return butt
-
- def slider(self,init, start, end, x, y, box, title="",vert=True,linear=True,dwid=100,label=""):
- """Creates a slider
- init: initial value
- start, end: start and end of slider range
- x, y: x and y sizes of slider
- box: parent box
- title: if given, the slider name,
- which will also be the bus channel
- name. Otherwise a default name is
- given, SN, where N is slider number
- in order of creation.
- vert: vertical slider (True), else horiz.
- linear: linear response (True), else exponential (zero or negative
- ranges are not allowed)
- dwid: display width in pixels
- label: if given, the alternative slider name, for display only
- returns the widget instance"""
- self.slids = self.slids + 1
- if title == "":
- title = "S%d" % self.slids
- a = end - start
- if vert:
- step = a/y
- adj = gtk.Adjustment(init,start,end,step,step,0)
- slider = gtk.VScale(adj)
- slider.set_inverted(True)
- else:
- step = a/x
- adj = gtk.Adjustment(init,start,end,step,step,0)
- slider = gtk.HScale(adj)
- slider.set_draw_value(False)
- if step < 1.0:
- slider.set_digits(3)
- elif step < 10:
- slider.set_digits(2)
- elif step < 100:
- slider.set_digits(1)
- else:
- slider.set_digits(0)
- entry = gtk.Entry(5)
- if vert: entry.set_size_request(dwid,50)
- else: entry.set_size_request(dwid,50)
- entry.set_editable(False)
- if not linear:
- if (init <= 0) or (start <= 0) or (end <= 0):
- linear = True
- if not linear:
- pos = end*math.log(1,end/start)
- slider.set_range(pos, end)
- pos = end*math.log(init/start,end/start)
- slider.set_value(pos)
- if label == "": name = title
- else: name = label
- entry.set_text("%f" % init)
- label = gtk.Label(name)
- slider.set_size_request(x,y)
- box.pack_start(slider, False, False, 5)
- box.pack_start(entry, False, False, 2)
- box.pack_start(label, False, False, 2)
- self.sliders.append([slider,title,init,entry,linear,start,end])
- adj.connect("value_changed", self.slidcallback, slider)
- slider.show()
- entry.show()
- label.show()
- self.set_channel(title, init)
- return slider
-
- def numdisplay(self,box,title="",init=0.0,label=""):
- self.ndispwids = self.ndispwids + 1
- entry = gtk.Entry()
- if label == "": name = title
- else: name = label
- entry.set_text("%f" % init)
- label = gtk.Label(name)
- box.pack_start(entry, False, False, 2)
- box.pack_start(label, False, False, 2)
- self.ndisps.append([entry,title,init])
- entry.show()
- label.show()
- self.set_channel(title,init)
- return entry
-
- def setnumdisp(self,title,val):
- for i in self.ndisps:
- if i[1] == title:
- i[2] = val
- i[0].set_text("%f" % val)
- self.set_channel(title, val)
-
- def spin(self,init, start, end, step, page, box, accel=0,title="",label=""):
- """Creates a spin button
- init: initial value
- start, end: start and end of slider range
- step, page: small and large step sizes
- box: parent box
- accel: acceleration or 'climb rate' (0.0-1.0)
- title: if given, the spin button name,
- which will also be the bus channel
- name. Otherwise a default name is
- given, SPN, where N is spin number
- in order of creation.
- label: if given, the alternative name for the widget, for display only.
- returns the widget instance"""
- self.spinbs = self.spinbs + 1
- if title == "":
- title = "SP%d" % self.spinbs
- adj = gtk.Adjustment(init,start,end,step,page,0)
- spin = gtk.SpinButton(adj,accel)
- spin.set_alignment(.5)
- if label == "": name = title
- else: name = label
- label = gtk.Label(name)
- label.set_use_markup(True)
- box.pack_start(spin, False, False, 3)
- box.pack_start(label, False, False, 0)
- self.spins.append([spin,title,init])
- adj.connect("value_changed", self.spincallback, spin)
- spin.show()
- label.show()
- self.set_channel(title, init)
- return spin
-
- def text(self, name, box=None,colour=(0,0,0)):
- """Creates a static text label
- name: text label
- box: parent box, None if text is to be placed toplevel
- colour: RGB values in a tuple (R,G,B)
- returns the widget instance"""
- label = gtk.Label(name)
- label.set_use_markup(True)
- label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(colour[0],colour[1],colour[2], 0))
- if box:
- box.pack_start(label, False, False, 3)
- else:
- self.outbox.pack_start(label, False, False, 3)
- label.show()
- return label
-
- def framebox(self, name, vert=True, parent=None, colour=(0,0,0), padding=5):
- """Creates a frame box
- name: text label
- vert: vertical (True) box, else horiz.
- parent: parent box, if None, this is a toplevel box
- colour: RGB values in a tuple (R,G,B)
- padding: padding space
- returns the box widget instance"""
- frame = gtk.Frame(name)
- frame.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(colour[0],colour[1],colour[2], 0))
- frame.get_label_widget().modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(colour[0],colour[1],colour[2], 0))
- frame.get_label_widget().set_use_markup(True)
- if parent:
- parent.pack_start(frame, False, False, padding)
- else:
- self.outbox.pack_start(frame, False, False, padding)
- if vert:
- box = gtk.VBox()
- else:
- box = gtk.HBox()
- frame.add(box)
- frame.show()
- box.show()
- return box
-
- def vsliderbank(self,items,init, start, end, x, y, box):
- """Creates a vertical slider bank
- items: number of sliders
- init: initial value
- start, end: start and end of slider range
- x, y: x and y sizes of slider
- box: parent box"""
- slid = self.slids
- for i in range(slid, slid+items):
- cbox = self.box(parent=box)
- self.slider(init,start,end,x,y,cbox)
-
- def hsliderbank(self,items,init, start, end, x, y, box):
- """Creates a horizontal slider bank
- items: number of sliders
- init: initial value
- start, end: start and end of slider range
- x, y: x and y sizes of slider
- box: parent box"""
- slid = self.slids
- for i in range(slid, slid+items):
- cbox = self.box(False,box)
- self.slider(init,start,end,x,y,cbox,"",False)
-
- def buttonbank(self,items, box):
- """Creates a button bank
- items: number of sliders
- box: parent box."""
- start = self.butts
- for i in range(start, start+items):
- self.button(box)
-
- def delete_event(self, widget, event, data=None):
- return False
-
- def get_toolbox(self):
- """Returns the Activity toolbox"""
- return self.toolbox
-
- def channels_reinit(self):
- """ resets channel to current widget values"""
- for j in self.buttons:
- if(j[1] != "pause"):
- if(j[1] != "play"):
- if(j[1] != "reset"):
- self.set_channel(j[1],j[2])
- for j in self.sliders:
- if j[4]:
- self.set_channel(j[1],j[2])
- pass
- else:
- value = j[5]*pow(j[6]/j[5], j[2]/j[6])
- self.set_channel(j[1], value)
- for j in self.spins:
- self.set_channel(j[1],j[2])
-
- def widgets_reset(self):
- """ resets widget to channel values"""
- for j in self.buttons:
- self.button_setvalue(j[0], j[2])
- self.set_channel(j[1],j[2])
- for j in self.sliders:
- j[0].set_value(j[2])
- j[0].emit("value_changed")
- for j in self.spins:
- j[0].set_value(j[2])
- j[0].emit("value_changed")
-
- def channels_save(self):
- """ Saves a list with channel names and current values.
- Returns a list of tuples (channel_name, channel_value)"""
- chan_list = []
- for i in self.channel_widgets:
- for j in i:
- if(j[1] != "pause"):
- if(j[1] != "play"):
- if(j[1] != "reset"):
- chan_list.append((j[1],j[2]));
- return chan_list
-
- def channels_load(self, chan_list):
- """ Loads a list with channel names and values into the
- current channel list """
- for i in self.channnel_widgets:
- for j in i:
- cnt = 0
- while(j[1] == chan_list[cnt][0]):
- j[1] = chann_list[cnt][0]
- j[2] = chan_list[cnt][1]
- cnt = cnt+1
- self.widgets_reset()
-
- def set_channel_metadata(self):
- """ Saves channel data as metadata. Can be called in
- write_file() to save channel/widget data """
- mdata = self.channels_save()
- for i in mdata:
- self.window.metadata['channel-'+i[0]] = str(i[1])
-
- def get_channel_metadata(self):
- """ Retrieves channel data from metadata. Can be called after
- widgets have been created to retrieve channel data and
- reset widgets """
- for i in self.channel_widgets:
- for j in i:
- mdata = self.window.metadata.get('channel-'+j[1],'0')
- if mdata is None: continue
- else:
- try: j[2] = float(mdata)
- except: j[2] = mdata
- self.widgets_reset()
-
-
- def nofocus(self):
- pass
-
- def focus_connect(self):
- if not self.connected:
- self.focus = True
- self.in_id = self.window.connect('focus_in_event', self.focus_in)
- self.out_id = self.window.connect('focus_out_event', self.focus_out)
- self.connected = True
-
- def focus_disconnect(self):
- if self.connected:
- self.window.disconnect(self.in_id)
- self.window.disconnect(self.out_id)
- self.connected = False
-
- def __init__(self,act,colour=(-1,-1,-1),vert=True,toolbox=None):
- """Constructor
- act: activity object
- colour: bg colour RGB tuple (R,G, B)
- vert: True for vertical topmost arrangement, horiz. otherwise
- toolbox: activity toolbox object, if None (default) a
- standard toolbox will be supplied"""
- self.sliders = []
- self.slids = 0
- self.spins = []
- self.spinbs = 0
- self.buttons = []
- self.butts = 0
- self.cbbuttons = []
- self.cbbutts = 0
- self.mbuttons = []
- self.mbutts = 0
- self.boxes = []
- self.ndisps = []
- self.ndispwids = 0
- self.connected = False
- self.channel_widgets = [self.sliders, self.spins, self.buttons]
- self.filenames = dict()
- self.window = act
- if toolbox == None:
- self.toolbox = activity.ActivityToolbox(self.window)
- else: self.toolbox = toolbox
- self.window.set_toolbox(self.toolbox)
- self.toolbox.show()
- if colour[0] >= 0:
- self.window.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(colour[0],colour[1],colour[2], 0))
- if vert: self.outbox = gtk.VBox()
- else: self.outbox = gtk.HBox()
- self.window.set_canvas(self.outbox)
- self.data_path = os.path.join(act.get_activity_root(),"data/")
- self.outbox.show()
- self.logger = sugar.logger.logging.getLogger('csndsugui')
-
-
-class CsoundGUI(BasicGUI):
- """A class inheriting from BasicGUI containing a Csound instance and a performance
- thread instance."""
-
- def set_channel(self,name,val):
- """overrides the base method.
- sets the bus channel value, called by the widget callbacks
- channel names 'play', 'pause' and
- 'reset' are reserved for these respective uses"""
- if not self.ready:
- if name == "play":
- self.play()
- elif name == "pause":
- self.pause()
- elif name == "reset":
- self.reset()
- self.csound.SetChannel(name,val)
- else:
- BasicGUI.set_channel(self,name,val)
-
- def set_filechannel(self,chan,name):
- """overrides the base method, setting the channel string"""
- if not self.ready:
- self.csound.SetChannel(chan,name)
- else:
- BasicGUI.set_filechannel(self,chan,name)
-
- def set_message(self, mess):
- """overrides the base method, sends a score message"""
- self.perf.InputMessage(mess)
-
- def set_focus(self):
- """overrides the base class method, resetting/recompiling Csound"""
- if self.focus:
- self.compile()
- self.channels_reinit()
- if self.replay and not self.on:
- self.play()
- self.logger.debug("focus_off and playing")
- else:
- self.replay = self.on
- self.logger.debug("focus_out and stopping")
- self.reset()
- return 1
-
- def play(self):
- """Starts a performance. """
- if not self.on:
- if self.paused: return
- self.on = True
- self.perf.Play()
- else:
- self.on = False
- self.perf.Pause()
-
- def pause(self):
- """Pauses a performance. """
- if self.on:
- self.on = False
- self.paused = True
- self.perf.Pause()
- elif self.paused:
- self.on = True
- self.paused = False
- self.perf.Play()
-
- def csd(self, name):
- """Sets the source CSD and compiles it.
- name: CSD filename
- returns zero if successful"""
- path = activity.get_bundle_path()
- if self.ready:
- res = self.csound.Compile("%s/%s" % (path,name))
- if not res:
- self.ready = False
- self.focus_connect()
- self.path = path
- self.name = name
- return res
-
- def recompile(self):
- """Recompiles the set CSD.
- returns zero if successful"""
- if not self.ready and self.name != "0":
- self.perf.Stop()
- self.perf.Join()
- self.on = False
- self.paused = False
- self.perf = csnd.CsoundPerformanceThread(self.csound)
- if self.arglist != None:
- res = self.csound.Compile(self.arglist.argc(),self.arglist.argv())
- else:
- res = self.csound.Compile("%s/%s" % (self.path,self.name))
- if(res): self.ready = True
- return res
-
- def compile(self,name=None,args=[]):
- """Compiles Csound code.
- name: CSD filename if given
- args: list of arguments (as strings)
- returns 0 if successful , non-zero if not."""
- if self.ready:
- if args != []:
- self.arglist = csnd.CsoundArgVList()
- self.path = activity.get_bundle_path()
- if name != None: self.name = name
- elif self.name == "0": return -1
- if self.arglist != None:
- if name != None:
- self.arglist.Append("csound")
- self.arglist.Append("%s/%s" % (self.path,self.name))
- for i in args:
- self.arglist.Append(i)
- res = self.csound.Compile(self.arglist.argc(),self.arglist.argv())
- else: res = self.csound.Compile("%s/%s" % (self.path,self.name))
- if not res:
- self.ready = False
- self.focus_connect()
- else:
- self.arglist = None
- return res
-
- def reset(self):
- """Resets Csound, ready for a new CSD"""
- if not self.ready:
- self.perf.Stop()
- self.perf.Join()
- self.on = False
- self.paused = False
- self.perf = csnd.CsoundPerformanceThread(self.csound)
- self.ready = True
-
- def close(self, event):
- self.reset()
- sys.exit(0)
-
- def tcallback(self,cbdata):
- if self.stopcb: return False
- if self.on and self.sync:
- self.tcb(cbdata)
- return True
-
- def set_timer(self,time,cb,cbdata,sync=True):
- """Sets a timer callback, called at time intervals.
- Sync=True makes it start/stop with Csound performance"""
- if(self.stopcb == True):
- self.sync = sync
- self.tcb = cb
- self.stopcb = False
- gobject.timeout_add(time,self.tcallback,cbdata)
-
- def stop_timer(self):
- """Stops the timer"""
- self.stopcb = True
-
- def score_time(self):
- """Returns the current score time"""
- return self.csound.GetScoreTime()
-
- def __init__(self,act,colour=(-1,-1,-1),vert=True):
- """constructor
- act: activity object
- colour: bg colour RGB tuple (R,G, B)
- vert: True for vertical topmost arrangement, horiz. otherwise."""
- locale.setlocale(locale.LC_NUMERIC, 'C')
- self.csound = csnd.Csound()
- self.perf = csnd.CsoundPerformanceThread(self.csound)
- BasicGUI.__init__(self,act,colour,vert)
- self.ready = True
- self.on = False
- self.paused = False
- self.name = "0"
- self.arglist = None
- self.replay = False
- self.stopcb = True
+# sugar-aware GUI classes
+# with boxes, sliders, spinbuttons, buttons, etc
+#
+# (c) Victor Lazzarini, 2006-08
+#
+# This library is free software; you can redistribute it
+# and/or modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# csndsugui 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with csndsugui; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA
+#
+# As a special exception, if other files instantiate templates or
+# use macros or inline functions from this file, this file does not
+# by itself cause the resulting executable or library to be covered
+# by the GNU Lesser General Public License. This exception does not
+# however invalidate any other reasons why the library or executable
+# file might be covered by the GNU Lesser General Public License.
+#
+#
+# version 0.1.3 06/08/08
+
+import pygtk
+pygtk.require('2.0')
+from sugar.activity import activity
+import gtk, gobject
+import sys
+import csnd
+import math
+import locale
+import os
+import sugar.logger
+import time
+
+class BasicGUI:
+ """Basic GUI with boxes, sliders, spins, buttons etc
+ using pygtk/sugar, from which GUI classes
+ can be derived for Csound use."""
+
+ def scale_font(self, widget):
+ font = widget.get_pango_context().get_font_description()
+ font_size = font.get_size()
+ width = gtk.gdk.screen_width()
+ mult = width * .0008
+ if os.path.exists("/etc/fedora-release") and open("/etc/fedora-release").read().find("Strawberry")!= -1:
+ mult = width * .0013
+ font.set_size(int(font_size * mult))
+ widget.modify_font(font)
+
+ def set_channel(self,name, val):
+ """basic bus channel setting method,
+ should be overriden for full-functionality."""
+ self.logger.debug("channel:%s, value:%.1f" % (name,val))
+
+ def set_filechannel(self,chan,name):
+ """basic filename channel setting method
+ should be overriden for full-functionality."""
+ self.logger.debug("channel:%s, filename:%s" % (chan,name))
+
+ def set_message(self, mess):
+ """basic message setting method
+ should be overriden for full-functionality."""
+ self.logger.debug(mess)
+
+ def get_slider_value(self,name):
+ """returns the slider value
+ name: slider name (which should also be the attached bus channel name"""
+ for i in self.sliders:
+ if i[1] == name:
+ return i[2]
+ return 0
+
+ def get_button_value(self,name):
+ """returns the button value (0 or 1)
+ name: button name (which should also be the attached bus channel name)"""
+ for i in self.buttons:
+ if i[1] == name:
+ return i[2]
+ return 0
+
+ def get_slider(self,name):
+ """returns the slider widget instance
+ name: slider name"""
+ for i in self.sliders:
+ if i[1] == name:
+ return i[0]
+ return 0
+
+ def get_button(self,name):
+ """returns the button widget instance
+ name: button name"""
+ for i in self.sliders:
+ if i[1] == name:
+ return i[0]
+ return 0
+
+ def set_focus(self):
+ """ called whenever the focus changes """
+ self.logger.debug(self.focus)
+
+ def focus_out(self, widget, event):
+ if(self.focus):
+ self.focus = False
+ self.set_focus()
+
+ def focus_in(self, widget, event):
+ if(not self.focus):
+ self.focus = True
+ self.set_focus()
+
+ def focus_back(self, widget, event):
+ self.window.disconnect(self.fback)
+ self.focus_connect()
+
+ def buttcallback(self, widget, data=None):
+ for i in self.buttons:
+ if i[0] == widget:
+ if i[2]:
+ i[2] = 0
+ i[0].modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0x8000,0x8000,0x8000, 2))
+ i[0].modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0x8000,0x8000,0x8000, 2))
+ else:
+ i[2] = 1
+ i[0].modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0xFFFF,0,0, 1))
+ i[0].modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF,0,0, 2))
+ self.set_channel(i[1], i[2])
+
+ def button_setvalue(self, widget, value):
+ if not value:
+ widget.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0x0FFF,0,0x00FF, 2))
+ widget.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF,0,0xFFFF, 2))
+ else:
+ widget.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0xFFFF,0,0, 1))
+ widget.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF,0,0, 2))
+
+ def mbuttcallback(self, widget, data=None):
+ for i in self.mbuttons:
+ if i[0] == widget:
+ self.set_message(i[2])
+
+ def slidcallback(self,adj,widget):
+ for i in self.sliders:
+ if i[0] == widget:
+ i[2] = adj.value
+ if i[4]:
+ self.set_channel(i[1],i[2])
+ i[3].set_text("%f" % i[2])
+ pass
+ else:
+ value = i[5]*pow(i[6]/i[5], i[2]/i[6])
+ self.set_channel(i[1], value)
+ i[3].set_text("%.3f" % value)
+ pass
+
+ def spincallback(self,adj,widget):
+ for i in self.spins:
+ if i[0] == widget:
+ i[2] = adj.value
+ self.set_channel(i[1],i[2])
+
+ def filecallback(self,widget):
+ name = self.curfile[0].get_filename()
+ self.set_filechannel(self.curfile[2], name)
+ for i in self.buttons:
+ if i[0] == self.curfile[1]:
+ i[2] = name
+ self.filenames.update({self.curfile[2] : name})
+ self.curfile[0].destroy()
+ self.fback = self.window.connect('focus_out_event', self.focus_back)
+
+ def destroy_chooser(self,widget):
+ self.curfile[0].destroy()
+
+ def fbuttcallback(self, widget, data=None):
+ self.focus_disconnect()
+ for i in self.buttons:
+ if i[0] == widget:
+ chooser = gtk.FileSelection(i[1])
+ self.curfile = (chooser, i[0], i[1])
+ chooser.set_filename(self.data_path)
+ chooser.ok_button.connect("clicked", self.filecallback)
+ chooser.cancel_button.connect("clicked", self.destroy_chooser)
+ chooser.show()
+
+ def cbbutton(self,box,callback,title=""):
+ """Creates a callbackbutton
+ box: parent box
+ callback: click callback
+ title: if given, the button name
+ returns the widget instance"""
+ self.cbbutts = self.cbbutts + 1
+ butt = gtk.Button(title)
+ self.scale_font(butt.child)
+ box.pack_start(butt, False, False, 2)
+ self.cbbuttons.append([butt,title,0])
+ butt.connect("clicked", callback)
+ butt.show()
+ return butt
+
+ def button(self,box, title="",label=""):
+ """Creates a button (on/off)
+ box: parent box
+ title: if given, the button name,
+ which will also be the bus channel
+ name. Otherwise a default name is
+ given, BN, where N is button number
+ in order of creation.
+ label: if given, an alternative button name,
+ which will be displayed instead of title
+ returns the widget instance"""
+ self.butts = self.butts + 1
+ if title == "":
+ title = "B%d" % self.butts
+ if label == "": name = title
+ else: name = label
+ butt = gtk.Button(" %s " % name)
+ self.scale_font(butt.child)
+ butt.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0x8000,0x8000,0x8000, 2))
+ box.pack_start(butt, False, False, 1)
+ self.buttons.append([butt,title,0])
+ butt.connect("clicked", self.buttcallback)
+ butt.show()
+ return butt
+
+ def mbutton(self,box,mess,title=""):
+ """Creates a mbutton (for sending a message)
+ box: parent box
+ title: if given, the button name, otherwise a default name is
+ given, BN, where N is button number
+ in order of creation.
+ mess: message to be sent when button is clicked
+ returns the widget instance"""
+ self.mbutts = self.mbutts + 1
+ if title == "":
+ title = "B%d" % self.mbutts
+ butt = gtk.Button(title)
+ butt.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0x0FFF,0,0x00FF, 1))
+ butt.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF,0xFFFF,0x0000, 2))
+ box.pack_start(butt, False, False, 5)
+ self.mbuttons.append([butt,title,mess])
+ butt.connect("clicked", self.mbuttcallback)
+ butt.show()
+ return butt
+
+ def box(self,vert=True, parent=None, padding=3):
+ """creates a box
+ vert: True, creates a vertical box; horiz.
+ otherwise
+ parent: parent box, None if this is a toplevel box
+ padding: box padding
+ returns the widget instance"""
+ if vert:
+ box = gtk.VBox()
+ else:
+ box = gtk.HBox()
+ if parent:
+ parent.pack_start(box, False, False, padding)
+ else:
+ self.outbox.pack_start(box, False, False, padding)
+ self.boxes.append(box)
+ box.show()
+ return box
+
+ def filechooser(self,box,title,label=""):
+ """Creates a filechooser button
+ title: button name, also file bus channel name
+ box: parent box
+ label: if given, alternative name, for display purposes only
+ otherwise button will display its title."""
+ if label == "": name = title
+ else: name = label
+ butt = gtk.Button(name)
+ box.pack_start(butt, False, False, 5)
+ self.buttons.append([butt,title,"0"])
+ butt.connect("clicked", self.fbuttcallback)
+ self.set_filechannel(title,"0")
+ self.filenames.update({title:"0"})
+ butt.show()
+ return butt
+
+ def slider(self,init, start, end, x, y, box, title="",vert=True,linear=True,dwid=100,label=""):
+ """Creates a slider
+ init: initial value
+ start, end: start and end of slider range
+ x, y: x and y sizes of slider
+ box: parent box
+ title: if given, the slider name,
+ which will also be the bus channel
+ name. Otherwise a default name is
+ given, SN, where N is slider number
+ in order of creation.
+ vert: vertical slider (True), else horiz.
+ linear: linear response (True), else exponential (zero or negative
+ ranges are not allowed)
+ dwid: display width in pixels
+ label: if given, the alternative slider name, for display only
+ returns the widget instance"""
+ self.slids = self.slids + 1
+ if title == "":
+ title = "S%d" % self.slids
+ a = end - start
+ if vert:
+ step = a/y
+ adj = gtk.Adjustment(init,start,end,step,step,0)
+ slider = gtk.VScale(adj)
+ slider.set_inverted(True)
+ else:
+ step = a/x
+ adj = gtk.Adjustment(init,start,end,step,step,0)
+ slider = gtk.HScale(adj)
+ slider.set_draw_value(False)
+ if step < 1.0:
+ slider.set_digits(3)
+ elif step < 10:
+ slider.set_digits(2)
+ elif step < 100:
+ slider.set_digits(1)
+ else:
+ slider.set_digits(0)
+ entry = gtk.Entry(5)
+ if vert: entry.set_size_request(dwid,50)
+ else: entry.set_size_request(dwid,50)
+ entry.set_editable(False)
+ if not linear:
+ if (init <= 0) or (start <= 0) or (end <= 0):
+ linear = True
+ if not linear:
+ pos = end*math.log(1,end/start)
+ slider.set_range(pos, end)
+ pos = end*math.log(init/start,end/start)
+ slider.set_value(pos)
+ if label == "": name = title
+ else: name = label
+ entry.set_text("%f" % init)
+ label = gtk.Label(name)
+ slider.set_size_request(x,y)
+ box.pack_start(slider, False, False, 5)
+ box.pack_start(entry, False, False, 2)
+ box.pack_start(label, False, False, 2)
+ self.sliders.append([slider,title,init,entry,linear,start,end])
+ adj.connect("value_changed", self.slidcallback, slider)
+ slider.show()
+ entry.show()
+ label.show()
+ self.set_channel(title, init)
+ return slider
+
+ def numdisplay(self,box,title="",init=0.0,label=""):
+ self.ndispwids = self.ndispwids + 1
+ entry = gtk.Entry()
+ if label == "": name = title
+ else: name = label
+ entry.set_text("%f" % init)
+ label = gtk.Label(name)
+ box.pack_start(entry, False, False, 2)
+ box.pack_start(label, False, False, 2)
+ self.ndisps.append([entry,title,init])
+ entry.show()
+ label.show()
+ self.set_channel(title,init)
+ return entry
+
+ def setnumdisp(self,title,val):
+ for i in self.ndisps:
+ if i[1] == title:
+ i[2] = val
+ i[0].set_text("%f" % val)
+ self.set_channel(title, val)
+
+ def spin(self,init, start, end, step, page, box, accel=0,title="",label=""):
+ """Creates a spin button
+ init: initial value
+ start, end: start and end of slider range
+ step, page: small and large step sizes
+ box: parent box
+ accel: acceleration or 'climb rate' (0.0-1.0)
+ title: if given, the spin button name,
+ which will also be the bus channel
+ name. Otherwise a default name is
+ given, SPN, where N is spin number
+ in order of creation.
+ label: if given, the alternative name for the widget, for display only.
+ returns the widget instance"""
+ self.spinbs = self.spinbs + 1
+ if title == "":
+ title = "SP%d" % self.spinbs
+ adj = gtk.Adjustment(init,start,end,step,page,0)
+ spin = gtk.SpinButton(adj,accel)
+ self.scale_font(spin)
+ spin.set_alignment(.5)
+ if label == "": name = title
+ else: name = label
+ label = gtk.Label(name)
+ self.scale_font(label)
+ box.pack_start(spin, False, False, 3)
+ box.pack_start(label, False, False, 0)
+ self.spins.append([spin,title,init])
+ adj.connect("value_changed", self.spincallback, spin)
+ spin.show()
+ label.show()
+ self.set_channel(title, init)
+ return spin
+
+ def text(self, name, box=None,colour=(0,0,0)):
+ """Creates a static text label
+ name: text label
+ box: parent box, None if text is to be placed toplevel
+ colour: RGB values in a tuple (R,G,B)
+ returns the widget instance"""
+ label = gtk.Label(name)
+ self.scale_font(label)
+ label.set_use_markup(True)
+ label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(colour[0],colour[1],colour[2], 0))
+ if box:
+ box.pack_start(label, False, False, 3)
+ else:
+ self.outbox.pack_start(label, False, False, 3)
+ label.show()
+ return label
+
+ def framebox(self, name, vert=True, parent=None, colour=(0,0,0), padding=5):
+ """Creates a frame box
+ name: text label
+ vert: vertical (True) box, else horiz.
+ parent: parent box, if None, this is a toplevel box
+ colour: RGB values in a tuple (R,G,B)
+ padding: padding space
+ returns the box widget instance"""
+ frame = gtk.Frame(name)
+ self.scale_font(frame.get_label_widget())
+ frame.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(colour[0],colour[1],colour[2], 0))
+ frame.get_label_widget().modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(colour[0],colour[1],colour[2], 0))
+ frame.get_label_widget().set_use_markup(True)
+ if parent:
+ parent.pack_start(frame, False, False, padding)
+ else:
+ self.outbox.pack_start(frame, False, False, padding)
+ if vert:
+ box = gtk.VBox()
+ else:
+ box = gtk.HBox()
+ frame.add(box)
+ frame.show()
+ box.show()
+ return box
+
+ def vsliderbank(self,items,init, start, end, x, y, box):
+ """Creates a vertical slider bank
+ items: number of sliders
+ init: initial value
+ start, end: start and end of slider range
+ x, y: x and y sizes of slider
+ box: parent box"""
+ slid = self.slids
+ for i in range(slid, slid+items):
+ cbox = self.box(parent=box)
+ self.slider(init,start,end,x,y,cbox)
+
+ def hsliderbank(self,items,init, start, end, x, y, box):
+ """Creates a horizontal slider bank
+ items: number of sliders
+ init: initial value
+ start, end: start and end of slider range
+ x, y: x and y sizes of slider
+ box: parent box"""
+ slid = self.slids
+ for i in range(slid, slid+items):
+ cbox = self.box(False,box)
+ self.slider(init,start,end,x,y,cbox,"",False)
+
+ def buttonbank(self,items, box):
+ """Creates a button bank
+ items: number of sliders
+ box: parent box."""
+ start = self.butts
+ for i in range(start, start+items):
+ self.button(box)
+
+ def delete_event(self, widget, event, data=None):
+ return False
+
+ def get_toolbox(self):
+ """Returns the Activity toolbox"""
+ return self.toolbox
+
+ def channels_reinit(self):
+ """ resets channel to current widget values"""
+ for j in self.buttons:
+ if(j[1] != "pause"):
+ if(j[1] != "play"):
+ if(j[1] != "reset"):
+ self.set_channel(j[1],j[2])
+ for j in self.sliders:
+ if j[4]:
+ self.set_channel(j[1],j[2])
+ pass
+ else:
+ value = j[5]*pow(j[6]/j[5], j[2]/j[6])
+ self.set_channel(j[1], value)
+ for j in self.spins:
+ self.set_channel(j[1],j[2])
+
+ def widgets_reset(self):
+ """ resets widget to channel values"""
+ for j in self.buttons:
+ self.button_setvalue(j[0], j[2])
+ self.set_channel(j[1],j[2])
+ for j in self.sliders:
+ j[0].set_value(j[2])
+ j[0].emit("value_changed")
+ for j in self.spins:
+ j[0].set_value(j[2])
+ j[0].emit("value_changed")
+
+ def channels_save(self):
+ """ Saves a list with channel names and current values.
+ Returns a list of tuples (channel_name, channel_value)"""
+ chan_list = []
+ for i in self.channel_widgets:
+ for j in i:
+ if(j[1] != "pause"):
+ if(j[1] != "play"):
+ if(j[1] != "reset"):
+ chan_list.append((j[1],j[2]));
+ return chan_list
+
+ def channels_load(self, chan_list):
+ """ Loads a list with channel names and values into the
+ current channel list """
+ for i in self.channnel_widgets:
+ for j in i:
+ cnt = 0
+ while(j[1] == chan_list[cnt][0]):
+ j[1] = chann_list[cnt][0]
+ j[2] = chan_list[cnt][1]
+ cnt = cnt+1
+ self.widgets_reset()
+
+ def set_channel_metadata(self):
+ """ Saves channel data as metadata. Can be called in
+ write_file() to save channel/widget data """
+ mdata = self.channels_save()
+ for i in mdata:
+ self.window.metadata['channel-'+i[0]] = str(i[1])
+
+ def get_channel_metadata(self):
+ """ Retrieves channel data from metadata. Can be called after
+ widgets have been created to retrieve channel data and
+ reset widgets """
+ for i in self.channel_widgets:
+ for j in i:
+ mdata = self.window.metadata.get('channel-'+j[1],'0')
+ if mdata is None: continue
+ else:
+ try: j[2] = float(mdata)
+ except: j[2] = mdata
+ self.widgets_reset()
+
+
+ def nofocus(self):
+ pass
+
+ def focus_connect(self):
+ if not self.connected:
+ self.focus = True
+ self.in_id = self.window.connect('focus_in_event', self.focus_in)
+ self.out_id = self.window.connect('focus_out_event', self.focus_out)
+ self.connected = True
+
+ def focus_disconnect(self):
+ if self.connected:
+ self.window.disconnect(self.in_id)
+ self.window.disconnect(self.out_id)
+ self.connected = False
+
+ def __init__(self,act,colour=(-1,-1,-1),vert=True,toolbox=None):
+ """Constructor
+ act: activity object
+ colour: bg colour RGB tuple (R,G, B)
+ vert: True for vertical topmost arrangement, horiz. otherwise
+ toolbox: activity toolbox object, if None (default) a
+ standard toolbox will be supplied"""
+ self.sliders = []
+ self.slids = 0
+ self.spins = []
+ self.spinbs = 0
+ self.buttons = []
+ self.butts = 0
+ self.cbbuttons = []
+ self.cbbutts = 0
+ self.mbuttons = []
+ self.mbutts = 0
+ self.boxes = []
+ self.ndisps = []
+ self.ndispwids = 0
+ self.connected = False
+ self.channel_widgets = [self.sliders, self.spins, self.buttons]
+ self.filenames = dict()
+ self.window = act
+ if toolbox == None:
+ self.toolbox = activity.ActivityToolbox(self.window)
+ else: self.toolbox = toolbox
+ self.window.set_toolbox(self.toolbox)
+ self.toolbox.show()
+ if colour[0] >= 0:
+ self.window.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(colour[0],colour[1],colour[2], 0))
+ if vert: self.outbox = gtk.VBox()
+ else: self.outbox = gtk.HBox()
+ self.window.set_canvas(self.outbox)
+ self.data_path = os.path.join(act.get_activity_root(),"data/")
+ self.outbox.show()
+ self.logger = sugar.logger.logging.getLogger('csndsugui')
+
+
+class CsoundGUI(BasicGUI):
+ """A class inheriting from BasicGUI containing a Csound instance and a performance
+ thread instance."""
+
+ def set_channel(self,name,val):
+ """overrides the base method.
+ sets the bus channel value, called by the widget callbacks
+ channel names 'play', 'pause' and
+ 'reset' are reserved for these respective uses"""
+ if not self.ready:
+ if name == "play":
+ self.play()
+ elif name == "pause":
+ self.pause()
+ elif name == "reset":
+ self.reset()
+ self.csound.SetChannel(name,val)
+ else:
+ BasicGUI.set_channel(self,name,val)
+
+ def set_filechannel(self,chan,name):
+ """overrides the base method, setting the channel string"""
+ if not self.ready:
+ self.csound.SetChannel(chan,name)
+ else:
+ BasicGUI.set_filechannel(self,chan,name)
+
+ def set_message(self, mess):
+ """overrides the base method, sends a score message"""
+ self.perf.InputMessage(mess)
+
+ def set_focus(self):
+ """overrides the base class method, resetting/recompiling Csound"""
+ if self.focus:
+ self.compile()
+ self.channels_reinit()
+ if self.replay and not self.on:
+ self.play()
+ self.logger.debug("focus_off and playing")
+ else:
+ self.replay = self.on
+ self.logger.debug("focus_out and stopping")
+ self.reset()
+ return 1
+
+ def play(self):
+ """Starts a performance. """
+ if not self.on:
+ if self.paused: return
+ self.on = True
+ self.perf.Play()
+ else:
+ self.on = False
+ self.perf.Pause()
+
+ def pause(self):
+ """Pauses a performance. """
+ if self.on:
+ self.on = False
+ self.paused = True
+ self.perf.Pause()
+ elif self.paused:
+ self.on = True
+ self.paused = False
+ self.perf.Play()
+
+ def csd(self, name):
+ """Sets the source CSD and compiles it.
+ name: CSD filename
+ returns zero if successful"""
+ path = activity.get_bundle_path()
+ if self.ready:
+ res = self.csound.Compile("%s/%s" % (path,name))
+ if not res:
+ self.ready = False
+ self.focus_connect()
+ self.path = path
+ self.name = name
+ return res
+
+ def recompile(self):
+ """Recompiles the set CSD.
+ returns zero if successful"""
+ if not self.ready and self.name != "0":
+ self.perf.Stop()
+ self.perf.Join()
+ self.on = False
+ self.paused = False
+ self.perf = csnd.CsoundPerformanceThread(self.csound)
+ if self.arglist != None:
+ res = self.csound.Compile(self.arglist.argc(),self.arglist.argv())
+ else:
+ res = self.csound.Compile("%s/%s" % (self.path,self.name))
+ if(res): self.ready = True
+ return res
+
+ def compile(self,name=None,args=[]):
+ """Compiles Csound code.
+ name: CSD filename if given
+ args: list of arguments (as strings)
+ returns 0 if successful , non-zero if not."""
+ if self.ready:
+ if args != []:
+ self.arglist = csnd.CsoundArgVList()
+ self.path = activity.get_bundle_path()
+ if name != None: self.name = name
+ elif self.name == "0": return -1
+ if self.arglist != None:
+ if name != None:
+ self.arglist.Append("csound")
+ self.arglist.Append("%s/%s" % (self.path,self.name))
+ for i in args:
+ self.arglist.Append(i)
+ res = self.csound.Compile(self.arglist.argc(),self.arglist.argv())
+ else: res = self.csound.Compile("%s/%s" % (self.path,self.name))
+ if not res:
+ self.ready = False
+ self.focus_connect()
+ else:
+ self.arglist = None
+ return res
+
+ def reset(self):
+ """Resets Csound, ready for a new CSD"""
+ if not self.ready:
+ self.perf.Stop()
+ self.perf.Join()
+ self.on = False
+ self.paused = False
+ self.perf = csnd.CsoundPerformanceThread(self.csound)
+ self.ready = True
+
+ def close(self, event):
+ self.reset()
+ sys.exit(0)
+
+ def tcallback(self,cbdata):
+ if self.stopcb: return False
+ if self.on and self.sync:
+ self.tcb(cbdata)
+ return True
+
+ def set_timer(self,time,cb,cbdata,sync=True):
+ """Sets a timer callback, called at time intervals.
+ Sync=True makes it start/stop with Csound performance"""
+ if(self.stopcb == True):
+ self.sync = sync
+ self.tcb = cb
+ self.stopcb = False
+ gobject.timeout_add(time,self.tcallback,cbdata)
+
+ def stop_timer(self):
+ """Stops the timer"""
+ self.stopcb = True
+
+ def score_time(self):
+ """Returns the current score time"""
+ return self.csound.GetScoreTime()
+
+ def __init__(self,act,colour=(-1,-1,-1),vert=True):
+ """constructor
+ act: activity object
+ colour: bg colour RGB tuple (R,G, B)
+ vert: True for vertical topmost arrangement, horiz. otherwise."""
+ locale.setlocale(locale.LC_NUMERIC, 'C')
+ self.csound = csnd.Csound()
+ self.perf = csnd.CsoundPerformanceThread(self.csound)
+ BasicGUI.__init__(self,act,colour,vert)
+ self.ready = True
+ self.on = False
+ self.paused = False
+ self.name = "0"
+ self.arglist = None
+ self.replay = False
+ self.stopcb = True
diff --git a/ourmusic.py b/ourmusic.py
index abac214..2fdaf1d 100644
--- a/ourmusic.py
+++ b/ourmusic.py
@@ -1,276 +1,289 @@
-# OUR MUSIC - Sonic Environments for Children (2009)
-# Art Hunkins (www.arthunkins.com)
-#
-# This library is free software; you can redistribute it
-# and/or modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# OurMusic 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with OurMusic; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-# 02111-1307 USA
-#
-# version 1 06/16/09
-#
-# Notes:
-#
-# Of the four Versions of OurMusic, 1 and 2 are similar, as are 3
-# and 4. The only significant difference is the control mechanism;
-# 2 and 4 are played solely on ASCII keyboard(s) (multiple keyboards;
-# the native and additional USB keyboards can be played simultaneously).
-# Collaborative performance is encouraged. Versions 3/4 are somewhat
-# more involved than 1/2; their textures are richer and they offer
-# enhanced options.
-#
-# Versions 1 and 3 require a USB MIDI controller with 8+ knobs
-# and/or sliders. The 8 knobs/sliders must have *contiguous* controller
-# #'s, or all be continuous controller 7 on channels 1-8(11).
-#
-# Important: The controller must be attached AFTER boot, and BEFORE
-# the version is selected. It is assumed that the controller is a USB
-# device. The inexpensive Korg nanoKontrol is one appropriate
-# controller choice; it can nicely handle either 8- or 9-slider
-# renditions (but not those requiring more than 9 sliders). Choose
-# Scene 4 on the Korg, and Channel "0" in the performance window.
-#
-# If you get audio glitching, open Sugar's Control Panel, and turn off
-# Extreme power management (under Power) or Wireless radio (under
-# Network).
-
-import csndsugui
-from sugar.activity import activity
-import gtk
-import os
-
-class OurMusic(activity.Activity):
-
- def __init__(self, handle):
-
- activity.Activity.__init__(self, handle)
-
- red = (0xDDDD, 0, 0)
- brown = (0x6600, 0, 0)
- green = (0, 0x5500, 0)
-
- win = csndsugui.CsoundGUI(self)
- if os.path.exists("/sys/power/olpc-pm"):
- tall = 1
- else:
- width = gtk.gdk.screen_width()
- height = gtk.gdk.screen_height()
- if (height * 1.35) > width:
- tall = 1
- else:
- tall = 0
- settings = gtk.settings_get_default()
- size = (width * .0125)
- settings.set_property("gtk-font-name", " %s " % size)
-
- win.text("<big><b><big><u>OUR MUSIC</u> - Sonic Environments for Children \
-(2009)</big></b>\n\
- Art Hunkins (www.arthunkins.com)</big>")
-
- if tall:
- win.text("A Creation Story:\n\
-<i> On the sixth day I was created.\n\
- God said I was very good\n\
- On the sixth day We were created - my friends and I.\n\
- God said We were very good.\n\
- On the sixth day my Family was created - my loved ones and I,\n\
- together with all the other creatures.\n\
- God said my Family was very good.\n\
- God saw that everything He made was very good.\n\
- He was so pleased He decided to take a holiday,\n\
- and joined us in play.</i>", None, colour=green)
- else:
- win.text("<small><b>A Creation Story:</b> <i>On the sixth day I was created. \
-God said I was very good.\n\
- On the sixth day We were created - my friends and I. \
-God said We were very good.\n\
- On the sixth day my Family was created - my loved ones and I, \
-together with all the other creatures. \
-God said my Family was very good.\n\
- God saw that everything He made was very good. \
-He was so pleased He decided to take a holiday, \
-and joined us in play.</i></small>", None, colour=green)
-
- win.text("\
-<b>1 - MyMusicMIDI</b> Simple; MIDI controller with 8-9 knobs/sliders\n\
-<b>2 - MyMusicASCII</b> Simple; 1 or more ASCII keyboards\n\
-<b>3 - OurMusicMIDI</b> \
-Advanced; MIDI controller with 8-11 knobs/sliders, or 8-10 \
-knobs/sliders and 10 MIDI notes\n\
-<b>4 - OurMusicASCII</b> Advanced; 1 or more ASCII keyboards\n\
-<i><b>MIDI</b>: plug in controller AFTER boot &amp; BEFORE selecting; \
-zero controls before start. \
-<b>ASCII</b>: press keys AFTER start.</i>", None, brown)
- nbox = win.box(False)
- win.text("", nbox)
- but1 = win.cbbutton(nbox, self.version1, " 1 MyMusicMIDI ")
- but1.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
- but1.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
- but2 = win.cbbutton(nbox, self.version2, " 2 MyMusicASCII")
- but2.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
- but2.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
- but3 = win.cbbutton(nbox, self.version3, "3 OurMusicMIDI ")
- but3.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
- but3.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
- but4 = win.cbbutton(nbox, self.version4, "4 OurMusicASCII")
- but4.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
- but4.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
- bbox = win.box(False)
- self.bb = bbox
- self.w = win
- self.r = red
- self.g = green
- self.br = brown
- self.ver = 0
-
- def onKeyPress(self, widget, event):
- if (self.p):
- if (self.ver == 2) or (self.ver == 4):
- self.w.set_channel("ascii", event.keyval)
- if event.hardware_keycode == 82:
- self.w.set_channel("ascii", 45)
-
- def playcsd(self, widget):
- if self.p == False:
- self.p = True
- self.w.play()
- self.but.set_label("STOP !")
- self.but.child.set_use_markup(True)
- self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0xFFFF, 0, 0))
- self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF, 0, 0))
- if (self.ver == 2) or (self.ver == 4):
- self.connect("key-press-event", self.onKeyPress)
- else:
- self.p = False
- self.w.recompile()
- self.w.channels_reinit()
- self.but.set_label("START !")
- self.but.child.set_use_markup(True)
- self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
- self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
-
- def version1(self, widget):
- if self.ver != 0:
- self.box1.destroy()
- self.box2.destroy()
- self.w.reset()
- self.w.csd("MyMusicMIDI.csd")
- if not self.w.csd("MyMusicMIDI.csd"):
- self.ver = 1
- self.box1 = self.w.box(True, self.bb)
- self.w.text("", self.box1)
- self.box2 = self.w.box(True, self.bb)
- self.f = self.w.framebox(" <b>1 - MyMusicMIDI</b> ", False, self.box2, self.r)
- self.b1 = self.w.box(True, self.f)
- self.b2 = self.w.box(True, self.f)
- self.b3 = self.w.box(True, self.f)
- self.w.spin(0, 0, 16, 1, 1, self.b1, 0, "chan", "Channel # [0=CC7,\n \
-channels 1-8(9)]")
- self.w.spin(20, 0, 120, 1, 1, self.b1, 0, "ctrl", "1st Controller #")
- self.w.button(self.b2, "pan", "Pan Control ?")
- self.w.text("", self.b2)
- self.w.spin(7, 0, 127, 1, 1, self.b2, 0, "panctrl", "Pan Controller #")
- self.p = False
- self.w.text("\n<i>Select options first </i>", self.b3, self.g)
- self.but = self.w.cbbutton(self.b3, self.playcsd, "START !")
- self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
- self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
-
- def version2(self, widget):
- if self.ver != 0:
- self.box1.destroy()
- self.box2.destroy()
- self.ver = 2
- self.box1 = self.w.box(True, self.bb)
- self.w.text("\t\t\t ", self.box1)
- self.box2 = self.w.box(True, self.bb)
- self.f = self.w.framebox(" <b>2 - MyMusicASCII</b> ", False, self.box2, self.r)
- self.b1 = self.w.box(True, self.f)
- self.b2 = self.w.box(True, self.f)
- self.w.reset()
- self.w.csd("MyMusicASCII.csd")
- self.w.text(" <b>Active Keys:</b>\n1-10(0) fade secs\nQ-I \
-tones (8) on/off\n\
-[Z-/ pan position]\n- (minus) = all off\n", self.b1, self.br)
- self.w.button(self.b2, "pan", "Pan Control ?")
- self.p = False
- self.w.text("\n<i>Select option first </i>", self.b2, self.g)
- self.but = self.w.cbbutton(self.b2, self.playcsd, "START !")
- self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
- self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
-
- def version3(self, widget):
- if self.ver != 0:
- self.box1.destroy()
- self.box2.destroy()
- self.w.reset()
- self.w.csd("OurMusicMIDI.csd")
- if not self.w.csd("OurMusicMIDI.csd"):
- self.ver = 3
- self.box1 = self.w.box(True, self.bb)
- self.w.text("", self.box1)
- self.box2 = self.w.box(True, self.bb)
- self.f = self.w.framebox(" <b>3 - OurMusicMIDI</b> ", False, self.box2, self.r)
- self.b1 = self.w.box(True, self.f)
- self.b2 = self.w.box(True, self.f)
- self.b3 = self.w.box(True, self.f)
- self.b4 = self.w.box(True, self.f)
- self.b5 = self.w.box(True, self.f)
- self.b6 = self.w.box(True, self.f)
- self.w.spin(0, 0, 16, 1, 1, self.b1, 0, "chan", "Channel # [0=CC7,\n \
-channels 1-8(11)]")
- self.w.spin(20, 0, 120, 1, 1, self.b1, 0, "ctrl", "1st Controller #")
- self.w.spin(0, 0, 3, 1, 1, self.b2, 0, "harm", "Harmonics 0=normal\n\
-1=random 2=knob/\nslider 3=MIDI notes")
- self.w.spin(7, 0, 127, 1, 1, self.b3, 0, "harctrl", "Harm Control #")
- self.w.spin(60, 0, 118, 1, 1, self.b3, 0, "harmidi", "1st MIDI Note #\n\
-(for harmonics)")
- self.w.button(self.b4, "pan", "Pan Control ?")
- self.w.text("", self.b4)
- self.w.spin(7, 0, 127, 1, 1, self.b4, 0, "panctrl", "Pan Control #")
- self.w.spin(0, 0, 2, 1, 1, self.b5, 7, "depth", " Depth 0=none\n\
-1=random 2=cont")
- self.w.spin(7, 0, 127, 1, 1, self.b5, 0, "depctrl", "Depth Control #")
- self.p = False
- self.w.text("\n<i>Select options first </i>", self.b6, self.g)
- self.but = self.w.cbbutton(self.b6, self.playcsd, "START !")
- self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
- self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
-
- def version4(self, widget):
- if self.ver != 0:
- self.box1.destroy()
- self.box2.destroy()
- self.ver = 4
- self.box1 = self.w.box(True, self.bb)
- self.w.text("\t\t\t\t\t\t\t\t\t\t\t", self.box1)
- self.box2 = self.w.box(True, self.bb)
- self.f = self.w.framebox(" <b>4 - OurMusicASCII</b> ", False, self.box2,
-self.r)
- self.b1 = self.w.box(True, self.f)
- self.b2 = self.w.box(True, self.f)
- self.b3 = self.w.box(True, self.f)
- self.w.reset()
- self.w.csd("OurMusicASCII.csd")
- self.w.text(" <b>Active Keys:</b>\n1-10(0) fade secs\n\
-Q-I tones (8) on/off\n[A-; harmonics (10)]\n[Z-/ pan position]\n\
-[SHIFT 0(`)-9 depth]\n- (minus) = all off", self.b1, self.br)
- self.w.spin(0, 0, 2, 1, 1, self.b2, 0, "harm", "Harmonics 0=normal\n\
-1=random 2=control\n")
- self.w.button(self.b2, "pan", "Pan Control ?")
- self.w.spin(0, 0, 2, 1, 1, self.b3, 0, "depth", " Depth 0=none\n1\
-=random 2=control")
- self.p = False
- self.w.text("<i>Select options first </i>", self.b3, self.g)
- self.but = self.w.cbbutton(self.b3, self.playcsd, "START !")
- self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
- self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
+# OUR MUSIC - Sonic Environments for Children (2009)
+# Art Hunkins (www.arthunkins.com)
+#
+# OurMusic is licensed under the Creative Commons Attribution-Share
+# Alike 3.0 Unported License. To view a copy of this license, visit
+# http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to
+# Creative Commons, 171 Second Street, Suite 300, San Francisco,
+# California, 94105, USA.
+#
+# It 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.
+#
+# version 2 12/18/09 Additions:
+# optional scrollbars
+# auto default font sizing for XO and all versions of SoaS
+# ready for basic font size adjustment by user or deployment
+# works with SoaS Strawberry (Sugar 0.84) after installing csound-python
+#
+# Notes:
+#
+# Of the four Versions of OurMusic, 1 and 2 are similar, as are 3
+# and 4. The only significant difference is the control mechanism;
+# 2 and 4 are played solely on ASCII keyboard(s) (multiple keyboards;
+# the native and additional USB keyboards can be played simultaneously).
+# Collaborative performance is encouraged. Versions 3/4 are somewhat
+# more involved than 1/2; their textures are richer and they offer
+# enhanced options.
+#
+# Versions 1 and 3 require a USB MIDI controller with 8+ knobs
+# and/or sliders. The 8 knobs/sliders must have *contiguous* controller
+# #'s, or all be continuous controller 7 on channels 1-8(11). Please note
+# with respect to the latter arrangement: in MyMusicMIDI, pan (if actively
+# controlled) is on channel 9; in OurMusicMIDI, *harmonics* are assigned
+# channel 9; pan, channel 10; and depth, channel 11 (these assignments are
+# fixed). When "MIDI notes" is selected to control harmonics with this
+# option, the "harmonics channel" is thus actually #9.
+#
+# Important: The controller must be attached AFTER boot, and BEFORE
+# the version is selected. It is assumed that the controller is a USB
+# device. The inexpensive Korg nanoKontrol is one appropriate
+# controller choice; it can nicely handle either 8- or 9-slider
+# renditions (but not those requiring more than 9 sliders). Choose
+# Scene 4 on the Korg, and Channel "0" in the performance window.
+#
+# If you get audio glitching, open Sugar's Control Panel, and turn off
+# Extreme power management (under Power) or Wireless radio (under
+# Network). Stereo headphones (an inexpensive set will work fine) or
+# external amplifier/speaker system are highly recommended.
+
+import csndsugui
+from sugar.activity import activity
+import gtk
+import os
+
+class OurMusic(activity.Activity):
+
+ def __init__(self, handle):
+
+ activity.Activity.__init__(self, handle)
+
+ red = (0xDDDD, 0, 0)
+ brown = (0x6600, 0, 0)
+ green = (0, 0x5500, 0)
+
+ win = csndsugui.CsoundGUI(self)
+ width = gtk.gdk.screen_width()
+ height = gtk.gdk.screen_height()
+ if os.path.exists("/etc/olpc-release") or os.path.exists("/sys/power/olpc-pm"):
+ tall = 1
+ adjust = 78
+ else:
+ adjust = 57
+ if (height * 1.35) > width:
+ tall = 1
+ else:
+ tall = 0
+ screen = win.box()
+ screen.set_size_request(width, height - adjust)
+ scrolled = gtk.ScrolledWindow()
+ scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ screen.pack_start(scrolled)
+ all = gtk.VBox()
+ all.show()
+ scrolled.add_with_viewport(all)
+ scrolled.show()
+
+ win.text("<big><b><big><u>OUR MUSIC</u> - Sonic Environments for Children \
+(2009)</big></b>\n\
+ Art Hunkins (www.arthunkins.com)</big>", all)
+
+ if tall:
+ win.text("A Creation Story:\n\
+<i> On the sixth day I was created.\n\
+ God said I was very good.\n\
+ On the sixth day We were created - my friends and I.\n\
+ God said We were very good.\n\
+ On the sixth day my Family was created - my loved ones and I,\n\
+ together with all the other creatures.\n\
+ God said my Family was very good.\n\
+ God saw that everything He made was very good.\n\
+ He was so pleased He decided to take a holiday,\n\
+ and joined us in play.</i>", all, green)
+ else:
+ win.text("<small><b>A Creation Story:</b> <i>On the sixth day I was created. \
+God said I was very good.\n\
+ On the sixth day We were created - my friends and I. \
+God said We were very good.\n\
+ On the sixth day my Family was created - my loved ones and I, \
+together with all the other creatures. \
+God said my Family was very good.\n\
+ God saw that everything He made was very good. \
+He was so pleased He decided to take a holiday, \
+and joined us in play.</i></small>", all, green)
+
+ win.text("\
+<b>1 - MyMusicMIDI</b> Simple; MIDI controller with 8-9 knobs/sliders\n\
+<b>2 - MyMusicASCII</b> Simple; 1 or more ASCII keyboards\n\
+<b>3 - OurMusicMIDI</b> \
+Advanced; MIDI controller with 8-11 knobs/sliders, or 8-10 \
+knobs/sliders and 10 MIDI notes\n\
+<b>4 - OurMusicASCII</b> Advanced; 1 or more ASCII keyboards\n\
+<i><b>MIDI</b>: plug in controller AFTER boot &amp; BEFORE selecting; \
+zero controls before start. \
+<b>ASCII</b>: press keys AFTER start.</i>", all, brown)
+ nbox = win.box(False, all)
+ win.text("", nbox)
+ but1 = win.cbbutton(nbox, self.version1, " 1 MyMusicMIDI ")
+ but1.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
+ but1.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
+ but2 = win.cbbutton(nbox, self.version2, " 2 MyMusicASCII")
+ but2.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
+ but2.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
+ but3 = win.cbbutton(nbox, self.version3, "3 OurMusicMIDI ")
+ but3.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
+ but3.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
+ but4 = win.cbbutton(nbox, self.version4, "4 OurMusicASCII")
+ but4.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
+ but4.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
+ bbox = win.box(False, all)
+ self.bb = bbox
+ self.w = win
+ self.r = red
+ self.g = green
+ self.br = brown
+ self.ver = 0
+
+ def onKeyPress(self, widget, event):
+ if (self.p):
+ if (self.ver == 2) or (self.ver == 4):
+ self.w.set_channel("ascii", event.keyval)
+ if event.hardware_keycode == 82:
+ self.w.set_channel("ascii", 45)
+
+ def playcsd(self, widget):
+ if self.p == False:
+ self.p = True
+ self.w.play()
+ self.but.child.set_label("STOP !")
+ self.but.child.set_use_markup(True)
+ self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0xFFFF, 0, 0))
+ self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF, 0, 0))
+ if (self.ver == 2) or (self.ver == 4):
+ self.connect("key-press-event", self.onKeyPress)
+ else:
+ self.p = False
+ self.w.recompile()
+ self.w.channels_reinit()
+ self.but.child.set_label("START !")
+ self.but.child.set_use_markup(True)
+ self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
+ self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
+
+ def version1(self, widget):
+ if self.ver != 0:
+ self.box1.destroy()
+ self.box2.destroy()
+ self.w.reset()
+ self.w.csd("MyMusicMIDI.csd")
+ if not self.w.csd("MyMusicMIDI.csd"):
+ self.ver = 1
+ self.box1 = self.w.box(True, self.bb)
+ self.w.text("", self.box1)
+ self.box2 = self.w.box(True, self.bb)
+ self.f = self.w.framebox(" <b>1 - MyMusicMIDI</b> ", False, self.box2, self.r)
+ self.b1 = self.w.box(True, self.f)
+ self.b2 = self.w.box(True, self.f)
+ self.b3 = self.w.box(True, self.f)
+ self.w.spin(0, 0, 16, 1, 1, self.b1, 0, "chan", "Channel # [0=CC7,\n \
+channels 1-8(9)]")
+ self.w.spin(20, 0, 120, 1, 1, self.b1, 0, "ctrl", "1st Controller #")
+ self.w.button(self.b2, "pan", "Pan Control ?")
+ self.w.text("", self.b2)
+ self.w.spin(7, 0, 127, 1, 1, self.b2, 0, "panctrl", "Pan Controller #")
+ self.p = False
+ self.w.text("\n<i>Select options first </i>", self.b3, self.g)
+ self.but = self.w.cbbutton(self.b3, self.playcsd, "START !")
+ self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
+ self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
+
+ def version2(self, widget):
+ if self.ver != 0:
+ self.box1.destroy()
+ self.box2.destroy()
+ self.ver = 2
+ self.box1 = self.w.box(True, self.bb)
+ self.w.text("\t\t\t ", self.box1)
+ self.box2 = self.w.box(True, self.bb)
+ self.f = self.w.framebox(" <b>2 - MyMusicASCII</b> ", False, self.box2, self.r)
+ self.b1 = self.w.box(True, self.f)
+ self.b2 = self.w.box(True, self.f)
+ self.w.reset()
+ self.w.csd("MyMusicASCII.csd")
+ self.w.text(" <b>Active Keys:</b>\n1-10(0) fade secs\nQ-I \
+tones (8) on/off\n\
+[Z-/ pan position]\n- (minus) = all off\n", self.b1, self.br)
+ self.w.button(self.b2, "pan", "Pan Control ?")
+ self.p = False
+ self.w.text("\n<i>Select option first </i>", self.b2, self.g)
+ self.but = self.w.cbbutton(self.b2, self.playcsd, "START !")
+ self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
+ self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
+
+ def version3(self, widget):
+ if self.ver != 0:
+ self.box1.destroy()
+ self.box2.destroy()
+ self.w.reset()
+ self.w.csd("OurMusicMIDI.csd")
+ if not self.w.csd("OurMusicMIDI.csd"):
+ self.ver = 3
+ self.box1 = self.w.box(True, self.bb)
+ self.w.text("", self.box1)
+ self.box2 = self.w.box(True, self.bb)
+ self.f = self.w.framebox(" <b>3 - OurMusicMIDI</b> ", False, self.box2, self.r)
+ self.b1 = self.w.box(True, self.f)
+ self.b2 = self.w.box(True, self.f)
+ self.b3 = self.w.box(True, self.f)
+ self.b4 = self.w.box(True, self.f)
+ self.b5 = self.w.box(True, self.f)
+ self.b6 = self.w.box(True, self.f)
+ self.w.spin(0, 0, 16, 1, 1, self.b1, 0, "chan", "Channel # [0=CC7,\n \
+channels 1-8(11)]")
+ self.w.spin(20, 0, 120, 1, 1, self.b1, 0, "ctrl", "1st Controller #")
+ self.w.spin(0, 0, 3, 1, 1, self.b2, 0, "harm", "Harmonics 0=normal\n\
+1=random 2=knob/\nslider 3=MIDI notes")
+ self.w.spin(7, 0, 127, 1, 1, self.b3, 0, "harctrl", "Harm Control #")
+ self.w.spin(60, 0, 118, 1, 1, self.b3, 0, "harmidi", "1st MIDI Note #\n\
+(for harmonics)")
+ self.w.button(self.b4, "pan", "Pan Control ?")
+ self.w.text("", self.b4)
+ self.w.spin(7, 0, 127, 1, 1, self.b4, 0, "panctrl", "Pan Control #")
+ self.w.spin(0, 0, 2, 1, 1, self.b5, 7, "depth", " Depth 0=none\n\
+1=random 2=cont")
+ self.w.spin(7, 0, 127, 1, 1, self.b5, 0, "depctrl", "Depth Control #")
+ self.p = False
+ self.w.text("\n<i>Select options first </i>", self.b6, self.g)
+ self.but = self.w.cbbutton(self.b6, self.playcsd, "START !")
+ self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
+ self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
+
+ def version4(self, widget):
+ if self.ver != 0:
+ self.box1.destroy()
+ self.box2.destroy()
+ self.ver = 4
+ self.box1 = self.w.box(True, self.bb)
+ self.w.text("\t\t\t\t\t\t\t\t\t\t\t", self.box1)
+ self.box2 = self.w.box(True, self.bb)
+ self.f = self.w.framebox(" <b>4 - OurMusicASCII</b> ", False, self.box2,
+self.r)
+ self.b1 = self.w.box(True, self.f)
+ self.b2 = self.w.box(True, self.f)
+ self.b3 = self.w.box(True, self.f)
+ self.w.reset()
+ self.w.csd("OurMusicASCII.csd")
+ self.w.text(" <b>Active Keys:</b>\n1-10(0) fade secs\n\
+Q-I tones (8) on/off\n[A-; harmonics (10)]\n[Z-/ pan position]\n\
+[SHIFT 0(`)-9 depth]\n- (minus) = all off", self.b1, self.br)
+ self.w.spin(0, 0, 2, 1, 1, self.b2, 0, "harm", "Harmonics 0=normal\n\
+1=random 2=control\n")
+ self.w.button(self.b2, "pan", "Pan Control ?")
+ self.w.spin(0, 0, 2, 1, 1, self.b3, 0, "depth", " Depth 0=none\n1\
+=random 2=control")
+ self.p = False
+ self.w.text("<i>Select options first </i>", self.b3, self.g)
+ self.but = self.w.cbbutton(self.b3, self.playcsd, "START !")
+ self.but.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
+ self.but.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0, 0x7700, 0))
diff --git a/setup.py b/setup.py
index a45d07f..77fda74 100644
--- a/setup.py
+++ b/setup.py
@@ -1,3 +1,4 @@
-#!/usr/bin/env python
-from sugar.activity import bundlebuilder
-bundlebuilder.start("OurMusic")
+#!/usr/bin/env python
+from sugar.activity import bundlebuilder
+if __name__ == "__main__":
+ bundlebuilder.start()