Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Lazzarini <Victor.Lazzarini@nuim.ie>2008-03-21 20:24:51 (GMT)
committer Victor Lazzarini <Victor.Lazzarini@nuim.ie>2008-03-21 20:24:51 (GMT)
commit257e63fde492f46f3826dccb06259d7d721a0664 (patch)
tree40cc62df4d08634b41dd0e8095f04c99e1ff6092
parent1d0533df58544d9f644d597529187a8a6293abf2 (diff)
added playfile.activity
added focus in/out capabilities to release soundcard
-rwxr-xr-xSynth.activity/csndsugui.py143
-rwxr-xr-xSynth.activity/synth.py2
-rw-r--r--Waves.activity/csndsugui.py143
-rwxr-xr-xcsndsugui.py143
-rwxr-xr-xplayfile.activity/MANIFEST7
-rwxr-xr-xplayfile.activity/activity/activity-playfiles.svg14
-rwxr-xr-xplayfile.activity/activity/activity.info7
-rwxr-xr-xplayfile.activity/csndsugui.py684
-rwxr-xr-xplayfile.activity/playfile.csd59
-rwxr-xr-xplayfile.activity/playfiles.py36
-rwxr-xr-xplayfile.activity/setup.py5
-rwxr-xr-xplayfile.activity/synth.py65
12 files changed, 1208 insertions, 100 deletions
diff --git a/Synth.activity/csndsugui.py b/Synth.activity/csndsugui.py
index eb84ec0..8281b19 100755
--- a/Synth.activity/csndsugui.py
+++ b/Synth.activity/csndsugui.py
@@ -37,7 +37,8 @@ import csnd
import math
import locale
import os
-
+import sugar.logger
+import time
class BasicGUI:
"""Basic GUI with boxes, sliders, spins, buttons etc
@@ -62,7 +63,7 @@ class BasicGUI:
def get_slider_value(self,name):
"""returns the slider value
- name: slider name (which should also be the attached bus channel name"""
+ name: slider name (which should also be the attached bus channel name"""
for i in self.sliders:
if i[1] == name:
return i[2]
@@ -92,6 +93,24 @@ class BasicGUI:
if i[1] == name:
return i[0]
return 0
+
+ def set_focus(self):
+ """ called whenever the focus changes """
+ print 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.connect_focus()
def buttcallback(self, widget, data=None):
for i in self.buttons:
@@ -107,7 +126,7 @@ class BasicGUI:
self.set_channel(i[1], i[2])
def mbuttcallback(self, widget, data=None):
- for i in self.buttons:
+ for i in self.mbuttons:
if i[0] == widget:
self.set_message(i[2])
@@ -133,19 +152,29 @@ class BasicGUI:
def filecallback(self,widget):
name = self.curfile[0].get_filename()
- self.set_filechannel(self.curfile[1], name)
- self.filenames.update({self.curfile[1] : name})
+ 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()
+
+ def destroy_chooser(self,widget):
+ self.curfile[0].destroy()
+
+
# internal callback
def fbuttcallback(self, widget, data=None):
+ self.focus_disconnect()
+ self.fback = self.window.connect('focus_in_event', self.focus_back)
for i in self.buttons:
if i[0] == widget:
chooser = gtk.FileSelection(i[1])
- self.curfile = (chooser, 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", lambda h: chooser.destroy())
+ chooser.cancel_button.connect("clicked", self.destroy_chooser)
chooser.show()
@@ -204,7 +233,7 @@ class BasicGUI:
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.buttons.append([butt,title,mess])
+ self.mbuttons.append([butt,title,mess])
butt.connect("clicked", self.mbuttcallback)
butt.show()
return butt
@@ -238,7 +267,7 @@ class BasicGUI:
else: name = label
butt = gtk.Button(name)
box.pack_start(butt, False, False, 5)
- self.buttons.append([butt,title])
+ self.buttons.append([butt,title,"0"])
butt.connect("clicked", self.fbuttcallback)
self.set_filechannel(title,"0")
self.filenames.update({title:"0"})
@@ -435,6 +464,32 @@ class BasicGUI:
"""Returns the Activity toolbox"""
return self.toolbox
+ def channels_reinit(self):
+ """ resets channel to current widget values"""
+ for i in self.channel_widgets:
+ for j in i:
+ if(j[1] != "pause"):
+ if(j[1] != "play"):
+ if(j[1] != "reset"):
+ self.set_channel(j[1],j[2])
+ self.logger.debug(j[1])
+
+ 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
@@ -453,6 +508,8 @@ class BasicGUI:
self.mbuttons = []
self.mbutts = 0
self.boxes = []
+ self.connected = False
+ self.channel_widgets = [self.sliders, self.spins, self.buttons]
self.filenames = dict()
self.window = act
if toolbox == None:
@@ -470,6 +527,8 @@ class BasicGUI:
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):
@@ -495,13 +554,26 @@ class CsoundGUI(BasicGUI):
def set_filechannel(self,chan,name):
"""overrides the base method, setting the channel string"""
if not self.ready:
- self.csound.SetChannel(chan,name)
+ self.csound.SetChannel(chan,name)
else:
- BasicGUI.set_filechannel(self,chan,name)
+ BasicGUI.set_filechannel(self,chan,name)
def set_message(self, mess):
"""overrides the base method, sends a score message"""
- self.perf.InputMessage(mess)
+ 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()
def play(self):
"""Starts a performance. """
@@ -524,19 +596,16 @@ class CsoundGUI(BasicGUI):
self.paused = False
self.perf.Play()
- def csd(self, name, extra=None):
+ def csd(self, name):
"""Sets the source CSD and compiles it.
name: CSD filename
- extra: a single extra parameter
returns zero if successful"""
- self.extra = extra
path = activity.get_bundle_path()
if self.ready:
- if self.extra != None:
- res = self.csound.Compile("%s/%s" % (path,name), extra)
- else:
res = self.csound.Compile("%s/%s" % (path,name))
- if not res: self.ready = False
+ if not res:
+ self.ready = False
+ self.focus_connect()
self.path = path
self.name = name
return res
@@ -552,38 +621,44 @@ class CsoundGUI(BasicGUI):
self.perf = csnd.CsoundPerformanceThread(self.csound)
if self.arglist != None:
res = self.csound.Compile(self.arglist.argc(),self.arglist.argv())
- elif self.extra != None:
- res = self.csound.Compile("%s/%s" % (self.path,self.name), self.extra)
else:
res = self.csound.Compile("%s/%s" % (self.path,self.name))
if(res): self.ready = True
return res
- def compile(self,name,args):
+ def compile(self,name=None,args=[]):
"""Compiles Csound code.
- name: CSD filename
+ name: CSD filename if given
args: list of arguments (as strings)
returns 0 if successful , non-zero if not."""
if self.ready:
- self.arglist = csnd.CsoundArgVList()
+ if args != []:
+ self.arglist = csnd.CsoundArgVList()
self.path = activity.get_bundle_path()
- self.name = name
- 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())
- if not res: self.ready = False
+ 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
- # resets Csound ready for a new CSD
def reset(self):
"""Resets Csound, ready for a new CSD"""
if not self.ready:
self.perf.Stop()
self.perf.Join()
self.on = False
- self.pause = False
+ self.paused = False
self.perf = csnd.CsoundPerformanceThread(self.csound)
self.ready = True
@@ -605,3 +680,5 @@ class CsoundGUI(BasicGUI):
self.paused = False
self.name = "0"
self.arglist = None
+ self.replay = False
+
diff --git a/Synth.activity/synth.py b/Synth.activity/synth.py
index a75d297..f62a8d2 100755
--- a/Synth.activity/synth.py
+++ b/Synth.activity/synth.py
@@ -16,7 +16,7 @@ class Synth(activity.Activity):
# GUI window
win = csndsugui.CsoundGUI(self,bg)
- if win.csd("synth.csd","-Mhw:1,0"):
+ if win.compile("synth.csd",["-Mhw:1,0"]):
win.csd("synth.csd")
txt = win.text("Synthesizer Panel",colour=fr)
hbox = win.box(False)
diff --git a/Waves.activity/csndsugui.py b/Waves.activity/csndsugui.py
index eb84ec0..8281b19 100644
--- a/Waves.activity/csndsugui.py
+++ b/Waves.activity/csndsugui.py
@@ -37,7 +37,8 @@ import csnd
import math
import locale
import os
-
+import sugar.logger
+import time
class BasicGUI:
"""Basic GUI with boxes, sliders, spins, buttons etc
@@ -62,7 +63,7 @@ class BasicGUI:
def get_slider_value(self,name):
"""returns the slider value
- name: slider name (which should also be the attached bus channel name"""
+ name: slider name (which should also be the attached bus channel name"""
for i in self.sliders:
if i[1] == name:
return i[2]
@@ -92,6 +93,24 @@ class BasicGUI:
if i[1] == name:
return i[0]
return 0
+
+ def set_focus(self):
+ """ called whenever the focus changes """
+ print 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.connect_focus()
def buttcallback(self, widget, data=None):
for i in self.buttons:
@@ -107,7 +126,7 @@ class BasicGUI:
self.set_channel(i[1], i[2])
def mbuttcallback(self, widget, data=None):
- for i in self.buttons:
+ for i in self.mbuttons:
if i[0] == widget:
self.set_message(i[2])
@@ -133,19 +152,29 @@ class BasicGUI:
def filecallback(self,widget):
name = self.curfile[0].get_filename()
- self.set_filechannel(self.curfile[1], name)
- self.filenames.update({self.curfile[1] : name})
+ 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()
+
+ def destroy_chooser(self,widget):
+ self.curfile[0].destroy()
+
+
# internal callback
def fbuttcallback(self, widget, data=None):
+ self.focus_disconnect()
+ self.fback = self.window.connect('focus_in_event', self.focus_back)
for i in self.buttons:
if i[0] == widget:
chooser = gtk.FileSelection(i[1])
- self.curfile = (chooser, 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", lambda h: chooser.destroy())
+ chooser.cancel_button.connect("clicked", self.destroy_chooser)
chooser.show()
@@ -204,7 +233,7 @@ class BasicGUI:
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.buttons.append([butt,title,mess])
+ self.mbuttons.append([butt,title,mess])
butt.connect("clicked", self.mbuttcallback)
butt.show()
return butt
@@ -238,7 +267,7 @@ class BasicGUI:
else: name = label
butt = gtk.Button(name)
box.pack_start(butt, False, False, 5)
- self.buttons.append([butt,title])
+ self.buttons.append([butt,title,"0"])
butt.connect("clicked", self.fbuttcallback)
self.set_filechannel(title,"0")
self.filenames.update({title:"0"})
@@ -435,6 +464,32 @@ class BasicGUI:
"""Returns the Activity toolbox"""
return self.toolbox
+ def channels_reinit(self):
+ """ resets channel to current widget values"""
+ for i in self.channel_widgets:
+ for j in i:
+ if(j[1] != "pause"):
+ if(j[1] != "play"):
+ if(j[1] != "reset"):
+ self.set_channel(j[1],j[2])
+ self.logger.debug(j[1])
+
+ 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
@@ -453,6 +508,8 @@ class BasicGUI:
self.mbuttons = []
self.mbutts = 0
self.boxes = []
+ self.connected = False
+ self.channel_widgets = [self.sliders, self.spins, self.buttons]
self.filenames = dict()
self.window = act
if toolbox == None:
@@ -470,6 +527,8 @@ class BasicGUI:
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):
@@ -495,13 +554,26 @@ class CsoundGUI(BasicGUI):
def set_filechannel(self,chan,name):
"""overrides the base method, setting the channel string"""
if not self.ready:
- self.csound.SetChannel(chan,name)
+ self.csound.SetChannel(chan,name)
else:
- BasicGUI.set_filechannel(self,chan,name)
+ BasicGUI.set_filechannel(self,chan,name)
def set_message(self, mess):
"""overrides the base method, sends a score message"""
- self.perf.InputMessage(mess)
+ 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()
def play(self):
"""Starts a performance. """
@@ -524,19 +596,16 @@ class CsoundGUI(BasicGUI):
self.paused = False
self.perf.Play()
- def csd(self, name, extra=None):
+ def csd(self, name):
"""Sets the source CSD and compiles it.
name: CSD filename
- extra: a single extra parameter
returns zero if successful"""
- self.extra = extra
path = activity.get_bundle_path()
if self.ready:
- if self.extra != None:
- res = self.csound.Compile("%s/%s" % (path,name), extra)
- else:
res = self.csound.Compile("%s/%s" % (path,name))
- if not res: self.ready = False
+ if not res:
+ self.ready = False
+ self.focus_connect()
self.path = path
self.name = name
return res
@@ -552,38 +621,44 @@ class CsoundGUI(BasicGUI):
self.perf = csnd.CsoundPerformanceThread(self.csound)
if self.arglist != None:
res = self.csound.Compile(self.arglist.argc(),self.arglist.argv())
- elif self.extra != None:
- res = self.csound.Compile("%s/%s" % (self.path,self.name), self.extra)
else:
res = self.csound.Compile("%s/%s" % (self.path,self.name))
if(res): self.ready = True
return res
- def compile(self,name,args):
+ def compile(self,name=None,args=[]):
"""Compiles Csound code.
- name: CSD filename
+ name: CSD filename if given
args: list of arguments (as strings)
returns 0 if successful , non-zero if not."""
if self.ready:
- self.arglist = csnd.CsoundArgVList()
+ if args != []:
+ self.arglist = csnd.CsoundArgVList()
self.path = activity.get_bundle_path()
- self.name = name
- 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())
- if not res: self.ready = False
+ 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
- # resets Csound ready for a new CSD
def reset(self):
"""Resets Csound, ready for a new CSD"""
if not self.ready:
self.perf.Stop()
self.perf.Join()
self.on = False
- self.pause = False
+ self.paused = False
self.perf = csnd.CsoundPerformanceThread(self.csound)
self.ready = True
@@ -605,3 +680,5 @@ class CsoundGUI(BasicGUI):
self.paused = False
self.name = "0"
self.arglist = None
+ self.replay = False
+
diff --git a/csndsugui.py b/csndsugui.py
index eb84ec0..8281b19 100755
--- a/csndsugui.py
+++ b/csndsugui.py
@@ -37,7 +37,8 @@ import csnd
import math
import locale
import os
-
+import sugar.logger
+import time
class BasicGUI:
"""Basic GUI with boxes, sliders, spins, buttons etc
@@ -62,7 +63,7 @@ class BasicGUI:
def get_slider_value(self,name):
"""returns the slider value
- name: slider name (which should also be the attached bus channel name"""
+ name: slider name (which should also be the attached bus channel name"""
for i in self.sliders:
if i[1] == name:
return i[2]
@@ -92,6 +93,24 @@ class BasicGUI:
if i[1] == name:
return i[0]
return 0
+
+ def set_focus(self):
+ """ called whenever the focus changes """
+ print 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.connect_focus()
def buttcallback(self, widget, data=None):
for i in self.buttons:
@@ -107,7 +126,7 @@ class BasicGUI:
self.set_channel(i[1], i[2])
def mbuttcallback(self, widget, data=None):
- for i in self.buttons:
+ for i in self.mbuttons:
if i[0] == widget:
self.set_message(i[2])
@@ -133,19 +152,29 @@ class BasicGUI:
def filecallback(self,widget):
name = self.curfile[0].get_filename()
- self.set_filechannel(self.curfile[1], name)
- self.filenames.update({self.curfile[1] : name})
+ 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()
+
+ def destroy_chooser(self,widget):
+ self.curfile[0].destroy()
+
+
# internal callback
def fbuttcallback(self, widget, data=None):
+ self.focus_disconnect()
+ self.fback = self.window.connect('focus_in_event', self.focus_back)
for i in self.buttons:
if i[0] == widget:
chooser = gtk.FileSelection(i[1])
- self.curfile = (chooser, 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", lambda h: chooser.destroy())
+ chooser.cancel_button.connect("clicked", self.destroy_chooser)
chooser.show()
@@ -204,7 +233,7 @@ class BasicGUI:
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.buttons.append([butt,title,mess])
+ self.mbuttons.append([butt,title,mess])
butt.connect("clicked", self.mbuttcallback)
butt.show()
return butt
@@ -238,7 +267,7 @@ class BasicGUI:
else: name = label
butt = gtk.Button(name)
box.pack_start(butt, False, False, 5)
- self.buttons.append([butt,title])
+ self.buttons.append([butt,title,"0"])
butt.connect("clicked", self.fbuttcallback)
self.set_filechannel(title,"0")
self.filenames.update({title:"0"})
@@ -435,6 +464,32 @@ class BasicGUI:
"""Returns the Activity toolbox"""
return self.toolbox
+ def channels_reinit(self):
+ """ resets channel to current widget values"""
+ for i in self.channel_widgets:
+ for j in i:
+ if(j[1] != "pause"):
+ if(j[1] != "play"):
+ if(j[1] != "reset"):
+ self.set_channel(j[1],j[2])
+ self.logger.debug(j[1])
+
+ 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
@@ -453,6 +508,8 @@ class BasicGUI:
self.mbuttons = []
self.mbutts = 0
self.boxes = []
+ self.connected = False
+ self.channel_widgets = [self.sliders, self.spins, self.buttons]
self.filenames = dict()
self.window = act
if toolbox == None:
@@ -470,6 +527,8 @@ class BasicGUI:
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):
@@ -495,13 +554,26 @@ class CsoundGUI(BasicGUI):
def set_filechannel(self,chan,name):
"""overrides the base method, setting the channel string"""
if not self.ready:
- self.csound.SetChannel(chan,name)
+ self.csound.SetChannel(chan,name)
else:
- BasicGUI.set_filechannel(self,chan,name)
+ BasicGUI.set_filechannel(self,chan,name)
def set_message(self, mess):
"""overrides the base method, sends a score message"""
- self.perf.InputMessage(mess)
+ 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()
def play(self):
"""Starts a performance. """
@@ -524,19 +596,16 @@ class CsoundGUI(BasicGUI):
self.paused = False
self.perf.Play()
- def csd(self, name, extra=None):
+ def csd(self, name):
"""Sets the source CSD and compiles it.
name: CSD filename
- extra: a single extra parameter
returns zero if successful"""
- self.extra = extra
path = activity.get_bundle_path()
if self.ready:
- if self.extra != None:
- res = self.csound.Compile("%s/%s" % (path,name), extra)
- else:
res = self.csound.Compile("%s/%s" % (path,name))
- if not res: self.ready = False
+ if not res:
+ self.ready = False
+ self.focus_connect()
self.path = path
self.name = name
return res
@@ -552,38 +621,44 @@ class CsoundGUI(BasicGUI):
self.perf = csnd.CsoundPerformanceThread(self.csound)
if self.arglist != None:
res = self.csound.Compile(self.arglist.argc(),self.arglist.argv())
- elif self.extra != None:
- res = self.csound.Compile("%s/%s" % (self.path,self.name), self.extra)
else:
res = self.csound.Compile("%s/%s" % (self.path,self.name))
if(res): self.ready = True
return res
- def compile(self,name,args):
+ def compile(self,name=None,args=[]):
"""Compiles Csound code.
- name: CSD filename
+ name: CSD filename if given
args: list of arguments (as strings)
returns 0 if successful , non-zero if not."""
if self.ready:
- self.arglist = csnd.CsoundArgVList()
+ if args != []:
+ self.arglist = csnd.CsoundArgVList()
self.path = activity.get_bundle_path()
- self.name = name
- 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())
- if not res: self.ready = False
+ 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
- # resets Csound ready for a new CSD
def reset(self):
"""Resets Csound, ready for a new CSD"""
if not self.ready:
self.perf.Stop()
self.perf.Join()
self.on = False
- self.pause = False
+ self.paused = False
self.perf = csnd.CsoundPerformanceThread(self.csound)
self.ready = True
@@ -605,3 +680,5 @@ class CsoundGUI(BasicGUI):
self.paused = False
self.name = "0"
self.arglist = None
+ self.replay = False
+
diff --git a/playfile.activity/MANIFEST b/playfile.activity/MANIFEST
new file mode 100755
index 0000000..0b3e488
--- /dev/null
+++ b/playfile.activity/MANIFEST
@@ -0,0 +1,7 @@
+setup.py
+playfile.csd
+activity/activity.info
+activity/activity-playfiles.svg
+csndsugui.py
+playfiles.py
+MANIFEST \ No newline at end of file
diff --git a/playfile.activity/activity/activity-playfiles.svg b/playfile.activity/activity/activity-playfiles.svg
new file mode 100755
index 0000000..f333eab
--- /dev/null
+++ b/playfile.activity/activity/activity-playfiles.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+ <!ENTITY fill_color "#FFFFFF">
+ <!ENTITY stroke_color "#000000">
+]>
+<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50">
+ <rect x="1" y="1" width="48" height="48"
+ style="fill:&fill_color;;stroke:&stroke_color;;stroke-width:2"/>
+
+<ellipse cx = "24" cy ="24"
+ rx="38" ry="22"
+ fill="white" stroke="white" stroke-width="2" />
+</svg>
diff --git a/playfile.activity/activity/activity.info b/playfile.activity/activity/activity.info
new file mode 100755
index 0000000..100b568
--- /dev/null
+++ b/playfile.activity/activity/activity.info
@@ -0,0 +1,7 @@
+[Activity]
+name = Playfiles
+service_name = org.laptop.playfiles
+class = playfiles.Playfiles
+icon = activity-playfiles
+activity_version = 1
+show_launcher = yes
diff --git a/playfile.activity/csndsugui.py b/playfile.activity/csndsugui.py
new file mode 100755
index 0000000..8281b19
--- /dev/null
+++ b/playfile.activity/csndsugui.py
@@ -0,0 +1,684 @@
+# 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.2 18/03/08
+
+import pygtk
+pygtk.require('2.0')
+from sugar.activity import activity
+import gtk
+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."""
+ print "channel:%s, value:%.1f" % (name,val)
+
+ def set_filechannel(self,chan,name):
+ """basic filename channel setting method
+ should be overriden for full-functionality."""
+ print "channel:%s, filename:%s" % (chan,name)
+
+
+ def set_message(self, mess):
+ """basic message setting method
+ should be overriden for full-functionality."""
+ print 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 """
+ print 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.connect_focus()
+
+ 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(0x0FFF,0,0x00FF, 2))
+ i[0].modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF,0,0xFFFF, 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 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()
+
+
+ def destroy_chooser(self,widget):
+ self.curfile[0].destroy()
+
+
+ # internal callback
+ def fbuttcallback(self, widget, data=None):
+ self.focus_disconnect()
+ self.fback = self.window.connect('focus_in_event', self.focus_back)
+ 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(" %s " % title)
+ box.pack_start(butt, False, False, 5)
+ 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.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.Color(0xFFFF,0,0, 1))
+ butt.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(0xFFFF,0,0xFFFF, 2))
+ box.pack_start(butt, False, False, 5)
+ 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=5):
+ """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 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)
+ if step < 1.0:
+ spin.set_digits(3)
+ elif step < 10:
+ spin.set_digits(2)
+ elif step < 100:
+ spin.set_digits(1)
+ else:
+ spin.set_digits(0)
+
+ if label == "": name = title
+ else: name = label
+ label = gtk.Label(name)
+ box.pack_start(spin, False, False, 5)
+ box.pack_start(label, False, False, 2)
+ 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.modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(colour[0],colour[1],colour[2], 0))
+ if box:
+ box.pack_start(label, False, False, 5)
+ else:
+ self.outbox.pack_start(label, False, False, 5)
+ 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))
+ 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 i in self.channel_widgets:
+ for j in i:
+ if(j[1] != "pause"):
+ if(j[1] != "play"):
+ if(j[1] != "reset"):
+ self.set_channel(j[1],j[2])
+ self.logger.debug(j[1])
+
+ 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.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()
+
+ 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 __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
+
diff --git a/playfile.activity/playfile.csd b/playfile.activity/playfile.csd
new file mode 100755
index 0000000..077ce78
--- /dev/null
+++ b/playfile.activity/playfile.csd
@@ -0,0 +1,59 @@
+<CsoundSynthesizer>
+<CsOptions>
+-odac -B2048 -b1024 -d -+rtaudio=alsa
+</CsOptions>
+<CsInstruments>
+sr=44100
+ksmps=100
+nchnls=1
+gas init 0
+
+instr 1
+Svol sprintf "main_volume%d", p4
+Spit sprintf "pitch%d", p4
+Smut sprintf "mute%d", p4
+S1 chnget "soundfile"
+i1 strcmp S1,"0"
+if i1 != 0 goto continue
+puts "no filename selected !!", 1
+turnoff
+goto end
+continue:
+ich filenchnls S1
+k2 chnget Svol
+kp chnget Spit
+km chnget Smut
+kv tonek k2*(1-km)/10, 10
+if ich == 1 then
+am diskin2 S1,kp,0,1
+else
+a1,a2 diskin2 S1,kp,0,1
+am = (a1+a2)/2
+endif
+as = am*kv
+ out as
+gas = as + gas
+end:
+endin
+
+instr 9
+S1 chnget "output_file"
+i1 strcmp S1,"0"
+if i1 != 0 goto continue
+puts "no output filename selected !!", 1
+turnoff
+goto end
+continue:
+fout S1,2, gas
+end:
+endin
+
+instr 10
+gas = 0
+endin
+
+</CsInstruments>
+<CsScore>
+i10 0 3600000
+</CsScore>
+</CsoundSynthesizer>
diff --git a/playfile.activity/playfiles.py b/playfile.activity/playfiles.py
new file mode 100755
index 0000000..ae8556c
--- /dev/null
+++ b/playfile.activity/playfiles.py
@@ -0,0 +1,36 @@
+# (c) Victor Lazzarini, 2006
+# Free software, licensed by GNU General Public License
+import csndsugui
+from sugar.activity import activity
+
+
+class Playfiles(activity.Activity):
+
+ def __init__(self, handle):
+ activity.Activity.__init__(self, handle)
+
+ # colour
+ bg = (0x0000, 0x7000, 0xA000)
+ white = (0xFFFF, 0xFFFF, 0xFFFF)
+
+ win = csndsugui.CsoundGUI(self, bg)
+ win.csd("playfile.csd")
+ win.text("Playing Sounds",colour=white)
+ #outbox = win.box(True)
+ bbox = win.box(False)
+ win.button(bbox,"play")
+ win.button(bbox,"pause")
+ win.filechooser(bbox,"soundfile")
+ pbox = []
+ for i in range(1, 10):
+ pbox.append(win.box(False))
+ win.mbutton(pbox[i-1],"i1.%d 0 -1 %d" % (i,i), "add to playlist %d..." % i)
+ win.mbutton(pbox[i-1],"i-1.%d 0 1 %d" % (i,i), "stop")
+ win.button(pbox[i-1], "mute%d"% i)
+ win.spin(5,0,10,0.5,1,pbox[i-1],0,"main_volume%d" % i )
+ win.slider(1.0,0.5,2.0,250,40,pbox[i-1],"pitch%i" % i, False,linear=False)
+ lbox = win.box(False)
+ win.mbutton(lbox,"i9 0 -1", "record")
+ win.mbutton(lbox,"i-9 0 1", "stop")
+ win.filechooser(lbox,"output_file")
+
diff --git a/playfile.activity/setup.py b/playfile.activity/setup.py
new file mode 100755
index 0000000..b1a11ac
--- /dev/null
+++ b/playfile.activity/setup.py
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+from sugar.activity import bundlebuilder
+if __name__ == "__main__":
+ bundlebuilder.start("Play files")
+
diff --git a/playfile.activity/synth.py b/playfile.activity/synth.py
new file mode 100755
index 0000000..d70d1c9
--- /dev/null
+++ b/playfile.activity/synth.py
@@ -0,0 +1,65 @@
+# (c) Victor Lazzarini, 2008
+# Free software, licensed by GNU General Public License
+
+import csndsugui
+from sugar.activity import activity
+
+
+class Synth(activity.Activity):
+
+ def __init__(self, handle):
+ activity.Activity.__init__(self, handle)
+
+ # colours
+ bg = (0x9000,0,0)
+ fr = (0x1000, 0x0000, 0x7000)
+
+ # GUI window
+ win = csndsugui.CsoundGUI(self,bg)
+ win.csd("synth.csd")
+ txt = win.text("Synthesizer Panel",colour=fr)
+ hbox = win.box(False)
+
+ # oscillator frames
+ box = win.box(parent=hbox)
+ box1 = win.box(False, box)
+ box2 = win.box(False, box)
+ frame1 = win.framebox("osc 1", False, box1, fr)
+ frame2 = win.framebox("osc 2", False, box2, fr)
+
+ # oscillator 1 controls
+ box = win.box(parent=frame1)
+ win.button(box,"osc1")
+ box = win.box(parent=frame1)
+ win.slider(1.0,0.25,4.0,45,100,box,"pitch1", linear=False)
+
+ # oscillator 2 controls
+ box = win.box(parent=frame2)
+ win.button(box,"osc2")
+ box = win.box(parent=frame2)
+ win.slider(1.0,0.25,4.0,45,100,box,"pitch2", linear=False)
+
+ # filter & mixer frames
+ box = win.box(parent=hbox)
+ box1 = win.box(False, box)
+ box2 = win.box(False, box)
+ frame1 = win.framebox("filter", True, box1, fr)
+ frame2 = win.framebox("mixer", False, box2, fr)
+
+ # filter controls
+ box = win.box(False, parent=frame1)
+ win.slider(1000.0,20.0,20000.0,120,20,box,"frequency", False,linear=False)
+ box = win.box(False, parent=frame1)
+ win.slider(0.9,0.0,1.0,120,20,box,"resonance", False)
+
+ # mixer controls
+ box = win.box(parent=frame2)
+ win.slider(0.0,0.0,100.0,45,180,box,"vol1")
+ box = win.box(parent=frame2)
+ win.slider(0.0,0.0,100.0,45,180,box,"vol2")
+ box = win.box(parent=frame2)
+ win.slider(0.0,0.0,100.0,45,180,box,"noise")
+ box = win.box(parent=frame2)
+ win.slider(0.0,0.0,100.0,45,180,box,"mic")
+
+ win.play()