The most important component of the Rubato system is undoubtedly the Rubato language. It is essentially the user interface to the Rubato system. This chapter of the thesis describes the goals, assumptions, design approaches and decisions taken leading to the specification of the Rubato language.
The following goals were instrumental in the shaping of the nature of the Rubato language:
The language should be loosely based on the structural organization, abstract concepts and principles of CMN, i.e. it should employ many of the same abstractions (the quantization of the musical stream into notes with psychoacoustical properties such as pitch, rhythm, loudness and timbre being a primary CMN concept that must be retained by the language). The rationale behind this goal is to minimize the effort required to code musical pieces written in CMN. Ideally, there should be an injective relationship between entities and concepts in CMN and their equivalent counterparts in the language and it should be possible to transcribe musical pieces in CMN directly into the language with minimal effort and by following a few simple rules.
The language should allow the encoding of as many CMN concepts as possible, if not in the same style and conventions, then at least in the same principle. In particular, the language should permit easy and painless specification of articulation marks, dynamics (including continuous dynamic specifications such as crescendo and ritartando), rhythmic stresses, key, meter and time signatures, barlines and various other notational devices of CMN traditionally ignored by computer music input languages. Any notation in CMN not explicitly handled by the language should be easy to simulate within the language by the user through devices resembling macros or procedures in computer programming languages. The purpose of this goal is to enlarge the class of music specifiable in the language as wide as possible.
In spite of the above goals, the language should be mainly a typographical language, i.e. it should be possible to encode a piece of music as a sequence of alphanumeric and special characters commonly available on a typewriter keyboard. This allows music pieces to be coded on a simple computer terminal without special music input facilities or a graphical user interface. The reason for this is to allow the language to be implementable across a wide variety of computer hardware and operating systems. The benefits of a graphical based language is heavily outweighed by the special hardware and software requirements necessary to support a graphical interface.
The language should encode musical pieces as compactly as possible, to minimize the time required to code musical pieces as well as the number of keystrokes required to represent a particular musical entity. A compact representation is also beneficial in that it requires minimal storage within the computer.
The language should allow a hierarchical organization of components in a musical piece when coded in the language representation. This parallels the (implied) concept of hierarchy in CMN. Traditionally, large pieces of music are broken up into smaller and smaller components such as movements, sections, themes, melodies, motives, phrases down to the individual notes. The representation of a musical piece in the language should mirror the piece's internal hierarchical organization as far as possible. The hierarchical organization should be flexible enough to allow common sections in the hierarchy, e.g. a phrase or melody interspersed throughout the piece across sections, to be represented or stored only once. Future invocations of a previously specified section of a piece should be easy to perform.
Hierarchical levels within a music piece should be nameable in the language, i.e. it should be possible to assign a sequence or characters forming a word to any component of the music. Specifying the name at a later stage should invoke the section of the music assigned to the name. Name assignment in the hierarchical structure should be nestable rather like declaration nesting in block-structured languages such as Algol or Pascal. In particular, a local assignment of a name to a musical structure should be visible to all lower layers of the hierarchy but invisible to the higher layers. This allows different sections of a piece to assign the same name to different structures independently without the concern that one assignment may overwrite the other.
The language should be inherently concurrent, i.e. it should be possible to specify sections which will be performed simultaneously. Music is not usually considered as a linear stream of notes but rather a set of note streams operating in parallel. This is exemplified in pieces written for a sympony orchestra. During the performance of a symphony, for example, each member of the orchestra can be considered a process that spews out musical notes independently of the other performers and yet the collection of independent players form a joint entity that can bring pleasure to a listener's ears. Often, performers share a musical part, such as members of the cello section often play a common phrase in unison. This can be likened to processes which are separate instances of a single process specification.
This is major difference between the new language and most of the other computer music input languages.
Typically, a computer music input language forces a piece of music with many parts to be encoded into a sequential stream which is processed sequentially. The language should allow each musical part to be specified separately, together with a notation to bind the separate pieces so that they will be performed simultaneously. Hence, the language can take advantage of upcoming parallel computer architectures because of its inherent concurrency. The implementation of the interpreter and player on a typical sequential computer entails time-sharing the computational power of the computer between active entities in the music in a round-robin fashion.
Finally, musical pieces written in the language should be aesthetic and pleasing to look at. To achieve this goal, the language may have to allow free-form input, i.e. spaces and blank lines and the typographical format of elements of the language are not syntactically significant.
In designing the language, some assumptions about the nature of music and the structure of musical pieces were made and these assumptions guided the approaches taken and the design decisions made. The assumptions may not be correct or even generally valid, but it is hoped that they are at least consistent and prove to be useful.
Music is composed of notes which are locally homogeneous. Locally within a piece, all notes typically lie relatively close to one another in pitch, and are usually similar in other attributes. For example, all notes in a phrase or melody are likely to be spaced equally apart in time and have the same duration, loudness, timbre, etc. A language that exploits this feature will simplify the keying in of musical phrases because the attributes of a note which are common across a phrase need only be specified for the phrase rather than for each individual note. Similarly, a group of phrases may possess similar attributes in the same way that notes do. Hence, the savings achieved can be replicated up the hierarchical structure.
Most musical pieces will repeat portions of themselves. Indeed, certains parts or types of music will often repeat endlessly, possibly with variations or in juxtaposition with another section which may not repeat at all. Even in cases where the melody does not repeat, the rhythmic pattern of the notes may be replicated. Repetition of musical sections are often intimately linked with the hierarchical structure of the musical piece. The language should be able to handle repetitions in form as well as content intelligently.
The performance of a musical piece can be likened to the sequential execution of a computer program. For instance, when a piece of music is being composed or performed, there is often an acute awareness in the mind of the composer or performer of the 'flow' of the musical piece with respect to time. This flow of a musical piece can be diverted within CMN using repetition marks and there are even constructs directly analogous to control flow statements in programming languages such as goto or if..then..else! Hence, the flow of music is very similar to the flow of execution within a computer program. A language for representing music should therefore be algorithmic and possess iteration and control flow primitives akin to the control flow statements available in a typical computer programming language.
The concepts used in Rubato are often just as applicable to other areas of real-time control systems as it is to music representation and performance. While the language should not be designed as a general purpose real-time control language, the design of the language must be flexible enough to allow the language to be used for nonmusical applications. To this end, there must exist alternative means of event specifications that do not correspond to CMN. For example, there should be at least two different ways of specifying the pitch of a note. It can either be specified as a key which is relative to the current key signature and the current octave, or as an absolute pitch number which corresponds to the number that will be sent out by the interface when playing the note. Similarly, the duration of a note can be specified as a time period which is relative to the current musical tempo, or as an absolute time interval.
With the previous goals and assumptions at hand, an initial design of the language was completed. The language was then modified and the design phase was reiterated until it was felt that the language was in a stable enough phase for a lexical analyser and parser to be constructed. It was found that the design often had to be modified in order to simplify the lexical analyser and/or parser. However, any modifications made were mostly cosmetic. Hence, by the time the specification of the language was drawn out, a rudimentary parser existed which could traverse through sample music representations written in the grammar of the language.
The following concepts were the result of the approaches examined during the design phase of the language:
The language views a musical stream as a sequence of notes possessing attributes. Each note must possess a pitch, along with attributes such as delay, duration, velocity, patch and channel. These attributes will be fully discussed in the chapter entitled A Specification of the Rubato Language, but it suffices for now to view notes as event specifications with each attribute of a note regarded as a dimension on which the note may be placed.
When defining a note, the only attribute that needs to be specified is the pitch. All other attributes will take on default values if not specified. The use of default attributes is a means of allowing note representations to be more compact then they would normally be. Since the default values do not change from note to note unless done explicitly, note specifications are largely context free and independent of one another.
There are two fundamental groupings of notes. A phrase is a collection of entities (such as notes) that will be played sequentially, one after another. In a sense, the 'execution' of a phrase will yield a melody or a musical phrase. A chord is a collection of entities that will be played simultaneously. These are the two fundamental 'building blocks' of hierarchy in the Rubato language. Phrases and chords may be nested, containing other phrases or chords. The Rubato language also allow phrases and chords to possess attributes which become the default attributes for all entities within the phrase or chord. Phrases in the Rubato language are analogous to subroutine calls in a programming language and chords are analogous to a primitive that spawns new processes in concurrent programming languages.
Within a phrase, execution proceeds sequentially unless a control flow statement is encountered which may or may not divert the 'execution flow' within the phrase. Control flow statements are similar to those in programming languages. There are iterative control flow statements as well as conditional statements.
Next: Chapter 3: LITERATURE REVIEW
Previous: Chapter 2: GENESIS AND METAMORPHOSIS
Back to: Table of Contents