Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSoaS user <liveuser@localhost.localdomain>2010-06-07 02:07:28 (GMT)
committer SoaS user <liveuser@localhost.localdomain>2010-06-07 02:07:28 (GMT)
commit230f863f55c337c750a7a14f63b6f8242cc9e1df (patch)
treec411d5d8168dbc49be3c45a249eacd7be2bfb5f6
Initial commit
-rwxr-xr-xMANIFEST7
-rwxr-xr-xMoonMusic.csd77
-rwxr-xr-xSunMusic.csd71
-rwxr-xr-xactivity/activity-sunmoonmusic.svg17
-rwxr-xr-xactivity/activity.info14
-rwxr-xr-xcsndsugui.py813
-rwxr-xr-xsetup.py4
-rwxr-xr-xsunmoonmusic.py182
8 files changed, 1185 insertions, 0 deletions
diff --git a/MANIFEST b/MANIFEST
new file mode 100755
index 0000000..30e1cc2
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,7 @@
+setup.py
+SunMusic.csd
+MoonMusic.csd
+activity/activity.info
+activity/activity-sunmoonmusic.svg
+csndsugui.py
+sunmoonmusic.py
diff --git a/MoonMusic.csd b/MoonMusic.csd
new file mode 100755
index 0000000..b3c74ce
--- /dev/null
+++ b/MoonMusic.csd
@@ -0,0 +1,77 @@
+; SISTER MOON (2010) for realtime Csound5 - by Arthur B. Hunkins
+; requires MIDI device with 8-9 knobs/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
+
+ instr 1
+
+ichan chnget "Chan"
+ictrl chnget "Cont"
+ipan chnget "Pan"
+ipctrl chnget "PCont"
+kfreq rspline -.055, .055, 20, 30
+kfreq = 795 + kfreq
+kmod1 ctrl7 (ichan = 0? 1: ichan), (ichan = 0? 7: ictrl), 0, 6
+kmod1 port kmod1, .1
+kmod2 ctrl7 (ichan = 0? 2: ichan), (ichan = 0? 7: ictrl + 1), 0, 6
+kmod2 port kmod2, .1
+kmod3 ctrl7 (ichan = 0? 3: ichan), (ichan = 0? 7: ictrl + 2), 0, 6
+kmod3 port kmod3, .1
+kmod4 ctrl7 (ichan = 0? 4: ichan), (ichan = 0? 7: ictrl + 3), 0, 6
+kmod4 port kmod4, .1
+kmod5 ctrl7 (ichan = 0? 5: ichan), (ichan = 0? 7: ictrl + 4), 0, 6
+kmod5 port kmod5, .1
+kmod6 ctrl7 (ichan = 0? 6: ichan), (ichan = 0? 7: ictrl + 5), 0, 6
+kmod6 port kmod6, .1
+krand rspline -2, 2, .5, .8
+krand2 rspline -2, 2, .5, .8
+krand3 rspline -2, 2, .5, .8
+krand4 rspline -2, 2, .5, .8
+krand5 rspline -2, 2, .5, .8
+krand6 rspline -2, 2, .5, .8
+amod1 lfo kfreq * kmod1, (kfreq * .895) + krand
+amod2 lfo kfreq * kmod2, (kfreq * .74) + krand2
+amod3 lfo kfreq * kmod3, (kfreq * .595) + krand3
+amod4 lfo kfreq * kmod4, (kfreq * .45) + krand4
+amod5 lfo kfreq * kmod5, (kfreq * .295) + krand5
+amod6 lfo kfreq * kmod6, (kfreq * .14) + krand6
+kamp2 ctrl7 (ichan = 0? 7: ichan), (ichan = 0? 7: ictrl + 6), 0, 1
+kamp table kamp2 * 512, 1
+kamp = (kamp2 == 0? 0: kamp * 3000)
+kamp port kamp, .1
+kramp jspline -.12 * kamp, 6, 10
+aout oscil kamp + kramp + amod1 + amod2 + amod3 + amod4 + amod5 + amod6, kfreq, 2
+kvol2 ctrl7 (ichan = 0? 8: ichan), (ichan = 0? 7: ictrl + 7), 0, 1
+kvol table kvol2 * 512, 1
+kvol = (kvol2 == 0? 0: kvol)
+kvol port kvol, .1
+aout = aout * kvol
+ if ipan = 0 goto skip
+kpan ctrl7 (ichan = 0? 9: ichan), (ichan = 0? 7: ipctrl), 0, 1
+kpan port kpan, .5
+a1,a2,a3,a4 pan aout, kpan, 1, 3, 1
+ outs a1, a2
+ goto fin
+skip: outs aout, aout
+fin: endin
+
+</CsInstruments>
+<CsScore>
+
+f1 0 512 16 1 511 2.2 1000
+f2 0 16384 10 1
+f3 0 8193 7 0 8193 1
+i1 0 3600
+
+</CsScore>
+</CsoundSynthesizer>
diff --git a/SunMusic.csd b/SunMusic.csd
new file mode 100755
index 0000000..19b667d
--- /dev/null
+++ b/SunMusic.csd
@@ -0,0 +1,71 @@
+; BROTHER SUN (2010) for realtime Csound5 - by Arthur B. Hunkins
+; requires MIDI device with 8-9 knobs/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
+
+ instr 1
+
+ichan chnget "Chan"
+ictrl chnget "Cont"
+ipan chnget "Pan"
+ipctrl chnget "PCont"
+kmod1 ctrl7 (ichan = 0? 1: ichan), (ichan = 0? 7: ictrl), 0, 7
+kmod1 port kmod1, .1
+kmod2 ctrl7 (ichan = 0? 2: ichan), (ichan = 0? 7: ictrl + 1), 0, 10
+kmod2 port kmod2, .1
+kmod3 ctrl7 (ichan = 0? 3: ichan), (ichan = 0? 7: ictrl + 2), 0, 13
+kmod3 port kmod3, .1
+kmod4 ctrl7 (ichan = 0? 4: ichan), (ichan = 0? 7: ictrl + 3), 0, 16
+kmod4 port kmod4, .1
+kmod5 ctrl7 (ichan = 0? 5: ichan), (ichan = 0? 7: ictrl + 4), 0, 19
+kmod5 port kmod5, .1
+kmod6 ctrl7 (ichan = 0? 6: ichan), (ichan = 0? 7: ictrl + 5), 0, 22
+kmod6 port kmod6, .1
+kfreq ctrl7 (ichan = 0? 7: ichan), (ichan = 0? 7: ictrl + 6), 50, 55
+kfreq port kfreq, 1.5, 50
+krand rspline -.1, .1, .5, .8
+krand2 rspline -.1, .1, .5, .8
+krand3 rspline -.1, .1, .5, .8
+krand4 rspline -.1, .1, .5, .8
+krand5 rspline -.1, .1, .5, .8
+amod1 lfo kfreq * kmod1, kfreq * 2
+amod2 lfo kfreq * kmod2, (kfreq * 3) + krand
+amod3 lfo kfreq * kmod3, (kfreq * 5) + krand2
+amod4 lfo kfreq * kmod4, (kfreq * 7) + krand3
+amod5 lfo kfreq * kmod5, (kfreq * 9) + krand4
+amod6 lfo kfreq * kmod6, (kfreq * 11) + krand5
+kamp2 ctrl7 (ichan = 0? 8: ichan), (ichan = 0? 7: ictrl + 7), 0, 1
+kamp table kamp2 * 512, 1
+kamp = (kamp2 == 0? 0: kamp * 25000)
+kamp port kamp, .1
+kramp jspline -.15 * kamp, 1, 3.5
+aout oscil kamp + kramp, amod1 + amod2 + amod3 + amod4 + amod5 + amod6, 2
+ if ipan = 0 goto skip
+kpan ctrl7 (ichan = 0? 9: ichan), (ichan = 0? 7: ipctrl), 0, 1
+kpan port kpan, .5
+a1,a2,a3,a4 pan aout, kpan, 1, 3, 1
+ outs a1, a2
+ goto fin
+skip: outs aout, aout
+fin: endin
+
+</CsInstruments>
+<CsScore>
+
+f1 0 512 16 1 511 2.2 1000
+f2 0 16384 10 1
+f3 0 8193 7 0 8193 1
+i1 0 3600
+
+</CsScore>
+</CsoundSynthesizer>
diff --git a/activity/activity-sunmoonmusic.svg b/activity/activity-sunmoonmusic.svg
new file mode 100755
index 0000000..13ccc07
--- /dev/null
+++ b/activity/activity-sunmoonmusic.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?><!-- Created with Inkscape (http://www.inkscape.org/) --><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [
+ <!ENTITY stroke_color "#000000">
+ <!ENTITY fill_color "#ffffff">
+]><svg height="48" id="svg2" version="1.0" width="48" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
+ <defs id="defs11"/>
+ <path d="M 31.113503,30.780875 C 31.388312,28.375302 30.083851,27.617627 28.521512,27.464839 C 24.935045,27.16059 20.911664,26.320436 20.756461,28.310274 C 20.170841,31.014643 19.787187,32.763195 19.199743,37.196561 C 18.920316,39.066156 19.979265,44.500894 15.350148,44.877248 C 10.620914,45.262039 8.1070794,42.278579 9.4381704,39.412893 C 11.310919,35.486517 16.041752,37.986387 16.526199,36.518113 C 17.956322,32.057432 17.756617,26.924746 18.912738,22.372505 C 18.958079,22.193977 19.56686,22.013833 19.921211,21.970612 C 20.848965,21.772286 32.104253,22.585264 32.825062,22.99762 C 33.179412,22.954397 33.673593,23.329524 33.815273,23.449981 C 35.006109,24.46244 34.288873,28.717053 34.069724,29.61478 C 33.484102,32.319151 33.075558,34.055988 32.488112,38.489357 C 32.208685,40.358952 33.292528,45.805397 28.663411,46.181753 C 23.934175,46.566542 21.420341,43.583088 22.751431,40.717398 C 24.624183,36.791021 29.330122,39.279182 29.814569,37.810909 C 30.52963,35.580568 30.83869,33.186444 31.113503,30.780875 z" id="path4" style="fill:&fill_color;;stroke:&stroke_color;;stroke-width:1.29730475"/>
+ <path d="M 21.185485,11.48052 C 21.185485,15.692821 17.491645,19.107565 12.935064,19.107565 C 8.3784831,19.107565 4.6846441,15.692821 4.6846441,11.48052 C 4.6846441,7.26822 8.3784831,3.8534758 12.935064,3.8534758 C 17.491645,3.8534758 21.185485,7.26822 21.185485,11.48052 L 21.185485,11.48052 z" id="path2398" style="fill:&fill_color;;stroke:&stroke_color;;stroke-width:1.43422401;stroke-opacity:1"/>
+ <path d="M 1.1416508,11.368556 L 3.3258817,11.384692 L 3.1184034,11.373275" id="path2401" style="fill:none;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/>
+ <path d="M 4.2597402,3.8441558 L 5.9220779,5.2987013" id="path2403" style="fill:none;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/>
+ <path d="M 12.571429,0.58100334 C 12.571429,2.5358798 12.571429,2.5358798 12.571429,2.5358798" id="path2405" style="fill:none;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1.15930045px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/>
+ <path d="M 19.577594,4.941886 C 21.045782,3.4736983 21.045782,3.4736983 21.045782,3.4736983" id="path2407" style="fill:none;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1.09025395px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/>
+ <path d="M 19.830731,17.856705 C 21.312126,19.441997 21.312126,19.441997 21.312126,19.441997" id="path2411" style="fill:none;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1.18094206px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/>
+ <path d="M 12.779221,20.569056 C 12.779221,22.443932 12.779221,22.443932 12.779221,22.443932" id="path2413" style="fill:none;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1.09683442px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/>
+ <path d="M 5.9463699,17.949734 C 4.3393444,19.141175 4.3393444,19.141175 4.3393444,19.141175" id="path2415" style="fill:none;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1.15920818px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/>
+ <path d="M 22.440435,11.276162 C 24.832293,11.269292 24.832293,11.269292 24.832293,11.269292" id="path2394" style="fill:none;fill-rule:evenodd;stroke:&stroke_color;;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"/>
+ <path d="M 36.295717,14.480639 C 42.775943,13.994601 42.992481,9.597368 42.893637,13.678247 C 42.819815,16.726076 38.971813,19.785021 34.80458,19.170489 C 30.637349,18.555958 26.70832,14.12874 27.373078,9.6209099 C 28.037836,5.1130803 32.257758,2.6922802 36.374503,4.0964477 C 31.050227,6.1182866 31.229069,11.651146 36.295717,14.480639 z" id="path15" style="fill:&fill_color;;stroke:&stroke_color;;stroke-width:1.43422401;stroke-opacity:1"/>
+</svg> \ No newline at end of file
diff --git a/activity/activity.info b/activity/activity.info
new file mode 100755
index 0000000..c210faf
--- /dev/null
+++ b/activity/activity.info
@@ -0,0 +1,14 @@
+[Activity]
+
+name = SunMoonMusic
+
+bundle_id = org.laptop.SunMoonMusic
+icon = activity-sunmoonmusic
+
+activity_version = 1
+
+host_version = 1
+
+show_launcher = yes
+exec = sugar-activity sunmoonmusic.SunMoonMusic
+license = CC-by-SA 3.0
diff --git a/csndsugui.py b/csndsugui.py
new file mode 100755
index 0000000..c8a404d
--- /dev/null
+++ b/csndsugui.py
@@ -0,0 +1,813 @@
+# 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()
+
+# The FONT DISPLAY in this activity can be resized (smaller or larger)
+# by changing the value of "resize" below. "Resize" can be positive
+# or negative, and is not limited to integers. A value of 1 equals a
+# point in font size.
+ resize = 0
+
+ font_size = font.get_size() + (resize * 1024)
+ width = gtk.gdk.screen_width()
+ mult = width * .00076
+ if os.path.exists("/etc/olpc-release") or os.path.exists("/etc/power/olpc-pm"):
+ mult = width * .00082
+ elif os.path.exists("/etc/fedora-release"):
+ release = open("/etc/fedora-release").read()
+ if release.find("SoaS release 1 ") != -1:
+ mult = width * .00132
+ elif release.find("SoaS release 2 ") != -1:
+ mult = width * .00085
+ elif release.find("Fedora release ") != -1:
+ mult = width * .00119
+ 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/setup.py b/setup.py
new file mode 100755
index 0000000..77fda74
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,4 @@
+#!/usr/bin/env python
+from sugar.activity import bundlebuilder
+if __name__ == "__main__":
+ bundlebuilder.start()
diff --git a/sunmoonmusic.py b/sunmoonmusic.py
new file mode 100755
index 0000000..b8ccd7a
--- /dev/null
+++ b/sunmoonmusic.py
@@ -0,0 +1,182 @@
+# SUN-MOON MUSIC - Sonic Environments for Children (2009)
+# Art Hunkins (www.arthunkins.com)
+#
+# SunMoonMusic 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.
+#
+# Notes:
+#
+# Both "Brother Sun Music" and "Sister Moon Music" require a USB MIDI
+# controller with 8-9 knobs (the 9th controller is only used with the
+# Pan option). The 8 knobs/sliders must have *contiguous* controller
+# #'s, or all be continuous controller 7 on channels 1-8(9).
+#
+# The first 7 controllers in "Sister Moon" vary volume for the 7 tones
+# (or tone pairs), while #8 is a MASTER volume control. The same is true
+# for "Brother Sun" except that there are only 6 tones; controller 7
+# varies overall pitch slightly.
+#
+# Important: The MIDI 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. Choose Scene 4 on the Korg, and Channel "0" in the
+# performance window. Preset all controllers to zero prior to start;
+# then, when using Pan, change controller 9 to its opening position
+# following start.
+#
+# 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. The audio
+# level will sound higher for "Brother Sun" than for "Sister Moon."
+#
+# The font display of this activity can be resized in csndsugui.py,
+# using any text editor. Further instructions are found toward the
+# beginning of csndsugui.py.
+
+import csndsugui
+from sugar.activity import activity
+import gtk
+import os
+
+class SunMoonMusic(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"):
+ adjust = 78
+ else:
+ adjust = 57
+ 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><big><b><u>BROTHER SUN &amp; SISTER MOON MUSIC</u> -\n\
+ Sonic Environments for Children (2010)</b></big>\n\
+\t Art Hunkins (www.arthunkins.com)</big>", all)
+
+ win.text("from <u>The Canticle of the Sun</u> by Francis of Assisi:\n\
+<i>\tBe praised, my Lord, through all your creatures,\n\
+\t\tespecially through my lord Brother Sun, who brings the day;\n\
+\t\tand you give light through him. \
+And he is beautiful and radiant in all his splendor!\n\
+\t\tOf you, Most High, he bears the likeness.\n\
+\tBe praised, my Lord, through Sister Moon and the stars;\n\
+\t\tin the heavens you have made them, precious and beautiful.</i>", all, green)
+
+ win.text("\
+A MIDI controller with 8-9 knobs/sliders is required; \
+the ninth control is only used to vary pan position.\n\
+Plug in MIDI controller AFTER boot &amp; BEFORE selecting Sun/Moon; \
+zero all controls before start.\n\
+Move Pan into position AFTER start. \
+Channel '0' = Continuous Controller 7 on channels 1-8(9).", all, brown)
+ nbox = win.box(False, all)
+ win.text("", nbox)
+ but1 = win.cbbutton(nbox, self.version1, " BROTHER SUN Music ")
+ 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, " SISTER MOON Music ")
+ but2.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0x7700, 0))
+ but2.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 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))
+ 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.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>Brother Sun Music</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.w.reset()
+ self.w.csd("SunMusic.csd")
+ self.w.spin(0, 0, 16, 1, 1, self.b1, 0, "Chan", " Channel # ")
+ self.w.spin(20, 0, 120, 1, 1, self.b2, 0, "Cont", " 1st Controller # ")
+ self.w.button(self.b3, "Pan", "Pan Control ?")
+ self.w.spin(7, 0, 127, 1, 1, self.b4, 0, "PCont", "Pan Controller #")
+ self.p = False
+ self.w.text("<i>Select options first </i>", self.b5, self.g)
+ self.but = self.w.cbbutton(self.b5, 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\t\t", self.box1)
+ self.box2 = self.w.box(True, self.bb)
+ self.f = self.w.framebox(" <b>Sister Moon Music</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.w.reset()
+ self.w.csd("MoonMusic.csd")
+ self.w.spin(0, 0, 16, 1, 1, self.b1, 0, "Chan", " Channel # ")
+ self.w.spin(20, 0, 120, 1, 1, self.b2, 0, "Cont", " 1st Controller # ")
+ self.w.button(self.b3, "Pan", "Pan Control ?")
+ self.w.spin(7, 0, 127, 1, 1, self.b4, 0, "PCont", "Pan Controller #")
+ self.p = False
+ self.w.text("<i>Select options first </i>", self.b5, self.g)
+ self.but = self.w.cbbutton(self.b5, 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))
+
+