A TOOLKIT FOR MUSIC AND AUDIO ACTIVITIES ON THE XO COMPUTERSkip other details (including permanent urls, DOI, citation information)
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 3.0 License. Please contact email@example.com to use this work in a way not covered by the license. :
For more information, read Michigan Publishing's access and usage policy.
Page 2 ï~~although not necessarily requiring fluency on both or any of these languages. The toolkit should provide a quick migration route from the FLTK widget opcodes, which integrate Csound5, as they will not be supported in the XO release of the language. Since many interesting Csound applications have been developed using these opcodes to implement their GUI, it will be quite useful to provide a route for porting these to the XO. 2. SYSTEM COMPONENTS As discussed in the introduction, the toolkit is based on two components: Csound, accessed through its API, and Python (with GTK), for activity development. The basic GUI environment on the XO laptop is called Sugar (fig.2). Also written in Python, it provides the activity model for the system. 2.1. The Csound Python API The Csound API is, in most part available for Python Scripting , with a few exceptions related to lowerlevel operations that are only suited to C/C++ programming. In general, the basic operations to control the Csound engine can be summarised as follows: 1. Csound instance creation: from csnd import * cs = Csound() 2. Code compilation: result = cs.Compile("mycsd.csd") 3. Performance: perf = CsoundPerformanceThread(cs) perf. Play () This simple example demonstrates the spawning of a separate thread for performance, but it is possible to implement a single-threaded version, if needed. Once an instance of Csound is performing, events can be sent to it using, for instance, perf.InputMessage(event string) with which instrument instances can be started or stopped. In addition, communication between Csound and Python is enabled by the software bus, using cs. SetChannel ("channelname", value) for sending control data in, and value = cs.GetChannel ("channel name") These and a few other methods of the Csound class can be used to control Csound in a very flexible way. The csndsugui toolkit combines these facilities with the GUI elements provided by PyGTK and Sugar to allow for simple and transparent activity development. 2.2. GTK and Sugar Sugar is the core of the XO laptop user interface. Applications running on it are called activities. From a programming point of view, they are based on subclasses of the Activity class, which is itself derived from the gtk.Window class (as well as gtk.Container). So it provides access to GTK graphics and widgets, which can be then integrated into an application. In order to create such application, the user will provide a class of his/her own, derived from sugar.activity.Activity. Such user-defined classes are then instantiated by sugar when an Activity is launched. In addition, Activities will in general also require a toolbox to be instantiated, so that default controls, such as close, minimise, etc., can be easily accessed. The application itself is a bundle of several files, including graphics resources, inventories, etc.., as well as the user supplied Python script(s). Figure 2. The Sugar desktop environment. The programming of Activity subclasses can be quite complex, as there is extensive support for a variety of components. The principle of the csndsugui toolkit is to allow all this complexity to be bypassed. The user will only need to derive a bare-bones Activity class and then use the toolkit to build the interface to his/her Csound code. 3. THE CSNDSUGUI TOOLKIT The csndsugui toolkit is founded on a base class, BasicGUI, which implements all the graphics, widget support and the basic communication mechanism. From this is derived the CsndGUI class, which implements all the Csound engine control. The BasicGUI class holds an externally-created Activity object that is its main window. It creates the standard Activity toolbox and any widgets that the user defines. Currently it supports the following GTK widgets: * Sliders (and slider banks) * On/off buttons (and button banks) * Message buttons
Page 3 ï~~Spin buttons File choosers Frames Boxes Text labels More widgets can be added, provided they are implemented in PyGTK. BasicGUI user methods: button(box, title): creates an ON/OFF button mbutton(box, message,title): creates a message button box(vert, parent,padding): creates a box (vert. or horiz.) filechooser(box, title): filechooser button slider(init,start,end,x,y,box,title,vert,linear): creates a linear or exponential slider (vert. or horiz.) spin(init,start,end,step,page,box,accel,title): creates a spin button text(name,box,colour):creates a text label framebox(name,vert,parent,colour,padding): creates a frame box (vert. or horiz.) vsliderbank(items,init,start,end,x,y,box): creates a vertical slider bank hsliderbank (items,init,start,end,x,y,box): creates a horizontal slider bank buttonbank(self, items, box): creates a button bank init_(act,colour,vert): creates a BasicGUI object based on Activity instance act The key aspect of the BasicGUI class implementation is that it provides an automatic generation/assignment of software bus channels. These carry the name label given to the widget and can be easily referenced in Csound code. They can also be assigned default names, such as BN, for a button, where N is the button number (in order of creation). All the communication calls are hidden away from the user, who only needs to create the widgets and use the control channels in his/her Csound instruments. The BasicGUI class does not know anything about Csound, so it requires that all of its functionality be overriden. This is done in the CsndGUI class, which implements the calls to the Csound API. A CsndGUI object will contain instances of Csound and CsoundPerformanceThread. It provides some basic methods for Csound operations, such as 'play', 'pause', etc.. CsndGUI user methods: csd(name): sets the source CSD (unified Csound code file) and compiles it play(): starts a Csound performance pause(): pauses performance reset(): resets Csound, ready for a new CSD set_channel(chan,val): set a value on a control channel, generally not used directly. set_filechannel(chan,name): sets a string on a file channel, generally not used directly set_message(mess): sets a message (RT event), generally not used directly (accessed through the GUI widgets) init_(act,colour,vert): creates a CsndGUI (and therefore a BasicGUI) object based on Activity instance act Typically, users will never create a BasicGUI object directly, but will instead instantiate a CsndGUI. Once this is done, a CSD can be passed to it and the performance can be initiated using the play() method. The next section demonstrates some typical uses of the toolkit. 4. ACTIVITY EXAMPLE A csndsugui-based activity will be based on two userwritten components: a python script, where the GUI is defined and an unified Csound code file (CSD), which is an XML file containing the Csound instruments and any relevant score events. Depending on the controls set up in the Python script, a number of channels will be available to Csound instruments. These can be used to control any parameters of the synthesis/processing operation. As mentioned above, the channels will be identified by their widget labels, so they can be easily referenced. The simple example shown here creates 8 parallel oscillators with independent on/off and frequency controls. A button bank is used for the oscillator switches and sliders for frequency adjustment. The activity script is shown below. It defines a subclass of activity.Activity (from the sugar package), which, as mentioned above, is derived from gtk.Window. Only the init () method of that class is required. A m CsoundGUI object is created as a class member and passed the class reference. Then the CSD for the application is set, followed by the creation of all required widgets. The code is completed by starting the Csound engine, which will be automatically stopped on exit. import csndsugui from sugar.activity import activity # the activity (sub-)class class Waves(activity.Activity): def init (self, handle): activity.Activity. init (self, \ handle) # colours red = (OxFFFF,0,0) bg = (OxF000, OxFF00, OxFFFF) # the csndsugui app object app = csndsugui.CsoundGUI (self,bg) # the source CS, window title app. csd ("waves. csd") app.text ("Making Waves") # bounding boxes for widgets sfbox = app.box(False) bfbox = app.box(False) # boxes for sliders and buttons sbox = app.framebox("frequencies",\ False, sfbox, red, 40) bbox = app.framebox("oscillators",\ False, sfbox,red, 40) # widgets
Page 4 ï~~app.buttonbank (8, bbox) app. spin (0,0,10,0.5, 1,bbox, 0, \ "main volume") app.vsliderbank(8,400.0,400.0, \ 500.0,80,200, sbox) # run the Csound engine app.play() The Csound code, as defined in the CSD file will then define all the instruments, using the controls provided in the Python script. The channels defined in there have the default names "BN" for buttons (on/off, 0/1) and "SN" for sliders. Channels are exported to global variables for ease of use: /* gkbN holds the (0 or 1) values of each button in the bank (B1-8) */ gkbl chnexport "BI", 1 Two instruments are used: the first to trigger instances of the second, which contains the sound synthesis code. The triggering is done by checking the values of the button channels B1 to B8: instr 1 kl init 1 /* if gkbl changes to 1 then the instance 1 of instr 11 is triggered */ if gkbl == 1 then if kl == 1 then event "i", 11.1, 0, -1, 1 kl =0 endif /* if gkbl changes to 0 then the instance 1 of instr 11 is killed */ else if kl == 0 then event "i", -11.1, 0, -1,1 kl=1 endif endif /* and so on for the other 7 buttons */ endin The synthesis instrument looks up the value of the S1 to S8 channels to get its frequency and the "mainvolume" channel (spin widget) to get its amplitude: instr 11 /* p4 is instance ID */ S1 sprintf "S%d", p4 k1 chnget S1 k2 chnget "main volume" kv tonek k2/10, 10 ka linenr 2000*kv,0.1,0.1,0.05 al oscili ka, ki, 1 outs al, al endin One instance of instr 1 runs for the duration of the program and up to 8 instances of instr 2 can be triggered at different times by using the button controls. As mentioned before, Activities are bundles containing the Python scripts plus resource files. The CSD file is placed in the activity bundle (its top directory). Other important files are: setup.py: used to create the activity and contains a call to bundlebuilder.start() with the name of the Activity subclass. activity/activity.info: contains all the required information about the activity (name, icon file, class name, etc). The process of putting together an activity bundle is quite simple, once all the required Python and Csound code are written. It is well documented by the OLPC development team. 5. FURTHER PROSPECTS The csndsugui is in its version 1, providing a fullyfunctional software, with features that make it a substitute to the Csound FLTK widget set, plus some extras such as the file chooser control. In its envisaged that most work will now be concentrated in integrating it further with Sugar, in order to take advantage of its facilities for GUI development. Some extra work on documentation, mainly in the development of tutorials for target users, will be necessary. The latest versions of the toolkit, reference and example applications can be found in: http://dev.laptop.org/git?p=activities/csndsugui 6. REFERENCES  ffitch, J. "On the Design of Csound5". Proceedings of the 3rd Linux Audio Conference, ZKM, Karlsruhe, Germany, 2005, pp.37-42.  Lazzarini, V. "Scripting Csound 5", Proceedings of the 4th Int. Linux Audio Conf., ZKM, Karlsruhe, Germany, 2006, pp.73-78.  http://www.laptop.org/laptop/hardware/specs.s html  http://www.laptop.org/vision/mission  http://www.laptop.org/laptop/software/specs.sh tml  http://wiki.laptop.org/go/TamTam  Papert, S.. Mindstorms. children, computers, and powerful ideas. Harvester Press, Brighton, 1980  Van Rossum, G and F. Drake. The Python Language Reference Manual, Network Theory, Bristol, 2003.