Generating Music Notation in Real Time
Listing 3. Configuration Variables
# No Clergy config.txt, written by script tupletpc = 50 restpc = 25 dynpc = 25 artpc = 25 number_of_measures = 20
The scripts then generate a full Score's worth of musical material, constrained by the variables above. At this point, all of these data still exist only as Lists of Objects within a Python script. I chose MusicXML as the format for external storage.
MusicXML is a subset of XML specifically geared toward musical data. Developed by Recordare LLC, it is largely geared toward being an interchange format for music notation programs. It is also useful, however, as a generic storage format for musical data, as befits a dialect of XML.
Listing 4. Sample MusicXML Fragment for One Note
<note> <pitch> <step>b</step> <alter>-1</alter> <octave>3</octave> </pitch> <duration>16</duration> <type>sixteenth</type> </note>
Musicians probably can figure out that this XML fragment represents a 16th note B flat in the third octave with no dynamic, articulatory or other special alterations.
The script stores the most recent MusicXML file for each instrument using the path convention inst/yyyy_mo_dd-hh_mi_ss.xml, where inst is the instrument name and other letter codes are time units. Upon reading an XML file, the script then moves it into a backup directory and compresses it with bzip2. Storage of old data is useful for documentation of specific performances, learning how audiences react to their role in the piece and debugging. Once the script has read in the XML data, it's ready to output for processing by Lilypond.
GNU Lilypond is a Scheme-based music typesetting program that uses a TeX-like backslash notation for formatting commands and has a particular focus on high-quality music engraving inspired by the best traditional hand engraving. It outputs to several high-resolution formats, including PostScript, DVI and PNG.
Listing 5. Sample of Lilypond Markup
| % MEASURE 2 \time 7/8 ef''8-\pp a'4 d'2-\marcato
In Listing 5, we see Lilypond markup for one measure of music. The vertical pipe represents a barline, the % MEASURE 2 is a comment, the \time indicates the 7/8 meter, the ef makes the first note an E flat, the '' raises the note two octaves higher than the baseline used by the program, the 8 gives the note a rhythmic value of an 8th note and the -\pp attaches a pianissimo dynamic indicator to the note. Two other notes follow. The measure is rendered as shown in Figure 2.
The storage of semantically meaningful musical data in MusicXML and presentation data in Lilypond markup mirrors the trend in the HTML or DocBook worlds, where structural information is kept independent of the final rendering. As a side benefit, these scripts also are useful in a pinch as a MusicXML to Lilypond to dvi/ps/pdf converter.
During the performance, the audience can and should input data that will direct the future course of the music. I wanted to use a GUI interface for the audience. The piece uses bash scripting as a glue language, but all of the real work is done by Python, making the various Python GUI options obvious candidates. For several reasons, I chose a Web browser interface with CGI forms for data input. What are the advantages of a Web interface over a Python-based GUI?
Web browsers are ubiquitous, among the most commonly used user applications in the world. Rather than requiring an installation of an X client and Python with GUI libraries and then needing to work out OS-specific issues, I simply can require performance sites to have machines with Web browsers—a trivial request.
It is largely due to browsers' ubiquity that they also are familiar. Self-described novice computer users are often far more comfortable operating a browser than some new GUI interface they've never seen before. In fact, even though page layout rendering of HTML often differs a great deal from one instance to another, it feels familiar to the user. This comfort level is especially critical for a performance situation like mine, where the audience needs to get over a natural reluctance to participate actively in a process traditionally reserved for the performers.
In addition, HTML is easy to code. Rob Pike's Rule 4 states that “fancy algorithms are buggier than simple ones”, and straightforward markup usually is even simpler. More information about the benefits of thin-client designs like this can be found in Hugh Williams and David Lane's Web Database Applications, published by O'Reilly and Associates.
Using a browser interface has clear drawbacks, but luckily, none are particularly relevant to my project. HTTP is slow, but I need to update only once per page of music, no faster than about once per minute. HTML/CSS style is relatively inflexible, but my design needs are simple. Video is problematic for pure HTML presentation without plugins that often are proprietary, but I need only still images.
Given that we have a browser interface and hopefully a participating audience, we need to process their data. I use a Python CGI script to capture variables. It writes values within a <pre> tag, values that the later processing script reads in order to do the actual modification of musical data. This generic, extensible setup means that the capturing script needs little to no alteration as I improve the piece's other scripts by adding variables or changing how they are interpreted at other stages in the piece.
- Readers' Choice Awards 2014 Poll
- Give new life to old phones and tablets with these tips!
- Tech Tip: Really Simple HTTP Server with Python
- Linux Systems Administrator
- Memory Ordering in Modern Microprocessors, Part I
- Senior Perl Developer
- Source Code Scanners for Better Code
- Technical Support Rep
- RSS Feeds