λGTK: A PORTABLE GRAPHICS LAYER FOR COMMON MUSIC

Heinrich Taube

Composition/Theory School of Music University of Illinois Urbana, IL USA

ABSTRACT presented an undue hardship or problem. But with the publication of Notes from the Metalevel [5] (the λGTK (LAMBDA GTK) is a new, portable graphics author’s book on algorithmic composition) in 2004, layer for implementing graphical user interface (GUI) new users who have no background in sound synthesis tools in Common Music [1] (CM), an algorithmic or programming have begun to experiment with music composition environment that runs in Common algorithmic composition and Common Music. The Lisp [2] and Scheme [3]. λGTK provides a complete author decided to use this recent circumstance as the interface to the popular GTK2 [4] graphics libraries and impetus to implement a graphic layer. Since CM is currently supports the development of graphical displays both portable and free, two central requirements of the in three different public domain Lisp implementations new graphics code are that (1) the graphics libraries on two different operating systems. Two full-featured must also be free and (2) the graphical tools that are GUI tools for Common Music -- a music data developed must be usable in more than one public visualization tool called Plotter and an executive “front domain Lisp implementation and on more than one end” window called CMIO -- are briefly described as . After considering a number of examples of λGTK functionality. A key feature of different strategies and options the author decided to λGTK is that it is generated programmatically from base CM’s graphics on Version 2 of the Gimp Tool Kit information parsed from GTK header declarations rather (GTK2). GTK is a popular, public domain graphics than coded directly by hand. One benefit of this package that runs on multiple platforms, including implementation method is that larger (or less inclusive) Linux, OS X and Windows. Its powerful windowing interfaces can be generated on demand so Lisp features, free distribution, and stable release cycles make applications only need to load bindings for entry points it a good choice to implement source portable graphical in the GTK libraries that they actually use. Porting interfaces for Common Music. After first attempting to λGTK to new Lisp implementations is also much less use and adopt a few existing Lisp/GTK interfaces it work than if the layer had been coded by hand, and became apparent that there was no existing that resolving errors and other porting issues is now a global offered a complete Lisp binding for the complete GTK2 operation (regenerating the layer) rather than a local one API or that would run on multiple operating systems (finding each affected entry and editing it by hand in a and Lisp implementations. Mario Momar’s LGTK [6] text editor). To port λGTK to a new Lisp the developer package was the best candidate system, but, because it simply provides “back end” functions to the generating is written by hand, it implements only a tiny fraction of program that translates the system’s intermediate Lisp the thousands of possible GTK entry points. After representation of GTK’s data structures into the considering the size of GTK and the fact that multiple appropriate foreign function interface (FFI) code for the bindings would be required for a portable layer, the new target host. The λGTK layer itself does not depend author decided that generating Common Music’s on anything in Common Music and is available as a graphics layer was the appropriate way to solve both separate, package released under the Lisp problems. Lesser General Public License (LLGPL). 2. λGTK DESIGN 1. BACKGROUND AND MOTAVATION

Common Music is an object-oriented music λGTK is a cross-platform Lisp interface to the complete composition environment. It generates sound by GTK+2 family of shared libraries. Its design reflects transforming a high-level Lisp representation of musical solutions to two separate but equally problematic Lisp structure (algorithms, musical event descriptions and implementation issues: variability between different other compositional representations) into a variety of Lisp environments and the large number of GTK entry protocols for controlling sound synthesis and music points that a working Lisp interface might want to use. score generation. CM has bindings for both Common Most Lisp vendors provide a foreign function interface Lisp and Scheme dialects of Lisp and runs in a variety (FFI) protocol that specifies how Lisp programs can of Lisp implementations and operating systems. Its interface to non-Lisp (typically ) executables stored in highly portable nature, coupled with the fact that neither shared libraries. A number of Lisp implementations also nor Scheme requires a graphics standard, provide the ability for foreign code to call Lisp has made Common Music an essentially text-based functions encapsulated as foreign function callbacks. system until now. For a certain class of user – someone Any Lisp implementation that provides these two trained in musical synthesis languages or having prior features -- FFI linking to shared libraries and foreign programming experience – the lack of GUI tools has not function callback support -- is a candidate for using GTK2 as a windowing API. Happily, most Lisp implementations now fulfil these two essential pointers to ints, floats and doubles are also handled requirements in one way or another. Unfortunately, automatically: foreign values are allocated and because the Lisp language specification does not cover initialized on the Lisp side, the pointers are then foreign function interface design, the manner in which passed to GTK, dereferenced upon return and vendors implement these features varies widely with returned to the Lisp caller as multiple values. each Lisp implementation. In order to deal with this variability between Lisp FFI designs as well as with the • Lisp names for GTK's enums, structs and functions. sheer size of GTK’s programming interface (which Lisp names are formed by substituting "-" for "_" contains literally thousands of function, struct and enum and converting C prefixes like glib_ and into exported Lisp package prefixes like definitions) λGTK contains no hand-coded software gtk_ beyond a handful of functions (ten) that implement glib: and gtk: (Figure 1). vendor specific “glue code” for creating and registering • Lisp accessor functions for reading and setting slot callbacks and allocating foreign structures. The rest of values in GTK structs. Struct slots that contain the interface -- currently consisting of 3,500 Lisp included structures are also supported, e.g. definitions for CM’s current graphics tools -- is gtk:widget.allocation.width. The first programmatically generated from two information argument to a Lisp foreign structure accessor is a database files. The first file (gtk.ffi) contains a Lisp pointer to the struct. If the referenced slot is an representation of all GTK library header declarations. array then a second required argument provides the The second file (gtk.api) is an API inclusion file that index. The final argument to a struct accessor is allows fine-grain control over which enums, structs, optional; if specified, it replaces the current value in struct slot accessors and API functions will receive Lisp the slot. For example: bindings in the generated interface. Both database files (gdk:rectangle.x rect) ; get x value (gtk.ffi and gtk.api) were derived from C header files (gdk:rectangle.x rect 100) ; set x value using FFIGEN [7], a program originally developed by Lars Thomas Hansen and now maintained by Gary Given the simple and consistent name translations, Byers as part of his OpenMCL [8] Lisp anyone who is familiar with GTK programming and implementation. FFIGEN uses output from the C Lisp function call syntax will find that graphics work ’s pre-processor to translate GTK header with λGTK is straightforward and requires no declarations into equivalent expressions formatted as documentation beyond the GTK API reference itself Lisp lists. These Lisp list expressions can then be read, (Figure 1). manipulated and analyzed by Lisp programs. In order to generate a GTK interface, λGTK reads the parsed header (gtk:define-signal-handler bye :void (w d) (format "bye!~%") information contained in the gtk.ffi database and then (gtk:main-quit)) translates that information into the foreign function binding code for each supported Lisp implementation. (defun hello-world () The λGTK translation generator is organized into two (let ((w (gtk:window-new 0)) layers: a common file (lambda-gtk-common.lisp) and a (b (gtk:button-new-with-label "Hello World!"))) “back end” implementation file for each target FFI (gtk:container-add w b) (lambda-gtk-openmcl.lisp, lambda-gtk-cmucl.lisp, and (gtk:container-set-border-width w 10) so on). The translation program uses only a very modest (g:signal-connect w "destroy" set of features from its host Lisp environment and is (g:callback bye) (g:nullptr)) easily portable to any Common Lisp and reasonably (gtk:widget-show-all w) featured Scheme. λGTK currently generates GTK (gtk:main))) bindings for three different Common Lisp on two different operating systems: Figure 1. The canonical “Hello World!” in λGTK. • OpenMCL 0.14.2-p on PPC/Darwin • SBCL [9] 0.8.16 on x86/Linux 4. COMMON MUSIC and λGTK • CMUCL [10] 19a on x86/Linux

Two additional ports, to CLISP [11] on Windows XP λGTK provides Common Music with a portable and Guile Scheme [12] on x86/Linux, are in progress. graphics layer that behaves identically across different Lisp implementations and operating systems. Because 3. λGTK FEATURES λGTK is so new, the current release of Common Music contains only two GUI programs: a data visualization tool called Plotter, and a front end window, called The generated interface provides the following features CMIO, that facilitates algorithmic generation of musical to Common Music: material to and from the supported sound synthesis • Source portable GUI programming across the applications. These two windows are full-featured supported Lisp environments. interfaces and require entry points into most of the libraries, from high-level GTK widget sets to low-level • Automatic conversion between Lisp data types GDK drawing primitives and GLIB event/signal (booleans, numbers, strings) and their equivalent handlers. CM’s graphics code requires no compile time types in GTK. Function arguments that involve C conditionals to account for any differences between the bindings. Just as importantly, since the bindings are level, top-down view of the system's complete IO generated, additional entry points into the GTK libraries capabilities, which means that new users can acquaint can be included in the future without any additional themselves with the overall design of the CM system work by the author as GUI tools are added and quite quickly. CMIO windows also offer the new user a developed. structured alternative to evaluating input and output expressions inside the Lisp read-eval-print loop (REPL). 5. CMIO The CMIO window performs its own Lisp error handling and, by default, reports Lisp errors without triggering the Lisp debugger. This more “gentle” The CMIO (Common Music Input/Output) window approach to error handling allows novice users to (Figure 2) provides a graphical “front end” for Common experiment with algorithmic composition and sound Music. Its primary purpose is to facilitate the most rendering examples with little or no prior experience common compositional activities apart from algorithmic with Lisp, without having to deal with input and output design: configuring synthesis and playback options and command evaluation inside Lisp’s development REPL. generating musical event data to-and-from the supported sound synthesis and display applications. In addition, the CMIO window provides users with a concise, high-

Figure 2. The CMIO window with the MIDI files page selected as the current target.

• A Status line displays color-coded messages about 5.1. Window Layout ongoing actions in the window.

The CMIO interface consists of four GUI components Each tabbed page in the window contains a set of fields arranged from top to bottom in the window: representing the input/output features of a given application or task. The right-justified pages (such as • A Sources notebook holds tabbed notebook pages Help or Systems) control more general features of the that relate to creating and generating event data. window or the surrounding Lisp environment. Color • A Targets notebook holds tab pages related to highlighting provides visual clues as to how sound synthesis and display applications. information on a page is interpreted by the interface: • An Executive frame manages the system's current working directory and current target file. • Blue labels mark fields that must contain information before a page can execute. • Yellow backgrounds mark fields that will be the window. A display's basic visual characteristics are explicitly evaluated by Lisp when the information controlled by axis objects that determine which slots in is accessed. the data sets are plotted and how these values will be • White backgrounds indicate fields that contain mapped to the display's presentation. Each axis can either uninterpreted text or else are read by Lisp to control up to two slots of data, so a total of four slots produce a value. It is possible to force evaluation in of interest can be viewed as the horizontal, vertical, a white field using the notation #.expr, where expr width, and height properties of the graphic points drawn is a Lisp expression that, when accessed by the in the window. The user assigns axis slots when the interface, will be evaluated to produce the contents window is created and may change the slot assignments of the field. after the window is open. Since the slot assignments are • The Status line uses colors to classify the type of the only connection between the display’s presentation message displayed: green text represents normal and the data, Plotter is capable of graphing any object information, yellow indicates a warning or represented in the CLOS object system. notification, and red signifies an error condition. Within a single display each data set is drawn in its own layer. Plot editing takes place on the front-most 5.2. Using the CMIO Window layer; background layers can be brought forward by clicking on their points or by selecting the layer from a To render musical events to a sound application, the pop-up menu. Layers can be made transparent, invisible user selects and configures the target's application page or opaque. If a layer is transparent then the data sets then enters an event expression in the Events buffer and behind it are also visible. If a layer is made invisible clicks the Compose button. Each target application page then its data will not appear in the display until it is has numerous fields for customizing its specific IO explicitly made visible again. Depending on how the behavior. These fields can be set in the GUI and also display axes are defined, each layer can switch between initialized to the user’s preference when the window is six basic viewing styles: Line and point, Line, Point, created. The exact set of sound applications (labeled Bar, Box and Bubble. An additional Notation view is targets in the window) that are available at any given currently under design. time depends both on what programs are installed on the host computer and what software systems have been 6.2. Plotter Tool Windows loaded into Lisp. These sound systems do not need to be configured ahead of musical experimentation; the Plotter Tool windows facilitate specific tasks when window's Systems and Files pages permit external working in a Plotter display. Tool windows belong to software applications such as CLM, CMN and the Potter they affect and are automatically closed when Midishare to be dynamically configured and loaded at the Plotter window itself is closed. There are currently any appropriate point in the working process. three tool windows defined: Sizing, Zooming, and the Editing tool. These windows all operate interactively; 6. PLOTTER changing a setting on them immediately updates the main window display without having to click an OK or Cancel button. The Sizing tool allows the size and style Plotter is a graphical tool for displaying, editing and of points and lines to be controlled. The Zooming tool sequencing musical data. This data can be passed to a allows both Zoom to Fit and percentage zooming from Plotter window in two different external formats: lists .25% to 400%; zooming can be applied to either or both of xy breakpoint values and lists of CLOS [13] objects. axes independently and can affect the size of lines and When breakpoints are specified the window becomes a points or not. full-featured envelope editor for creating breakpoint The Editing tool contains three tabbed displays: collections for use in shape-based composition and Cursor Mode, Selecting, and Mouse Control. The sound synthesis (Figure 3). When lists of CLOS Cursor Mode page toggles between four possible editing objects are passed to a Plotter window it can serve as a modes: Select Points, Select Regions, Add Points and generalized music sequencer for searching, editing, Delete Points. Each mode is indicated by an appropriate creating and playing back musical material (Figure 4). cursor in the Plotter display. The Select points pages Any number of Plotter windows can be open at the allows selection expressions to be evaluated. This is a same time, and copy/pasting between windows is very powerful editing feature because it enables only supported. It is also possible to manipulate Plotter those points for which an arbitrary predicate test returns windows (and the data inside them) by calling Plotter’s true to be selected for editing. The Mouse Controls tab API functions remotely from the Lisp REPL process. allows various aspects of mouse behavior to be controlled, including the ability for the user to set an 6.1. Displays, Axes, Layers and Points Add Points hook (function) that will be called whenever a point is added by a mouse click the display. The hook A Plotter window provides a two-dimensional view function can return whatever objects it wants to. Hooks onto one or more sets of point data. Point sets are to compute chords by FM synthesis and ring grouped into displays where each display defines a modulation are provided by Common Music. particular mapping of data to its graphic presentation in Figure 3. A plotter display containing three breakpoint envelopes.

Figure 4. A plotter sequencer display containing two layers of microtonal MIDI data. [3] Clinger, W., Kelsey, . and Rees, J. (eds.), 7. FUTURE DIRECTIONS “Revised (5) Report on the Algorithmic Language Scheme”, Higher-Order and Symbolic Computation, August 1998. 11(1). The λGTK graphics layer is essentially complete. Future directions include porting the layer to CLISP on [4] “GTK+ The Gimp Toolkit”, Reference Manual Windows XP, and to Guile Scheme on Linux. The web page, process of designing interface tools for Common Music < http://developer.gnome.org/doc/API/2.2/gtk >. has just begun and will be the central focus of software development for some time. Future plans include [5] Taube, H. Notes from the Metalevel, an implementing a pattern editing tool, a Common Introduction to Algorithmic Composition. Practice notation view for Plotter data, and a Code Tayor and Francis, London, 2004. editor for experimenting with musical algorithms. [6] Momar, M. “LGTK – GTK bindings for Common Lisp”, Project home page, 8. CONCLUSION < http://common-lisp.net/project/lgtk/ > .

Common Music is an algorithmic composition system [7] Hansen, L. “FFIGEN Manifesto and that runs in a variety of Lisp implementations and Overview”, Web page, operating systems. Its highly portable code base has, < http://www.ccs.neu.edu/home/lth/ffigen/manife until now, limited users of the system to text-based sto.html >. interactions. λGTK is a new graphics layer for Common [8] Byers, G. “OpenMCL Common Lisp”, Project Music that supports GUI design using the popular GTK home page, widget libraries. GTK code is generated from GTK’s λ < http://openmcl.clozure.com/index.html >. header declarations in order to simply many implementation and porting issues. Despite its recent [9] Rhodes, C. et al. (developers). “Steel Bank development, the new graphics layer already supports Common Lisp”, Project home page two full-featured GUI tools that are source portable < http://www.sbcl.org/ >. across three different Lisp implementations and two operating systems. Future plans include porting λGTK [10] Cracauer, M. et al. (developers). “CMUCL: a to CLISP on Windows XP and Guile Scheme, and to high-performance, free Common Lisp continue developing new GUI tools for algorithmic Implementation,” Project home page, composition in Common Music. http://www.cons.org/cmucl/ . [11] Haible, B. and Steingold, C. “GNU CLISP”, 9. REFERENCES Home page, < http://clisp.cons.org >.

[1] Taube, H., “Common Music: A Music [12]“Guile Scheme, Project GNU’s extension Composition Language in Common Lisp and language”, Home page, CLOS”, Computer Music Journal, 1991. < http://www.gnu.org/software/guile/ >. 15(2): p. 21-32. Steele, G., Common Lisp the [13]Keene, S. Object-Oriented Programming in Language, 2nd edition. Digital Press, Wobern, Common Lisp: A Programmer’s Guide to 1990. CLOS. Addison-Wesley, Reading, 1989. [2] Steele, G., , 2nd edition. Digital Press, Wobern, 1990.