Annotation of researchv10dc/vol2/music/music.ms, revision 1.1

1.1     ! root        1: .so ../ADM/mac
        !             2: .XX music 477 "Computer Music Under the 10th Edition UNIX System"
        !             3: .nr dP 1
        !             4: .nr dV 1.5p
        !             5: .de FG
        !             6: .ce
        !             7: Figure \\$1. \\$2
        !             8: .SP .5
        !             9: ..
        !            10: .TL
        !            11: Computer Music under the 10th Edition
        !            12: .UX
        !            13: System
        !            14: .AU
        !            15: T. J. Killian
        !            16: .AI
        !            17: .MH
        !            18: .AB
        !            19: We describe an evolving computer music system that draws upon many of
        !            20: the novel facilities in the Research
        !            21: .UX
        !            22: system, as well as the standard repertoire of
        !            23: familiar tools.
        !            24: The Teletype 5620 bitmap display serves both as the user's
        !            25: terminal and real-time controller.  The
        !            26: .I mux
        !            27: window system is used to download a
        !            28: .SM MIDI
        !            29: interface driver that
        !            30: services other windows (by direct code sharing) and
        !            31: host processes (which write on the driver's control stream).
        !            32: We presently support several
        !            33: .SM MIDI
        !            34: devices: the Yamaha
        !            35: .SM DX7 ,
        !            36: .SM TX816 ,
        !            37: .SM FB01 ,
        !            38: and
        !            39: .SM SPX90 .
        !            40: .PP
        !            41: Window programs include a piano-roll-style score facility and a
        !            42: virtual keyboard.  Host programs include a music compiler,
        !            43: .I m ,
        !            44: that converts an
        !            45: .SM ASCII
        !            46: score notation into
        !            47: .SM MIDI
        !            48: events;
        !            49: it is based on
        !            50: .I lex
        !            51: and
        !            52: .I yacc,
        !            53: making it very easy to modify in response to user needs.
        !            54: There are also several filters that perform simple transformations
        !            55: (e.g., time and pitch translation) on
        !            56: .SM MIDI
        !            57: files.  The latter are
        !            58: .SM ASCII ,
        !            59: so that text filters (especially
        !            60: .I awk ,
        !            61: .I sed ,
        !            62: and
        !            63: .I sort)
        !            64: can be used for sound manipulation.
        !            65: .AE
        !            66: .2C
        !            67: .NH
        !            68: Introduction \- the
        !            69: .SM MIDI
        !            70: standard.
        !            71: .PP
        !            72: Computer-music applications have taken off in recent years, largely
        !            73: due to the introduction of the
        !            74: .SM MIDI
        !            75: (Musical Instrument Digital Interface)
        !            76: standard |reference(midi standard).
        !            77: .SM MIDI
        !            78: has made it possible, with very modest hardware,
        !            79: to interface a computer to synthesizers and other equipment, with broad
        !            80: compatibility among manufacturers.
        !            81: A full discussion of the
        !            82: .SM MIDI
        !            83: standard is out of place here; we will simply
        !            84: give some of its essential characteristics.
        !            85: .PP
        !            86: .SM MIDI
        !            87: uses an asynchronous serial protocol at 31.25 Kbaud to transmit \%8-bit
        !            88: data bytes over a \%5-mA current loop (thus, to the programmer, it looks like an
        !            89: .SM RS232
        !            90: line).  Data flow on any given cable is unidirectional.
        !            91: .I Status
        !            92: and
        !            93: .I data
        !            94: bytes are distinguished by the high-order bit being set or clear, respectively.
        !            95: A status byte encodes a
        !            96: .I function,
        !            97: and (usually) a
        !            98: .SM MIDI
        !            99: .I "channel number"
        !           100: in the range 1 to 16.
        !           101: Bytes are grouped logically into
        !           102: .I messages
        !           103: that consist of a status byte and (except as noted below) 1 or 2 data bytes.
        !           104: For example, the \%3-byte message (\c
        !           105: .CW 0x90,\ 0x3c,\ 0x40 )
        !           106: says, ``On channel 1,
        !           107: turn on note number 60 (middle C) with a volume of 64 (mf).''
        !           108: In most cases the size of a message is determined by its status byte, so
        !           109: the latter may be omitted if it is the same as the status byte most
        !           110: recently transmitted.
        !           111: .PP
        !           112: The messages most commonly used in performance, such as those that
        !           113: select a synthesizer's pre-programmed voices, or
        !           114: turn notes on and off, are fixed by the
        !           115: .SM MIDI
        !           116: standard.  An escape mechanism
        !           117: is provided to allow control sequences
        !           118: peculiar to the equipment of a given manufacturer.  This
        !           119: .I "system exclusive"
        !           120: message has the form (\c
        !           121: .CW 0xf0,
        !           122: .I "ident, data,"
        !           123: \&...,
        !           124: .CW 0xf7 ");"
        !           125: .I ident
        !           126: is a manufacturer's code assigned by the standards committee; the
        !           127: .I data
        !           128: is arbitrary (and can be of any length).
        !           129: .PP
        !           130: A device typically has three
        !           131: .SM MIDI
        !           132: sockets, labeled
        !           133: .SM IN ,
        !           134: .SM OUT ,
        !           135: and
        !           136: .SM THRU .
        !           137: Messages received at the
        !           138: .SM IN
        !           139: socket are acted upon in real time if the device's
        !           140: .SM MIDI
        !           141: channel number matches that of the message.
        !           142: In any case, the data are buffered directly to the
        !           143: .SM THRU
        !           144: socket to allow daisy-chaining.
        !           145: An instrument such as a
        !           146: keyboard may send an independent stream of messages to its
        !           147: .SM OUT
        !           148: socket.  A typical
        !           149: .SM MIDI
        !           150: performance consists of (mostly) note-on and note-off messages
        !           151: emitted by the ``performer'' with proper timing.
        !           152: .PP
        !           153: There are several problems with
        !           154: .SM MIDI ,
        !           155: the most serious of which
        !           156: is probably its limited bandwidth.  Chords consisting of, say, ten or twelve
        !           157: notes become noticeably arpeggiated, and changes in timbre that might
        !           158: require a long system-exclusive message cannot be fitted into fast passages.
        !           159: Lack of flow control makes this problem even worse.
        !           160: .SM MIDI
        !           161: is also tightly bound to the twelve-tone Western scale; it is sometimes possible
        !           162: to work around this, again at the expense of bandwidth.
        !           163: .NH
        !           164: The
        !           165: .SM MIDI
        !           166: device driver.
        !           167: .PP
        !           168: Mark Kahrs and I built a
        !           169: .SM MIDI
        !           170: interface board that plugs into the parallel
        !           171: .SM I/O
        !           172: port of the Teletype 5620 bitmap terminal |reference(kahrs 5620).
        !           173: The 5620 has a \%32-bit
        !           174: microprocessor with 1 Mb of memory, and runs the
        !           175: .I mux
        !           176: window system |reference(blit bstj).
        !           177: Using the 5620 as the real-time controller, we are able
        !           178: to place a synthesizer under the control of a host computer
        !           179: (in this case, a
        !           180: .SM VAX
        !           181: 750), without a large amount of systems programming.
        !           182: .PP
        !           183: The
        !           184: .SM MIDI
        !           185: device driver (\c
        !           186: .I midiblt )
        !           187: is down-loaded into a
        !           188: .I mux
        !           189: window, where it takes over interrupt handling on the parallel
        !           190: .SM I/O
        !           191: port.  Three types of interrupts are handled:
        !           192: .SM UART
        !           193: transmitter and receiver ready,
        !           194: and a \%5-msec clock.
        !           195: .SM MIDI
        !           196: data are organized into three queues.  Incoming messages are time-stamped
        !           197: and placed on the
        !           198: .I receiver
        !           199: queue, where they are available to other software.  At clock interrupt, the
        !           200: .I scheduler
        !           201: queue is examined for messages with time less than or equal to the current
        !           202: time; such messages are moved from the scheduler queue to the
        !           203: .I transmitter
        !           204: queue, from which they are sent to the hardware as quickly as possible.
        !           205: .PP
        !           206: There is a sharp division between routines that control the
        !           207: .SM UART
        !           208: directly
        !           209: (and handle single characters)
        !           210: and those that manipulate
        !           211: .SM MIDI
        !           212: messages.  For example, the
        !           213: .SM MIDI
        !           214: transmitter is
        !           215: a finite-state machine that understands things like elided status bytes; it
        !           216: is called by a lower-level routine and produces the next byte to be sent by
        !           217: the
        !           218: .SM UART .
        !           219: .PP
        !           220: Routines that empty the receiver queue and fill the scheduler queue are
        !           221: available from outside the driver.
        !           222: .I Midiblt
        !           223: places their entry points in a name table maintained by
        !           224: .I mux ;
        !           225: since there is no memory mapping in the 5620, they are immediately available
        !           226: to other programs down-loaded in the terminal.
        !           227: This code-sharing mechanism is used to implement a virtual-keyboard program,
        !           228: .I jx7 ,
        !           229: which provides the functionality of a one-fingered mouse-pianist, with slide
        !           230: controls for volume, vibrato, pitch bend, etc.
        !           231: .NH
        !           232: Communication with the host.
        !           233: .PP
        !           234: Host communication takes place via the
        !           235: .I streams
        !           236: mechanism |reference(latest streams).  Briefly, each
        !           237: window is associated with a host control stream managed by
        !           238: .I mux ;
        !           239: when a program down-loaded in the terminal does a read or write,
        !           240: .I mux
        !           241: performs the appropriate operation on the stream associated with the window.
        !           242: The program at the other end of the stream can be the shell
        !           243: (this is how multiple virtual terminals are implemented), or a special-purpose
        !           244: program (as in the case of a text editor).
        !           245: .I Midiblt
        !           246: falls into the second category.  It mounts
        !           247: its stream under the name \&\c
        !           248: .CW .MIDI
        !           249: in the
        !           250: user's home directory, in effect
        !           251: creating a character-special file for the
        !           252: .SM MIDI
        !           253: driver.  The terminal side of
        !           254: .I midiblt
        !           255: reads characters as they appear from the host, assembles them into
        !           256: .SM MIDI
        !           257: messages, and places the messages on the scheduler queue.  (The host side of
        !           258: .I midiblt
        !           259: does not look at this data; error correction and flow control are performed by
        !           260: .I mux ).
        !           261: .PP
        !           262: We have followed a time-honored
        !           263: .UX
        !           264: tradition by formatting the
        !           265: .SM MIDI
        !           266: file in
        !           267: .SM ASCII .
        !           268: Such a file consists of a series of lines, one per
        !           269: .SM MIDI
        !           270: message.
        !           271: Each line is a sequence of blank-separated decimal numbers, viz.: event time
        !           272: (msec), status byte, and data.  (Backslash-newline can be used
        !           273: to break long system-exclusive messages.)
        !           274: In this form, the entire panoply of
        !           275: .UX
        !           276: text-processing tools can be
        !           277: brought to bear in rough-and-ready fashion.
        !           278: .PP
        !           279: On the other hand, this format is not well
        !           280: suited for direct transmission to the 5620, since bandwidth is at a premium.
        !           281: The program
        !           282: .I midi ,
        !           283: which compresses the data, is used; it replaces (and has similar semantics to)
        !           284: .CW "cat >.MIDI" .
        !           285: In addition,
        !           286: .I midi
        !           287: attaches itself to the
        !           288: .I "process group"
        !           289: associated with the \&\c
        !           290: .CW .MIDI
        !           291: stream.  This allows the
        !           292: .I midiblt
        !           293: window to send signals to the
        !           294: .I midi
        !           295: process so that, e.g., if the user does a reset from the
        !           296: .I midiblt
        !           297: menu, there is proper coordination between the host and the driver.
        !           298: .PP
        !           299: The
        !           300: .CW "midi | midiblt"
        !           301: pattern is repeated in the programs
        !           302: .I score
        !           303: and
        !           304: .I scoreblt ,
        !           305: which produce a pitch vs. time graph.
        !           306: .I Scoreblt
        !           307: manages a terminal window and draws the display.  Through the code-sharing
        !           308: mechanism mentioned earlier, it has access to
        !           309: .I thinkblt
        !           310: which drives a HP ThinkJet dot-matrix printer.
        !           311: .NH
        !           312: Synthesizer control.
        !           313: .PP
        !           314: The system described was first used to run a Yamaha
        !           315: .SM DX7
        !           316: and, later, a
        !           317: .SM TX816 .
        !           318: Both produce sound via
        !           319: .SM FM
        !           320: synthesis |reference(chowning), a voice being described
        !           321: by around 100 (digital) parameters, all settable by system-exclusive
        !           322: .SM MIDI
        !           323: messages.  The
        !           324: .SM DX7
        !           325: has internal memory for 32 pre-loaded voices that can be
        !           326: selected by number (via the
        !           327: .SM MIDI
        !           328: .I "program change"
        !           329: message).  It is a keyboard instrument with additional controls for
        !           330: editing voice parameters (the current voice, whether internal or downloaded,
        !           331: is always copied into an editing buffer).
        !           332: Although the
        !           333: .SM DX7
        !           334: is limited to playing in one voice at a time,
        !           335: up to 16 simultaneous notes can be produced.  The
        !           336: .SM TX816
        !           337: is a rack-mounted
        !           338: unit consisting of eight
        !           339: .SM TF1 "'s."
        !           340: Each
        !           341: .SM TF1
        !           342: is essentially a
        !           343: .SM DX7
        !           344: without keyboard, and
        !           345: can be set to a different
        !           346: .SM MIDI
        !           347: channel, so that
        !           348: orchestral and multi-track effects are possible.
        !           349: .PP
        !           350: A number of C programs are used for synthesizer configuration.
        !           351: .I Txchan
        !           352: assigns channel numbers to the
        !           353: .SM TF1 "'s."
        !           354: .I Mecho
        !           355: is used to send ``constant'' data (such as to select an internal voice, or
        !           356: alter single parameters of a voice).
        !           357: .I Dxvoice
        !           358: downloads voice data from a library file on the host.  Figure 1 is an example
        !           359: of a shell script that sets up the
        !           360: .SM TX816
        !           361: with five instruments, one of which
        !           362: (the harpsichord) uses two
        !           363: .SM TF1 "'s"
        !           364: in parallel.  The violin voice needs to be
        !           365: downloaded; the rest are already stored in the proper
        !           366: .SM TF1 "'s"
        !           367: (they came from the factory this way).
        !           368: Percent signs delimit comments to
        !           369: .I mecho .
        !           370: .1C
        !           371: .KF top
        !           372: .P1
        !           373: txchan 1 1 3 4 5 6 7 8
        !           374: mecho  init \e
        !           375:        prog    -c1 28          % harpsichord chan 1    % \e
        !           376:                -c4 3           % reeds chan 4          % \e
        !           377:                -c6 24          % flute chan 6          % \e
        !           378:                -c8 3           % bass pipes chan 8     % \e
        !           379:        dx      -c8 p144 24     % move up an octave     % \e
        !           380:        parm    -c4 p4 127      % foot control reeds    % \e
        !           381:                -c6 p2 127      % breath control flute  % \e
        !           382:                -c8 p4 127      % foot control pipes    %
        !           383: dxvoice        -c3 -v2 tx816.8         # solo violin chan 3
        !           384: .P2
        !           385: .FG 1 "Setting up the TX816"
        !           386: .KE
        !           387: .2C
        !           388: .PP
        !           389: This scheme is complete in that it allows access to any
        !           390: .SM MIDI
        !           391: or
        !           392: .SM DX
        !           393: parameter,
        !           394: but it is not altogether satisfactory.  The user must know, for example, that
        !           395: voice 3 is ``reeds'' in the fourth unit, but ``bass pipes'' in the eighth.
        !           396: Simply assigning names to numbered parameters does not reduce the complexity,
        !           397: however.  Ideally, one would like an interactive ``orchestration editor''
        !           398: supported by a large database.
        !           399: .1C
        !           400: .KF bottom
        !           401: .P1
        !           402: main()
        !           403: {
        !           404:        int c, x, y, z, magic = 13, size = 64;
        !           405:        int mask = 2*size-1;
        !           406:        for (c = z = 0; c <= mask; c++, z += magic)
        !           407:                for (newfile(), y=0; y < size; y++)
        !           408:                        if ((x = (y ^ z) & mask) < size)
        !           409:                                play((x+y), (x-y));
        !           410: }
        !           411: .P2
        !           412: .FG 2 "Munching squares"
        !           413: .KE
        !           414: .2C
        !           415: .NH
        !           416: Musical examples in C and the shell.
        !           417: .PP
        !           418: The first piece to be played on our system was written by Cynthia P. Killian
        !           419: using a combination of C and the Bourne shell.  The composer took
        !           420: raw material produced by the ``munching squares'' algorithm and manipulated
        !           421: it by splicing and dubbing techniques.  Figure 2 shows the heart of the algorithm.
        !           422: .I X
        !           423: and
        !           424: .I y
        !           425: trace out short diagonal segments, which are rotated by 45 degrees and passed to
        !           426: .I play .
        !           427: The resulting vertical coordinate is mapped onto a tone row, and the length of
        !           428: the segment (as determined by a sequence of points at the same height) determines
        !           429: the length of time the tone is held.
        !           430: .I Newfile
        !           431: breaks the output into separate small files (\c
        !           432: .CW smunch.\fI?? )
        !           433: for convenience.  The
        !           434: latter are then processed by shell scripts like that shown in Figure 3.
        !           435: The unfamiliar commands in the script are either shell scripts or trivial C
        !           436: programs.
        !           437: .I Sed
        !           438: and
        !           439: .I "sort\ \-n"
        !           440: form the basis for cutting and pasting.  Operators that do a lot of arithmetic
        !           441: (e.g,
        !           442: .I retro ,
        !           443: which time-reverses its input) are written in C.  The shell syntax for
        !           444: operator precedence and the semantics of the
        !           445: .UX
        !           446: filter are extremely
        !           447: well matched to this application.
        !           448: .1C
        !           449: .KF
        !           450: .P1
        !           451: (divider <smunch.06 3 4; divider <smunch.07 1 2
        !           452:  divider <smunch.07 1 2 |
        !           453:   invert 0 1120 0 | retro) | ttrans 0 280 >tmp$$
        !           454: (cat tmp$$
        !           455:  divider <smunch.08 7 8) | ttrans `endtime <tmp$$` -1260
        !           456: rm tmp$$
        !           457: .P2
        !           458: .FG 3 "Shell script for processing munching squares"
        !           459: .KE
        !           460: .KF bottom
        !           461: .P1
        !           462: /* Inventio 4 (BWV 775) */
        !           463: 8 = 120                /* tempo: 120 eighth notes/min  */
        !           464: 3 / 8          /* time signature               */
        !           465: {
        !           466: treble : 1     <      6(16)         | 6(16)         >
        !           467:                | F60: d3 e f g a b@ | c# b@ a g f e |
        !           468: bass : 1       <      4.            | 4.            >
        !           469:                | F60: r             | r             |
        !           470: 
        !           471: treble < 3(8)          | 3(8)          | 6(16)        >
        !           472:        | f    a   d4   | g3    c4# e   | d e f g a b@ |
        !           473: bass   < 6(16)         | 6(16)         | 3(8)         >
        !           474:        | d2 e f g a b@ | c# b@ a g f e | f   a   d3   |
        !           475: \&...
        !           476: }
        !           477: .P2
        !           478: .FG 4 "The beginning of a Bach invention"
        !           479: .KE
        !           480: .2C
        !           481: .NH
        !           482: The M language.
        !           483: .PP
        !           484: The need for a closer tie with standard musical notation led to the development
        !           485: of the M language.  We will try to give a feel for the language with a short
        !           486: example shown in Figure 4.
        !           487: .PP
        !           488: An M file consists of ``front matter'' followed by text enclosed
        !           489: in matching curly braces.  The comment convention is similar to C's,
        !           490: except that comments nest.
        !           491: The music is divided into
        !           492: .I lines
        !           493: formed by a
        !           494: .I "voice name" ,
        !           495: an optional colon and
        !           496: .SM MIDI
        !           497: channel number, a
        !           498: .I "rhythm list" ,
        !           499: and corresponding
        !           500: .I "note list" .
        !           501: Voice names are arbitrary alphanumeric strings.
        !           502: Within rhythm and note lists,
        !           503: measures are delimited by barlines.
        !           504: A rhythm list consists of
        !           505: .I "time values"
        !           506: (\c
        !           507: .CW \%1 "\&\ =\ whole note,"
        !           508: .CW \%2 "\&\ =\ half note,"
        !           509: .CW \%4 "\&\ =\ quarter note,"
        !           510: .CW \%4. "\&\ =\ dotted quarter note,"
        !           511: etc.) and
        !           512: .I rests,
        !           513: possibly with repeated groups (\c
        !           514: .CW "3(16 16r)"
        !           515: means
        !           516: .\".fp 9 MU Musicpi
        !           517: .\"\f(MU\N'140'\fP\ \f(MU\N'24'\fP
        !           518: .\"\f(MU\N'140'\fP\ \f(MU\N'24'\fP
        !           519: .\"\f(MU\N'140'\fP\ \f(MU\N'24'\fP).
        !           520: .fp 8 MU Sonata
        !           521: \f(MU\N'120'\fP\ \f(MU\N'197'\fP
        !           522: \f(MU\N'120'\fP\ \f(MU\N'197'\fP
        !           523: \f(MU\N'120'\fP\ \f(MU\N'197'\fP ).
        !           524: A note list consists of
        !           525: .I notes ,
        !           526: .I rests ,
        !           527: and
        !           528: .I modifiers .
        !           529: Notes specify
        !           530: .I "pitch class"
        !           531: and, optionally,
        !           532: .I "octave number" .
        !           533: Pitch class is indicated in standard letter notation, with accidentals
        !           534: .CW # ,
        !           535: .CW @
        !           536: (flat), and
        !           537: .CW =
        !           538: (natural).  The octave is given by a number appearing
        !           539: after the letter name, e.g.,
        !           540: .CW c3
        !           541: is middle c, and
        !           542: .CW c3# ,
        !           543: .CW c#3
        !           544: are a half-tone above.
        !           545: The octave number changes between b and c, so a half-tone below middle c is
        !           546: .CW b2 .
        !           547: A missing octave number defaults to that of the previous note in the same voice.
        !           548: Rests have time value only and are indicated by
        !           549: .CW r .
        !           550: .PP
        !           551: Modifiers are used to set ``environmental'' parameters; in the example,
        !           552: the modifier
        !           553: .CW F60
        !           554: specifies a ``key force'' (volume) of 60 units.
        !           555: .PP
        !           556: Not shown in the example are notations for ties and more complicated rhythms.
        !           557: Ties map particularly easily onto
        !           558: .SM MIDI
        !           559: events.  Observe that a note usually
        !           560: generates two
        !           561: .SM MIDI
        !           562: events, note-on and note-off.  A note with a tie going out
        !           563: (e.g.,
        !           564: .CW \%c- "),"
        !           565: simply loses its note-off event, and one with a tie coming in
        !           566: (e.g.,
        !           567: .CW _c ")"
        !           568: loses its note-on event.
        !           569: Time values may contain multiplicative expressions, e.g.,
        !           570: .CW 3(3*4)
        !           571: is a triplet to a quarter note.
        !           572: Finally, values that are inconvenient to
        !           573: generate otherwise can be specified with numerator and denominator, e.g.,
        !           574: .CW 9/17 .
        !           575: .PP
        !           576: Also not shown in the example are possibilities for grouping in the
        !           577: note list.  Parentheses group a
        !           578: .I sequence ,
        !           579: and square brackets group a
        !           580: .I chord .
        !           581: E.g., all of the notes in
        !           582: .CW "[c\ e\ g]"
        !           583: are sounded simultaneously, and
        !           584: groupings may be nested, so that
        !           585: .CW "[(c\ d\ c) (e\ g\ e) (g\ b\ g)]"
        !           586: has three
        !           587: sequences running in parallel to make a \%I-V-I progression.
        !           588: .PP
        !           589: To facilitate machine generation of M code, an alternative rhythm
        !           590: notation is allowed: the rhythm list can be omitted, and time values prefixed
        !           591: to the corresponding notes.  This is readable to humans, but less convenient
        !           592: for keyboard input (see below).
        !           593: .PP
        !           594: M is based on
        !           595: .I lex
        !           596: and
        !           597: .I yacc ,
        !           598: and its continuing development depends heavily on them.
        !           599: M is intended to be used by musicians who are not computer scientists, and
        !           600: who can't always pass on the merits of a feature without testing it.  Hence
        !           601: the ability to experiment is most important.
        !           602: .I Lex
        !           603: in particular has been justly criticized on performance grounds, given that
        !           604: lexical analyzers are fairly easy to write by hand.  But this is the case
        !           605: only for a static language, and M is still changing rapidly, particularly in
        !           606: the area of dynamics control.
        !           607: .PP
        !           608: M produces a
        !           609: .SM MIDI
        !           610: file on its standard output, so that
        !           611: .CW "m bach\ |\ midi"
        !           612: is an example of a common invocation.
        !           613: It also has options to restrict the output
        !           614: to certain voices or a range of measures, as a debugging aid.
        !           615: .NH
        !           616: The M keyboard interface.
        !           617: .PP
        !           618: It is possible to generate the notes of an M program by playing at the
        !           619: .SM DX7
        !           620: keyboard.  First the note-on and note-off events are collected by
        !           621: .I midiblt
        !           622: and written into a file on the host.  This file is then converted into a
        !           623: list of note names by
        !           624: .I unmidi .
        !           625: We have used the conventions that the
        !           626: .SM DX7 "'s"
        !           627: .SM YES
        !           628: button generates a newline, and the
        !           629: .SM NO
        !           630: button produces the comment
        !           631: .CW "/*?*/" .
        !           632: This gives the user some control over the format and the ability to flag errors.
        !           633: We also use the ``portamento'' pedal to generate a barline.
        !           634: .I Unmidi
        !           635: has an ``output key'' option to direct it towards desired enharmonic spellings.
        !           636: The output from
        !           637: .I unmidi
        !           638: is fed to an
        !           639: .I awk
        !           640: script which adds voice names.  Now only the rhythm
        !           641: is missing.  Since it is separate from the notes, it
        !           642: can be typed in quickly by making a second pass over the score.
        !           643: .NH
        !           644: Conclusions.
        !           645: .PP
        !           646: Twelve-tone pieces such as the one in section 5, and serialized pieces
        !           647: particularly, would be easier and faster to develop with the aid of specialized
        !           648: tools.  These could range anywhere from a library of C routines to a
        !           649: complete language implementation.  We expect to begin on a modest scale
        !           650: with the former and enlist the efforts of interested composers.
        !           651: .PP
        !           652: It is clear that we have barely scratched the surface of
        !           653: an immensely challenging class
        !           654: of problems.  The
        !           655: .UX
        !           656: system, originally crafted as a home for programmers,
        !           657: has proven remarkably robust, flexible, and downright hospitable as a base
        !           658: for a very different application.
        !           659: .NH
        !           660: References.
        !           661: .LP
        !           662: |reference_placement

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.