Generating Music Notation in Real Time
Listing 6. Script Fragment to Capture User Data
import cgi, re form = cgi.FieldStorage() formS = '<pre>\n' for field in form: formS += field + ' = ' formS += form[field].value + '\n' formS += '</pre>\n'
The script then inserts the formS string at the appropriate point within the feedback file. The variables are integers representing percentage chances that a given note will have a given characteristic. I chose to list the values within <pre> tags to allow easy observation of changes to variables during a performance using a Web browser. The scripts always write the most recent data immediately after a <!-- begin --> comment.
In addition to the audience data variables, the processing script also incorporates a second-order Markov chain (see the “Markov Chains” sidebar). This allows all pages of music after the first to share characteristics of the first page while still being shaped by the audience feedback.
Markov Chains, named after Russian Mathematician A.A. Markov, are ordered collections of data based on samples. For each set element x, we find all transitions from it to any element, including a repetition of itself. From those data, we find the probability that x leads to each element that follows it. We then can use those probabilities to reconstruct a randomly generated set that resembles the source set without necessarily being identical to it.
The user then continues to run the noclergy.py script for as long as desired. Another wrapper shell script could keep the piece running until a specific condition is met, such one of the pc variables reaching a given minimum or maximum. It also could have a set number of iterations. It even could run as a long-term installation. No performer relishes the thought of sitting for eight or more hours and playing whatever appears on a screen in front of him or her. Therefore, for very long runs, I should alter the program such that it does not require performers. One option would be to output to a synthesizer such as Csound. Another option would be to display the notation for visual demonstration only.
Future plans for this project include a port to the Ruby language. This is mainly for self education, but there are other reasons. Ruby code tends to be more compact—the advantages of features like the each method add up with enough code. In informal benchmarking, I've also found Ruby faster than Python for some tasks. I'd like to test this more scientifically, with and without Python bytecode optimization. Finally, by porting, I'll learn both Python and Ruby better—always a good thing.
As mentioned previously, the scripts store previous runs of the piece in the MusicXML format. There is no reason that other music in that same format couldn't be run through the script. By using other source music, the mutate.py script can create Markovian blends of Charlie Parker and Bartok, or whatever suits the user's tastes.
Finally, here's some technical trivia that may interest readers. I achieved much faster XML access when I did “dumb” file/string readline operations with my own convention for placement of \n characters. Conversion to standard DOM-aware XML libraries slowed the program down noticeably but made it both more robust and more usable by others. For a while, I even kept both versions of XML reading available. Eventually, I decided to use only the DOM-based reading, even thought it has become the slowest portion of the script by far.
In the end, I felt that arguments for using an HTTP-based audience interface had merit for the XML access issue. Using the standard DOM library made the script available to a wider user base. The XML read runs fast enough for usability today and will be even faster in the future with faster hardware. Therefore, I decided to comply with existing standards in the interest of robustness.
I plan to have a performance at the University at Buffalo in late 2004. Obviously, the program's collision with a real-world test should provide a great deal of useful information about how to improve it. The specifics of the performance are still in question, but I may try to use wireless browsers for the audience, which I hope will provide a less intimidating interface for them and will improve the overall experience for both performers and audience members.
Resources for this article: www.linuxjournal.com/article/7815.
Kevin Baird is pursuing a PhD in Music Composition at the University at Buffalo in Buffalo, New York. He is on-line at kevinbaird.net.
|Speed Up Your Web Site with Varnish||Jun 19, 2013|
|Non-Linux FOSS: libnotify, OS X Style||Jun 18, 2013|
|Containers—Not Virtual Machines—Are the Future Cloud||Jun 17, 2013|
|Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer||Jun 12, 2013|
|Weechat, Irssi's Little Brother||Jun 11, 2013|
|One Tail Just Isn't Enough||Jun 07, 2013|
- Containers—Not Virtual Machines—Are the Future Cloud
- Non-Linux FOSS: libnotify, OS X Style
- Linux Systems Administrator
- Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer
- Validate an E-Mail Address with PHP, the Right Way
- Technical Support Rep
- Senior Perl Developer
- UX Designer
- Introduction to MapReduce with Hadoop on Linux
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?