This is Info file pm.info, produced by Makeinfo version 1.68 from the input file bigpm.texi.  File: pm.info, Node: MARC/XML, Next: MCrypt, Prev: MARC, Up: Module List A subclass of MARC.pm to provide XML support. ********************************************* NAME ==== MARC::XML - A subclass of MARC.pm to provide XML support. SYNOPSIS ======== use MARC::XML; #read in some MARC and output some XML $myobject = MARC::XML->new("marc.mrc","usmarc"); $myobject->output({file=>">marc.xml",format=>"xml"}); #read in some XML and output some MARC $myobject = MARC::XML->new("marc.xml","xml"); $myobject->output({file=>">marc.mrc","usmarc"); DESCRIPTION =========== MARC::XML is a subclass of MARC.pm which provides methods for round-trip conversions between MARC and XML. MARC::XML requires that you have the CPAN modules MARC.pm and XML::Parser installed in your Perl library. Version 1.04 of MARC.pm and 2.27 of XML::Parser (or later) are required. As a subclass of MARC.pm a MARC::XML object will by default have the full functionality of a MARC.pm object. See the MARC.pm documentation for details. The XML file that is read and generated by MARC::XML is not associated with a Document Type Definition (DTD). This means that your files need to be well-formed, but they will not be validated. When performing XML->MARC conversion it is important that the XML file is structured in a particular way. Fortunately, this is the same format that is generated by the MARC->XML conversion, so you should be able to be able to move your data easily between the two formats. Downloading and Intalling ------------------------- Download First make sure that you have *MARC.pm* and XML::Parser installed. Both Perl extensions are available from the CPAN http://www.cpan.org/modules/by-module, and they must be available in your Perl library for MARC::XML to work properly. MARC::XML is provided in standard CPAN distribution format. Download the latest version from http://www.cpan.org/modules/by-module/MARC/XML. It will extract into a directory MARC-XML-version with any necessary subdirectories. Once you have extracted the archive Change into the MARC-XML top directory and execute the following command depending on your platform. Unix perl Makefile.PL make make test make install Win9x/WinNT/Win2000 perl Makefile.PL perl test.pl perl install.pl Test Once you have installed, you can check if Perl can find it. Change to some other directory and execute from the command line: perl -e "use MARC::XML" If you *do not* get any response that means everything is OK! If you get an error like *Can't locate method "use" via package MARC::XML*. then Perl is not able to find MARC::XML-double check that the file copied it into the right place during the install. Todo ---- * Checking for field and record lengths to make sure that data read in from an XML file does not exceed the limited space available in a MARC record. * Support for MARC <-> Unicode character conversions. * MARC <-> EAD (Encoded Archival Description) conversion? * Support for MARC <-> DC/RDF (Dublin Core Metadata encoded in the Resource Description Framework)? * Support for MARC <-> FGDC Metadata (Federal Geographic Data Committee) conversion? Web Interface ------------- A web interface to MARC.pm and MARC::XML is available at http://libstaff.lib.odu.edu/cgi-bin/marc.cgi where you can upload records and observe the results. If you'd like to check out the cgi script take a look at http://libstaff.lib.odu.edu/depts/systems/iii/scripts/MARCpm/marc-cgi.txt However, to get the full functionality you will want to install MARC.pm and MARC::XML on your server or PC. Sample XML file --------------- Below is an example of the flavor of XML that MARC::XML will generate and read. There are only four elements: the ** pair that serves as the root for the file; the ** pair that encloses each record; the ** pair which encloses each field; and the ** pair which encloses each subfield. In addition the ** and ** tags have three possible attributes: type which defines the specific tag or subfield ; as well as *i1* and *i2* which allow you to define the indicators for a specific tag. 00901cam 2200241Ia 45e0 ocm01047729 OCoLC 19990808143752.0 741021s1884 enkaf 000 1 eng d KSU KSU GZM PS1305 .A1 1884 VODN Twain, Mark, 1835-1910. The adventures of Huckleberry Finn : (Tom Sawyer's comrade) : scene, the Mississippi Valley : time, forty to fifty years ago / by Mark Twain (Samuel Clemens) ; with 174 illustrations. London : Chatto & Windus, 1884. xvi, 438 p., [1] leaf of plates : ill. ; 20 cm. First English ed. State B; gatherings saddle-stitched with wire staples. Advertisements on p. [1]-32 at end. Bound in red S cloth; stamped in black and gold. BAL 3414. Huckleberry Finn. E0 VOD METHODS ======= Here is a list of methods available to you in MARC::XML. new() ----- MARC::XML overides MARC.pm's new() method to create a MARC::XML object. Similar to MARC.pm's new() it can take two arguments: a file name, and the format of the file to read in. However MARC::XML's new() gives you an extra format choice "XML" (which is also the default). Internally, the XML source is converted to a series of addfield() and createrecord() calls. The order of MARC tags is preserved by default. But if an optional third argument is passed to new(), it is used as the ordered option for the addfield() calls. Like MARC.pm, it is not possible to read only part of an XML input file using new(). Some examples: #read in an XML file called myxmlfile.xml use MARC::XML; $x = MARC::XML->new("myxmlfile.xml","xml"); $x = MARC::XML->new("needsort.xml","xml","y"); Since the full funtionality of MARC.pm is also available you can read in other types of files as well. Although new() with no arguments will create an object with no records, just like MARC.pm, XML format not supported by openmarc() and nextmarc() for input. The openxml() and nextxml() methods provide similar operation. And you can output from XML to a different format source. #read in a MARC file called mymarcfile.mrc use MARC::XML; $x = MARC::XML->new("mymarcfile.mrc","usmarc"); $x = MARC::XML->new(); output() -------- MARC::XML's output() method allows you to output the MARC object as an XML file. It takes eight arguments: file, format, lineterm, and records have the same function as in MARC.pm. If not specified, format defaults to "xml" and lineterm defaults to "\n". A charset parameter accepts a hash-reference to a user supplied character translation table. The internal default is based on the LoC "register.sgm" table supplied with the LoC. SGML utilities. You can use the *ansel_default* method to get a hash-reference to it if you only want to modify a couple of characters. See example below. The encoding, *dtd_file*, and *standalone* arguments correspond to the specified fields in an XML header. If not specified, *standalone* defaults to "yes" and encoding to "US-ASCII". If an optional *dtd_file* is specified, a *Document Type Declaration* is added to the output to contain the data. use MARC::XML; $x = MARC::XML->new("mymarcfile.mrc","usmarc"); $x->output({file=>">myxmlfile.xml",format=>"xml"}); Or if you only want to output the first record: $x->output({file=>">myxmlfile.xml",format=>"xml",records=>[1]}); If you like you can also output portions of the XML file using the format options: *xml_header*, *xml_body*, and *xml_footer*. Remember to prefix your file name with a >> to append though. This example will output record 1 twice. use MARC::XML; $x = MARC::XML->new("mymarcfile.mrc","usmarc"); $x->output({file=>">myxmlfile.xml",format=>"xml_header"}); $x->output({file=>">>myxmlfile.xml",format=>"xml_body",records=>[1]}); $x->output({file=>">>myxmlfile.xml",format=>"xml_body",records=>[1]}); $x->output({file=>">>myxmlfile.xml",foramt=>"xml_footer"}); Instead of outputting to a file, you can also capture the output in a variable if you wish. use MARC::XML; $x = MARC::XML->new("mymarcfile.mrc","usmarc"); $myxml = $x->output({format=>"xml"}); As with new() the full functionality of MARC.pm's output() method are available to you as well. So you could read in an XML file and then output it as ascii text: use MARC::XML; $x = MARC::XML->new("myxmlfile.xml","xml"); $x->output({file=>">mytextfile.txt","ascii"); NOTES ===== Please let us know if you run into any difficulties using MARC.pm-we'd be happy to try to help. Also, please contact us if you notice any bugs, or if you would like to suggest an improvement/enhancement. Email addresses are listed at the bottom of this page. Development of MARC.pm and other library oriented Perl utilities is conducted on the Perl4Lib listserv. Perl4Lib is an open list and is an ideal place to ask questions about MARC.pm. Subscription information is available at http://www.vims.edu/perl4lib Two global boolean variables are reserved for test and debugging. Both are "0" (off) by default. The `$XTEST' variable disables internal error messages generated using Carp. It should only be used in the automatic test suite. The `$XDEBUG' variable adds verbose diagnostic messages. EXAMPLES ======== The *eg* subdirectory contains a few complete examples to get you started. AUTHORS ======= Chuck Bearden cbearden@rice.edu Bill Birthisel wcbirthisel@alum.mit.edu Derek Lane dereklane@pobox.com Charles McFadden chuck@vims.edu Ed Summers ed@cheetahmail.com SEE ALSO ======== perl(1), MARC.pm, MARC http://lcweb.loc.gov/marc , XML http://www.w3.org/xml . COPYRIGHT ========= Copyright (C) 1999,2000, Bearden, Birthisel, Lane, McFadden, and Summers. All rights reserved. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. 23 April 2000. Portions Copyright (C) 1999,2000, Duke University, Lane.  File: pm.info, Node: MCrypt, Next: MD5, Prev: MARC/XML, Up: Module List Perl extension for MCrypt Crypto library **************************************** NAME ==== MCrypt - Perl extension for MCrypt Crypto library DISCLAIMER ========== THIS IS A FIRST RELEASE BETA VERSION. ------------------------------------- Yes, it does work. If you have use for this, please try and use it and report any bugs you find. Feedback from users of this module is important. SYNOPSIS ======== use MCrypt qw(:Functions :Modes :Types) ; my $key = "my secret key"; my $data "this is my secret data"; # optional IV that matches the blocksize of the cipher! my $iv = "12345678" ; # 8 bytes for MCRYPT_3DES $ciphertext = mcrypt_cbc( MCRYPT_3DES, $key, $data, MCRYPT_ENCRYPT, $iv ) ; **NOTE** Please read the section on EXPORT TAGS below for information on the MCRYPT_ constants and the how to conserve your namespace. DEPENDENCIES ============ This interface is dependent on the 2.2.x tree of the MCRYPT library. Please download and install the latest libmcrypt-2.2.x.tar.gz at ftp://argeas.cs-net.gr/pub/unix/mcrypt. As of this writing, the latest is libmcrypt-2.2.7.tar.gz. Additional information about the mcrypt library can be found at http://mcrypt.hellug.gr. Libmcrypt MUST be found in your library path when using this module. In Linux, libmcrypt is defaultly installed in /usr/local/lib - in this case, be sure that the /usr/local/lib path is in your /etc/ld.so.conf. DESCRIPTION =========== This is an perl interface to the MCrypt crypto library, which supports a wide variety of block algorithms such as DES, TripleDES, Blowfish (default), 3-WAY, SAFER-SK64, SAFER-SK128, TWOFISH, TEA, RC2, GOST, LOKI, SERPENT, CAST and RIJNDAEL in CBC, OFB, CFB and ECB cipher modes. Mcrypt can be used to encrypt and decrypt using the above mentioned ciphers. The four important mcrypt commands (mcrypt_cfb(), mcrypt_cbc(), mcrypt_ecb(), and mcrypt_ofb()) can operate in both modes which are named MCRYPT_ENCRYPT and MCRYPT_DECRYPT, respectively. Mcrypt can operate in four block cipher modes (CBC, OFB, CFB, and ECB). We will outline the normal use for each of these modes. For a more complete reference and discussion see Applied Cryptography by Schneier (ISBN 0-471-11709-9). ECB (electronic codebook) is suitable for random data, such as encrypting other keys. Since data there is short and random, the disadvantages of ECB have a favorable negative effect. CBC (cipher block chaining) is especially suitable for encrypting files where the security is increased over ECB significantly. CFB (cipher feedback) is the best mode for encrypting byte streams where single bytes must be encrypted. OFB (output feedback, in 8bit) is comparable to CFB, but can be used in applications where error propagation cannot be tolerated. It's insecure (because it operates in 8bit mode) so it is not recommended to use it. MCrypt does not support encrypting/decrypting bit streams currently. As of now, MCrypt only supports handling of strings. Here is the list of cipher constants which are currently supported by the MCrypt module: MCRYPT_DES MCRYPT_3DES MCRYPT_3WAY MCRYPT_GOST MCRYPT_SAFER64 MCRYPT_SAFER128 MCRYPT_CAST_128 MCRYPT_CAST_256 MCRYPT_XTEA MCRYPT_RC2_128 MCRYPT_RC2_192 MCRYPT_RC2_1024 MCRYPT_TWOFISH128 MCRYPT_TWOFISH192 MCRYPT_TWOFISH256 MCRYPT_BLOWFISH_128 MCRYPT_BLOWFISH_192 MCRYPT_BLOWFISH_256 MCRYPT_BLOWFISH_448 (the default if a blank cipher is supplied) MCRYPT_CAST_256 MCRYPT_SAFERPLUS MCRYPT_LOKI97 MCRYPT_SERPENT_128 MCRYPT_SERPENT_192 MCRYPT_SERPENT_256 MCRYPT_RIJNDAEL_128 MCRYPT_RIJNDAEL_192 MCRYPT_RIJNDAEL_256 MCRYPT_CRYPT MCRYPT_RC6_128 MCRYPT_RC6_192 MCRYPT_RC6_256 MCRYPT_IDEA (non-free) MCRYPT_ARCFOUR (also aliased as MCRYPT_RC_4) You must (in CFB and OFB mode) or can (in CBC mode) supply an initialization vector (IV) to the respective cipher function. The IV must be unique and must be the same when decrypting/encrypting. With data which is stored encrypted, you can take the output of a function of the index under which the data is stored (e.g. the MD5 key of the filename). Alternatively, you can transmit the IV together with the encrypted data (see chapter 9.3 of Applied Cryptography by Schneier (ISBN 0-471-11709-9) for a discussion of this topic). EXPORT TAGS A more conservative usage of the above SYNOPSIS: ================================================================ # no export tags supplied in the below line; import :Functions by default use MCrypt ; my $key = "my secret key"; my $data "this is my secret data"; # optional IV that matches the blocksize of the cipher! my $iv = "12345678" ; # 8 bytes for MCRYPT_3DES $ciphertext = mcrypt_cbc( MCrypt::MCRYPT_3DES, $key, $data, MCrypt::MCRYPT_ENCRYPT, $iv ) ; Functions This tag exports all the functions related to MCrypt. This tag should always be imported unless you are going to be calling MCrypt functions with the full package name. This tag is automatically imported if no export tags are supplied as in the above example. (i.e. MCrypt::mcrypt_cbc()). Modes This tag exports the encryption mode constants MCRYPT_ENCRYPT and MCRYPT_DECRYPT. It is recommended that you import this tag as it only imports two constants into your namespace. If you are being conservative with your namespace, you can leave this out providing you call these constant with the package name. (i.e. MCrypt::MCRYPT_ENCRYPT ) Types This tag exports the cipher constants defined by the list of ciphers above in DESCRIPTION. It is recommended you import this tag for ease of use. If you are concerned with polluting your namespace, do not import this tag, and use the form MCrypt::MCRYPT_CIPHERNAME when supplying the cipher to the MCrypt functions. (i.e. MCrypt::MCRYPT_3DES ) PROGRAMMING FUNCTIONS AND METHODS ================================= The following methods are available: mcrypt_cbc() Mcrypt_cbc() encrypts or decrypts (depending on mode) the data with cipher and key in CBC cipher mode and returns the resulting string. $ciphertext = mcrypt_cbc($cipher, $key, $data, $mode, [$IV]) ; Cipher is one of the MCRYPT_ciphername constants. Key is the key supplied to the algorithm. It must be kept secret. Data is the data which shall be encrypted/decrypted. Mode is MCRYPT_ENCRYPT or MCRYPT_DECRYPT. IV is the optional initialization vector. (This must be the blocksize of the cipher!) mcrypt_ecb() Mcrypt_ecb() encrypts or decrypts (depending on mode) the data with cipher and key in ECB cipher mode and returns the resulting string. $ciphertext = mcrypt_ecb($cipher, $key, $data, $mode) ; Cipher is one of the MCRYPT_ciphername constants. Key is the key supplied to the algorithm. It must be kept secret. Data is the data which shall be encrypted/decrypted. Mode is MCRYPT_ENCRYPT or MCRYPT_DECRYPT. mcrypt_ofb() Mcrypt_ofb() encrypts or decrypts (depending on mode) the data with cipher and key in OFB cipher mode and returns the resulting string. $ciphertext = mcrypt_ofb($cipher, $key, $data, $mode, $IV) ; Cipher is one of the MCRYPT_ciphername constants. Key is the key supplied to the algorithm. It must be kept secret. Data is the data which shall be encrypted/decrypted. Mode is MCRYPT_ENCRYPT or MCRYPT_DECRYPT. IV is the initialization vector. (This must be the blocksize of the cipher!) mcrypt_cfb() Mcrypt_cfb() encrypts or decrypts (depending on mode) the data with cipher and key in CFB cipher mode and returns the resulting string. $ciphertext = mcrypt_cfb($cipher, $key, $data, $mode, $IV) ; Cipher is one of the MCRYPT_ciphername constants. Key is the key supplied to the algorithm. It must be kept secret. Data is the data which shall be encrypted/decrypted. Mode is MCRYPT_ENCRYPT or MCRYPT_DECRYPT. IV is the initialization vector. (This must be the blocksize of the cipher!) mcrypt_get_cipher_name() Mcrypt_get_cipher_name() is used to get the name of the specified cipher. This function takes the cipher number as an argument and returns the name of the cipher as a string or false, if the cipher does not exist. $ciphername = mcrypt_get_cipher_name( MCRYPT_3DES ) ; Cipher is one of the MCRYPT_ciphername constants. mcrypt_get_key_size() Mcrypt_get_key_size() is used to get the size of a key of the specified cipher. This function takes one argument, the cipher and returns the size in bytes. This function is useful to find the keysize for a specific cipher. The key you use SHOULD match the keysize. $keysize = mcrypt_get_key_size( MCRYPT_3DES ) ; Cipher is one of the MCRYPT_ciphername constants. mcrypt_get_block_size() Mcrypt_get_block_size() is used to get the size of a block of the specified cipher. This function takes one argument, the cipher and returns the size in bytes. This function is useful for determining the correct size of the IV of a cipher. $keysize = mcrypt_get_block_size( MCRYPT_3DES ) ; Cipher is one of the MCRYPT_ciphername constants. TODO ==== - More bug testing. - implement mcrypt_create_iv() in a nice way - detection of libmcrypt installation AUTHOR ====== Kuo, Frey, kero@3SHEEP.COM. CREDITS ------- Mavroyanopoulos, Nikos, - for the libmcrypt library. Schumann, Sasha, - for PHP's implementation of the libmcrypt interface. SEE ALSO ======== mcrypt(3).  File: pm.info, Node: MD5, Next: MIDI, Prev: MCrypt, Up: Module List Perl interface to the MD5 Message-Digest Algorithm ************************************************** NAME ==== MD5 - Perl interface to the MD5 Message-Digest Algorithm SYNOPSIS ======== use MD5; $context = new MD5; $context->reset(); $context->add(LIST); $context->addfile(HANDLE); $digest = $context->digest(); $string = $context->hexdigest(); $digest = MD5->hash(SCALAR); $string = MD5->hexhash(SCALAR); DESCRIPTION =========== The MD5 module is *depreciated*. Use Digest::MD5 instead. The current MD5 module is just a wrapper around the Digest::MD5 module. It is provided so that legacy code that rely on the old interface still work and get the speed benefit of the new module. In addition to the methods provided for Digest::MD5 objects, this module provide the class methods MD5->hash() and MD5->hexhash() that basically do the same as the md5() and md5_hex() functions provided by Digest::MD5. SEE ALSO ======== *Note Digest/MD5: Digest/MD5,  File: pm.info, Node: MIDI, Next: MIDI/Event, Prev: MD5, Up: Module List read, compose, modify, and write MIDI files. ******************************************** NAME ==== MIDI - read, compose, modify, and write MIDI files. SYNOPSIS ======== use MIDI; $chimes_track = MIDI::Track->new({ 'events' => [ ['text_event',0, 'www.ely.anglican.org/parishes/camgsm/chimes.html'], ['text_event',0, 'Lord through this hour/ be Thou our guide'], ['text_event',0, 'so, by Thy power/ no foot shall slide'], ['text_event',0, '(coded at ' . scalar(localtime) . ' )'], ['patch_change', 0, 1, 8], # Patch 8 = Celesta map( (['note_on',0,1,$_->[0],96], ['note_off',$_->[1],1,$_->[0],0]), [25,96],[29,96],[27,96],[20,192],[25,96],[27,96],[29,96],[25,192], [29,96],[25,96],[27,96],[20,192],[20,96],[27,96],[29,96],[25,192], )# [Note,Duration] ==> ['note_on',0,1, N ,96], ['note_off', D ,1, N ,0] ] }); $chimes = MIDI::Opus->new( { 'format' => 0, 'ticks' => 96, 'tracks' => [ $chimes_track ] } ); $chimes->write_to_file('chimes.mid'); DESCRIPTION =========== This suite of modules provides routines for reading, composing, modifying, and writing MIDI files. From FOLDOC (`http://wombat.doc.ic.ac.uk/foldoc/'): *MIDI, Musical Instrument Digital Interface* (MIDI /mi'-dee/, /mee'-dee/) A hardware specification and protocol used to communicate note and effect information between synthesisers, computers, music keyboards, controllers and other electronic music devices. [...] The basic unit of information is a "note on/off" event which includes a note number (pitch) and key velocity (loudness). There are many other message types for events such as pitch bend, patch changes and synthesizer-specific events for loading new patches etc. There is a file format for expressing MIDI data which is like a dump of data sent over a MIDI port. [...] COMPONENTS ========== The MIDI-Perl suite consists of these modules: *Note MIDI: MIDI, (which you're looking at), *Note MIDI/Opus: MIDI/Opus,, *Note MIDI/Track: MIDI/Track,, *Note MIDI/Event: MIDI/Event,, *Note MIDI/Score: MIDI/Score,, and *Note MIDI/Simple: MIDI/Simple,. All of these contain documentation in pod format. You should read all of these pods. The order you want to read them in will depend on what you want to do with this suite of modules: if you are focused on manipulating the guts of existing MIDI files, read the pods in the order given above. But if you aim to compose music with this suite, read this pod, then *Note MIDI/Score: MIDI/Score, and *Note MIDI/Simple: MIDI/Simple,, and then skim the rest. (For your reference, there is also a document in pod format which is not itself an actual module: *Note MIDI/Filespec: MIDI/Filespec,. It is an old version of the MIDI file specification.) INTRODUCTION ============ This suite of modules is basically object-oriented, with the exception of MIDI::Simple. MIDI opuses ("songs") are represented as objects belonging to the class MIDI::Opus. An opus contains tracks, which are objects belonging to the class MIDI::Track. A track will generally contain a list of events, where each event is a list consisting of a command, a delta-time, and some number of parameters. In other words, opuses and tracks are objects, and the events in a track comprise a LoL (and if you don't know what an LoL is, you must read *Note Perllol: (perl.info)perllol,). Furthermore, for some purposes it's useful to analyze the totality of a track's events as a "score" - where a score consists of notes where each event is a list consisting of a command, a time offset from the start of the track, and some number of parameters. This is the level of abstraction that MIDI::Score and MIDI::Simple deal with. While this suite does provide some functionality accessible only if you're comfortable with various kinds of references, and while there are some options that deal with the guts of MIDI encoding, you can (I hope) get along just fine with just a basic grasp of the MIDI "standard", and a command of LoLs. I have tried, at various points in this documentation, to point out what things are not likely to be of use to the casual user. TO DO ===== Maybe have a MIDI cookbook of commonly used short scripts? *A PLEA*: Currently this suite can only read/write MIDI data from/to MIDI files. However, it would be desirable to have realtime access to a MIDI device - at least on systems where a MIDI device (whether thru a hardware port or as a virtual sequencer in a sound card) is accessable as a virtual file (`/dev/midi0', `/dev/midi', `/dev/sequencer', or whatever). However, I have no such MIDI devices (much less ports) at hand for development and testing. But if *you* have such devices (I'm thinking a Linuxer with a synth hooked to their MIDI port), and if you want to help me experiment with directly accessing them from Perl, then please email me. I already have a pretty good idea of how it should work - but as always, the proof is as much in the pudding as the devil is in the details. GOODIES ======= The bare module MIDI.pm doesn't do much more than use the necessary component submodules (i.e., all except MIDI::Simple). But it does provide some hashes you might find useful: `%MIDI::note2number' and `%MIDI::number2note' `%MIDI::number2note' correponds MIDI note numbers to a more comprehensible representation (e.g., 68 to 'Gs4', for G-sharp, octave 4); `%MIDI::note2number' is the reverse. Have a look at the source to see the contents of the hash. `%MIDI::patch2number' and `%MIDI::number2patch' `%MIDI::number2patch' correponds General MIDI patch numbers (0 to 127) to English names (e.g., 79 to 'Ocarina'); `%MIDI::patch2number' is the reverse. Have a look at the source to see the contents of the hash. `%MIDI::notenum2percussion' and `%MIDI::percussion2notenum' `%MIDI::notenum2percussion' correponds General MIDI Percussion Keys to English names (e.g., 56 to 'Cowbell') - but note that only numbers 35 to 81 (inclusive) are defined; `%MIDI::percussion2notenum' is the reverse. Have a look at the source to see the contents of the hash. BRIEF GLOSSARY ============== This glossary defines just a few terms, just enough so you can (hopefully) make some sense of the documentation for this suite of modules. If you're going to do anything serious with these modules, however, you *should really* invest in a good book about the MIDI standard - see the References. channel: a logical channel to which control changes and patch changes apply, and in which MIDI (note-related) events occur. control: one of the various numeric parameters associated with a given channel. Like S registers in Hayes-set modems, MIDI controls consist of a few well-known registers, and beyond that, it's patch-specific and/or sequencer-specific. *delta-time*: the time (in ticks) that a sequencer should wait between playing the previous event and playing the current event. *meta-event*: any of a mixed bag of events whose common trait is merely that they are similarly encoded. Most meta-events apply to all channels, unlike events, which mostly apply to just one channel. note: my oversimplistic term for items in a score structure. *opus*: the term I prefer for a piece of music, as represented in MIDI. Most specs use the term "song", but I think that this falsely implies that MIDI files represent vocal pieces. patch: an electronic model of the sound of a given notional instrument. *running status*: a form of modest compression where an event lacking an event command byte (a "status" byte) is to be interpreted as having the same event command as the preceding event - which may, in turn, lack a status byte and may have to be interpreted as having the same event command as *its* previous event, and so on back. score: a structure of notes like an event structure, but where notes are represented as single items, and where timing of items is absolute from the beginning of the track, instead of being represented in delta-times. *song*: what some MIDI specs call a song, I call an opus. *sequencer*: a device or program that interprets and acts on MIDI data. This prototypically refers to synthesizers or drum machines, but can also refer to more limited devices, such as mixers or even lighting control systems. status: a synonym for "event". *sysex*: a chunk of binary data encapsulated in the MIDI data stream, for whatever purpose. *text event*: any of the several meta-events (one of which is actually called 'text_event') that conveys text. Most often used to just label tracks, note the instruments used for a track, or to provide metainformation about copyright, performer, and piece title and author. *tick*: the timing unit in a MIDI opus. *variable-length encoding*: an encoding method identical to what Perl calls the 'w' (BER, Basic Encoding Rules) pack/unpack format for integers. REFERENCES ========== Christian Braut. *The Musician's Guide to Midi.* ISBN 0782112854. [This one is indispensible -SMB] Langston, Peter S. 1998. "Little Music Languages", p.587-656 in: Salus, Peter H,. editor in chief, /Handbook of Programming Languages/, vol. 3. MacMillan Technical, 1998. [The volume it's in is probably not worth the money, but see if you can at least glance at this article anyway. It's not often you see 70 pages written on music languages. -SMB] I'll keep a list of other references and good stuff at the URL `http://www.speech.cs.cmu.edu/~sburke/pub/perl_midi/' AUTHOR ====== Sean M. Burke `sburke@cpan.org'  File: pm.info, Node: MIDI/Event, Next: MIDI/Filespec, Prev: MIDI, Up: Module List MIDI events *********** NAME ==== MIDI::Event - MIDI events SYNOPSIS ======== # Dump a MIDI file's text events die "No filename" unless @ARGV; use MIDI; # which "use"s MIDI::Event; MIDI::Opus->new( { "from_file" => $ARGV[0], "exclusive_event_callback" => sub{print "$_[2]\n"}, "include" => \@MIDI::Event::Text_events } ); # These options percolate down to MIDI::Event::decode exit; DESCRIPTION =========== Functions and lists to do with with MIDI events and MIDI event structures. An event is a list, like: ( 'note_on', 141, 4, 50, 64 ) where the first element is the event name, the second is the delta-time, and the remainder are further parameters, per the event-format specifications below. An *event structure* is a list of references to such events - a "LoL". If you don't know how to deal with LoLs, you must read *Note Perllol: (perl.info)perllol,. GOODIES ======= For your use in code (as in the code in the Synopsis), this module provides a few lists: @MIDI_events a list of all "MIDI events" AKA voice events - e.g., 'note_on' @Text_events a list of all text meta-events - e.g., 'track_name' @Nontext_meta_events all other meta-events (plus 'raw_data' and F-series events like 'tune_request'). @Meta_events the combination of Text_events and Nontext_meta_events. @All_events the combination of all the above lists. FUNCTIONS ========= This module provides three functions of interest, which all act upon event structures. As an end user, you probably don't need to use any of these directly, but note that options you specify for MIDI::Opus->new with a from_file or from_handle options will percolate down to these functions; so you should understand the options for the first two of the below functions. (The casual user should merely skim this section.) MIDI::Event::decode( \$data, { ...options... } ) This takes a reference to binary MIDI data and decodes it into a new event structure (a LoL), a reference to which is returned. Options are: 'include' => LISTREF *If specified*, listref is interpreted as a reference to a list of event names (e.g., 'cue_point' or 'note_off') such that only these events will be parsed from the binary data provided. Events whose names are NOT in this list will be ignored - i.e., they won't end up in the event structure, and they won't be each passed to any callbacks you may have specified. 'exclude' => LISTREF *If specified*, listref is interpreted as a reference to a list of event names (e.g., 'cue_point' or 'note_off') that will NOT be parsed from the binary stream; they'll be ignored - i.e., they won't end up in the event structure, and they won't be passed to any callbacks you may have specified. Don't specify both an include and an exclude list. And if you specify *neither*, all events will be decoded - this is what you probably want most of the time. I've created this include/exclude functionality mainly so you can scan a file rather efficiently for just a few specific event types, e.g., just text events, or just sysexes. 'no_eot_magic' => 0 or 1 See the description of `'end_track'', in "EVENTS", below. 'event_callback' => CODEREF If defined, the code referred to (whether as `\&wanted' or as `sub { BLOCK }') is called on every event after it's been parsed into an event list (and any EOT magic performed), but before it's added to the event structure. So if you want to alter the event stream on the way to the event structure (which counts as deep voodoo), define 'event_callback' and have it modify its `@_'. 'exclusive_event_callback' => CODEREF Just like 'event_callback'; but if you specify this, the callback is called *instead* of adding the events to the event structure. (So the event structure returned by decode() at the end will always be empty.) Good for cases like the text dumper in the Synopsis, above. MIDI::Event::encode( \@events, {...options...}) This takes a reference to an event structure (a LoL) and encodes it as binary data, which it returns a reference to. Options: 'unknown_callback' => CODEREF If this is specified, it's interpreted as a reference to a subroutine to be called when an unknown event name (say, 'macro_10' or something), is seen by encode(). The function is fed all of the event (its name, delta-time, and whatever parameters); the return value of this function is added to the encoded data stream - so if you don't want to add anything, be sure to return ". If no 'unknown_callback' is specified, encode() will warn (well, carp) of the unknown event. To merely block that, just set 'unknown_callback' to `sub{return('')}' 'no_eot_magic' => 0 or 1 Determines whether a track-final 0-length text event is encoded as a end-track event - since a track-final 0-length text event probably started life as an end-track event read in by decode(), above. 'never_add_eot' => 0 or 1 If 1, encode() never ever *adds* an end-track (EOT) event to the encoded data generated unless it's *explicitly* there as an 'end_track' in the given event structure. You probably don't ever need this unless you're encoding for *straight* writing to a MIDI port, instead of to a file. 'no_running_status' => 0 or 1 If 1, disables MIDI's "running status" compression. Probably never necessary unless you need to feed your MIDI data to a strange old sequencer that doesn't understand running status. Note: If you're encoding just a single event at a time or less than a whole trackful in any case, then you probably want something like: $data_r = MIDI::Event::encode( [ [ 'note_on', 141, 4, 50, 64 ] ], { 'never_add_eot' => 1} ); which just encodes that one event *as* an event structure of one event - i.e., an LoL that's just a list of one list. But note that running status will not always apply when you're encoding less than a whole trackful at a time, since running status works only within a LoL encoded all at once. This'll result in non-optimally compressed, but still effective, encoding. MIDI::Event::copy_structure() This takes a reference to an event structure, and returns a reference to a copy of it. If you're thinking about using this, you probably should want to use the more straightforward $track2 = $track->copy instead. But it's here if you happen to need it. EVENTS AND THEIR DATA TYPES =========================== DATA TYPES ---------- Events use these data types: channel = a value 0 to 15 note = a value 0 to 127 dtime = a value 0 to 268,435,455 (0x0FFFFFFF) velocity = a value 0 to 127 channel = a value 0 to 15 patch = a value 0 to 127 sequence = a value 0 to 65,535 (0xFFFF) text = a string of 0 or more bytes of of ASCII text raw = a string of 0 or more bytes of binary data pitch_wheel = a value -8192 to 8191 (0x1FFF) song_pos = a value 0 to 16,383 (0x3FFF) song_number = a value 0 to 127 tempo = microseconds, a value 0 to 16,777,215 (0x00FFFFFF) For data types not defined above, (e.g., *sf* and *mi* for `'key_signature''), consult *Note MIDI/Filespec: MIDI/Filespec, and/or the source for `MIDI::Event.pm'. And if you don't see it documented, it's probably because I don't understand it, so you'll have to consult a real MIDI reference. EVENTS ------ And these are the events: ('note_off', dtime, channel, note, velocity) ('note_on', dtime, channel, note, velocity) ('key_after_touch', dtime, channel, note, velocity) ('control_change', dtime, channel, *controller(0-127)*, *value(0-127)*) ('patch_change', dtime, channel, patch) ('channel_after_touch', dtime, channel, velocity) ('pitch_wheel_change', dtime, channel, pitch_wheel) ('set_sequence_number', dtime, sequence) ('text_event', dtime, text) ('copyright_text_event', dtime, text) ('track_name', dtime, text) ('instrument_name', dtime, text) ('lyric', dtime, text) ('marker', dtime, text) ('cue_point', dtime, text) ('text_event_08', dtime, text) ('text_event_09', dtime, text) ('text_event_0a', dtime, text) ('text_event_0b', dtime, text) ('text_event_0c', dtime, text) ('text_event_0d', dtime, text) ('text_event_0e', dtime, text) ('text_event_0f', dtime, text) ('end_track', dtime) ('set_tempo', dtime, tempo) ('smpte_offset', dtime, *hr*, *mn*, *se*, *fr*, ff) ('time_signature', dtime, *nn*, dd, cc, *bb*) ('key_signature', dtime, *sf*, *mi*) ('sequencer_specific', dtime, raw) ('raw_meta_event', dtime, command(0-255), raw) ('sysex_f0', dtime, raw) ('sysex_f7', dtime, raw) ('song_position', dtime) ('song_select', dtime, song_number) ('tune_request', dtime) ('raw_data', dtime, raw) Three of the above events are represented a bit oddly from the point of view of the file spec: The parameter pitch_wheel for `'pitch_wheel_change'' is a value -8192 to 8191, although the actual encoding of this is as a value 0 to 16,383, as per the spec. Sysex events are represented as either `'sysex_f0'' or `'sysex_f7'', depending on the status byte they are encoded with. `'end_track'' is a bit stranger, in that it is almost never actually found, or needed. When the MIDI decoder sees an EOT (i.e., an end-track status: FF 2F 00) with a delta time of 0, it is *ignored*! If in the unlikely event that it has a nonzero delta-time, it's decoded as a `'text_event'' with whatever that delta-time is, and a zero-length text parameter. (This happens before the 'event_callback' or 'exclusive_event_callback' callbacks are given a crack at it.) On the encoding side, an EOT is added to the end of the track as a normal part of the encapsulation of track data. I chose to add this special behavior so that you could add events to the end of a track without having to work around any track-final `'end_track'' event. However, if you set `no_eot_magic' as a decoding parameter, none of this magic happens on the decoding side - `'end_track'' is decoded just as it is. And if you set `no_eot_magic' as an encoding parameter, then a track-final 0-length `'text_event'' with non-0 delta-times is left as is. Normally, such an event would be converted from a `'text_event'' to an `'end_track'' event with thath delta-time. Normally, no user needs to use the `no_eot_magic' option either in encoding or decoding. But it is provided in case you need your event LoL to be an absolutely literal representation of the binary data, and/or vice versa. MIDI BNF ======== For your reference (if you can make any sense of it), here is a copy of the MIDI BNF, as I found it in a text file that's been floating around the Net since the late 1980s. Note that this seems to describe MIDI events as they can occur in MIDI-on-the-wire. I *think* that realtime data insertion (i.e., the ability to have s popping up in the *middle* of messages) is something that can't happen in MIDI files. In fact, this library, as written, *can't* correctly parse MIDI data that has such realtime bytes inserted in messages. Nor does it support representing such insertion in a MIDI event structure that's encodable for writing to a file. (Although you could theoretically represent events with embedded s as just raw_data events; but then, you can always stow anything at all in a raw_data event.) 1. ::= < MIDI Stream> 2. ::= | 3. ::= | | 4. ::= 5. ::= 6. ::= 7. ::= 8. ::= C | D 9. ::= 8 | 9 | A | B | E 10. ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | 8 | 9 | A | B | C | D | E | F 11. ::= 12. ::= | | 13. ::= | 14. ::= | | 15. ::= 16. ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 17. ::= F8 | FA | FB | FC | FE | FF 18. ::= | | | | 19. ::= 20. ::= 21. ::= F0 22. ::= F7 23. ::= | | | | 24. ::= F6 25. ::= 26. ::= 27. ::=F2 28. ::= F3 AUTHOR ====== Sean M. Burke `sburke@cpan.org' (Except the BNF - who knows who's behind that.)  File: pm.info, Node: MIDI/Filespec, Next: MIDI/Opus, Prev: MIDI/Event, Up: Module List MIDI File Specification *********************** NAME ==== MIDI::Filespec - MIDI File Specification DESCRIPTION =========== This is a POD version of a text file widely available on the Net. The copy I found came with this note: This document is Dave Oppenheim's current version of the MIDI file specification, as sent to those who have participated in its development. The consensus seems to be to submit this to the MIDI Manufacturers' Association as version 1.0. I apologize for any loss of clarity that might have occurred in the conversion from a Microsoft Word document to this pure text file. I have removed some of the discussion about recent changes to the specification in order to keep the file size reasonable. -Doug Wyatt Moreover, these caveats are in order: * The file below is not everything you need to know about MIDI - not by a long shot. If you know MIDI-on-the-wire, this document tells you how to encapsulate that data into files - and that's about all it tells you. If you need to know the semantics (or even syntax) of, for example, key_after_touch, it's not in here. * In other words: the file below describes syntax, but is a bit thin on semantics sometimes. * The file below is, in terms of computers and computer music, quite vintage. However, code built to this spec runs just fine on all of the two-dozen or so MIDIs I pulled at random from various places on the Net for testing. The only thing I've found that's not in this spec is a meta-event of the form "FF 21 01 00" that seems to occur often as the first event in a track. (I infer it means "start track", but I don't know, so I've made no effort to deal with it other than to parse it as `('raw_meta_event', 0, 33, "\x00")'.) There may be other extensions that've been made to the standard, and which are being used, but I've not yet run into them. Email me if you run across any. * The example C code in the section "4. Program Fragments and Example MIDI Files" is not the optimal way to do "variable-length encoding" in Perl; Perl supports this natively as the "w" format in packing and unpacking. See the source for `MIDI::Event' for examples. Standard MIDI Files 0.06, March 1, 1988 ======================================== 0: Introduction =============== This describes a proposed standard MIDI file format. MIDI files contain one or more MIDI streams, with time information for each event. Song, sequence, and track structures, tempo and time signature information, are all supported. Track names and other descriptive information may be stored with the MIDI data. This format supports multiple tracks and multiple sequences so that if the user of a program which supports multiple tracks intends to move a file to another one, this format can allow that to happen. This spec defines the 8-bit binary data stream used in the file. The data can be stored in a binary file, nibbleized, 7-bit-ized for efficient MIDI transmission, converted to Hex ASCII, or translated symbolically to a printable text file. This spec addresses what's in the 8-bit stream. 1: Sequences, Tracks, Chunks: File Block Structure =================================================== Sequence files are made up of chunks. Each chunk has a 4-character type and a 32-bit length, which is the number of bytes in the chunk. On the Macintosh, data is passed either in the data fork of a file, or on the Clipboard. (The file type on the Macintosh for a file in this format will be "Midi".) On any other computer, the data is simply the contents of the file. This structure allows future chunk types to be designed which may easily be ignored if encountered by a program written before the chunk type is introduced. Your programs should expect alien chunks and treat them as if they weren't there. This proposal defines two types of chunks: a header chunk and a track chunk. A header chunk provides a minimal amount of information pertaining to the entire MIDI file. A track chunk contains a sequential stream of MIDI data which may contain information for up to 16 MIDI channels. The concepts of multiple tracks, multiple MIDI outputs, patterns, sequences, and songs may all be implemented using several track chunks. A MIDI file always starts with a header chunk, and is followed by one or more track chunks. MThd
MTrk MTrk ... Track Data Format (MTrk chunk type) ----------------------------------- The MTrk chunk type is where actual song data is stored. It is simply a stream of MIDI events (and non-MIDI events), preceded by delta-time values. Some numbers in MTrk chunks are represented in a form called a variable-length quantity. These numbers are represented 7 bits per byte, most significant bits first. All bytes except the last have bit 7 set, and the last byte has bit 7 clear. If the number is between 0 and 127, it is thus represented exactly as one byte. Here are some examples of numbers represented as variable-length quantities: Number (hex) Representation (hex) 00000000 00 00000040 40 0000007F 7F 00000080 81 00 00002000 C0 00 00003FFF FF 7F 00004000 81 80 00 00100000 C0 80 00 001FFFFF FF FF 7F 00200000 81 80 80 00 08000000 C0 80 80 00 0FFFFFFF FF FF FF 7F The largest number which is allowed is 0FFFFFFF so that the variable-length representation must fit in 32 bits in a routine to write variable-length numbers. Theoretically, larger numbers are possible, but 2 x 108 96ths of a beat at a fast tempo of 500 beats per minute is four days, long enough for any delta-time! Here is the syntax of an MTrk chunk: = + = is stored as a variable-length quantity. It represents the amount of time before the following event. If the first event in a track occurs at the very beginning of a track, or if two events occur simultaneously, a delta-time of zero is used. Delta-times are always present. (Not storing delta-times of 0 requires at least two bytes for any other value, and most delta-times aren't zero.) Delta-time is in some fraction of a beat (or a second, for recording a track with SMPTE times), as specified in the header chunk. = | | is any MIDI channel message. Running status is used: status bytes may be omitted after the first byte. The first event in a file must specify status. Delta-time is not considered an event itself: it is an integral part of the specification. Notice that running status occurs across delta-times. specifies non-MIDI information useful to this format or to sequencers, with this syntax: FF All meta-events begin with FF, then have an event type byte (which is always less than 128), and then have the length of the data stored as a variable-length quantity, and then the data itself. If there is no data, the length is 0. As with sysex events, running status is not allowed. As with chunks, future meta-events may be designed which may not be known to existing programs, so programs must properly ignore meta-events which they do not recognize, and indeed, should expect to see them. New for 0.06: programs must never ignore the length of a meta-event which they do recognize, and they shouldn't be surprised if it's bigger than they expected. If so, they must ignore everything past what they know about. However, they must not add anything of their own to the end of a meta-event. is used to specify a MIDI system exclusive message, or as an "escape" to specify any arbitrary bytes to be transmitted. Unfortunately, some synthesizer manufacturers specify that their system exclusive messages are to be transmitted as little packets. Each packet is only part of an entire syntactical system exclusive message, but the times they are transmitted at are important. Examples of this are the bytes sent in a CZ patch dump, or the FB-01's "system exclusive mode" in which microtonal data can be transmitted. To be able to handle situations like these, two forms of are provided: F0 F7 In both cases, is stored as a variable-length quantity. It is equal to the number of bytes following it, not including itself or the message type (F0 or F7), but all the bytes which follow, including any F7 at the end which is intended to be transmitted. The first form, with the F0 code, is used for syntactically complete system exclusive messages, or the first packet an a series - that is, messages in which the F0 should be transmitted. The second form is used for the remainder of the packets within a syntactic sysex message, which do not begin with F0. Of course, the F7 is not considered part of the system exclusive message. Of course, just as in MIDI, running status is not allowed, in this case because the length is stored as a variable-length quantity which may or may not start with bit 7 set. (New to 0.06) A syntactic system exclusive message must always end with an F7, even if the real-life device didn't send one, so that you know when you've reached the end of an entire sysex message without looking ahead to the next event in the MIDI file. This principle is repeated and illustrated in the paragraphs below. The vast majority of system exclusive messages will just use the F0 format. For instance, the transmitted message F0 43 12 00 07 F7 would be stored in a MIDI file as F0 05 43 12 00 07 F7. As mentioned above, it is required to include the F7 at the end so that the reader of the MIDI file knows that it has read the entire message. For special situations when a single system exclusive message is split up, with parts of it being transmitted at different times, such as in a Casio CZ patch transfer, or the FB-01's "system exclusive mode", the F7 form of sysex event is used for each packet except the first. None of the packets would end with an F7 except the last one, which must end with an F7. There also must not be any transmittable MIDI events in- between the packets of a multi-packet system exclusive message. Here is an example: suppose the bytes F0 43 12 00 were to be sent, followed by a 200-tick delay, followed by the bytes 43 12 00 43 12 00, followed by a 100-tick delay, followed by the bytes 43 12 00 F7, this would be in the MIDI File: F0 03 43 12 00 81 48 200-tick delta-time F7 06 43 12 00 43 12 00 64 100-tick delta-time F7 04 43 12 00 F7 The F7 event may also be used as an "escape" to transmit any bytes whatsoever, including real-time bytes, song pointer, or MIDI Time Code, which are not permitted normally in this specification. No effort should be made to interpret the bytes used in this way. Since a system exclusive message is not being transmitted, it is not necessary or appropriate to end the F7 event with an F7 in this case. 2. Header Chunk =============== The header chunk at the beginning of the file specifies some basic information about the data in the file. The data section contains three 16-bit words, stored high byte first (of course). Here's the syntax of the complete chunk: As described above, is the four ASCII characters 'MThd'; is a 32-bit representation of the number 6 (high byte first). The first word, format, specifies the overall organization of the file. Only three values of format are specified: 0 the file contains a single multi-channel track 1 the file contains one or more simultaneous tracks (or MIDI outputs) of a sequence 2 the file contains one or more sequentially independent single-track patterns The next word, ntrks, is the number of track chunks in the file. The third word, division, is the division of a quarter-note represented by the delta-times in the file. (If division is negative, it represents the division of a second represented by the delta-times in the file, so that the track can represent events occurring in actual time instead of metrical time. It is represented in the following way: the upper byte is one of the four values -24, -25, -29, or -30, corresponding to the four standard SMPTE and MIDI time code formats, and represents the number of frames per second. The second byte (stored positive) is the resolution within a frame: typical values may be 4 (MIDI time code resolution), 8, 10, 80 (bit resolution), or 100. This system allows exact specification of time-code-based tracks, but also allows millisecond-based tracks by specifying 25 frames/sec and a resolution of 40 units per frame.) Format 0, that is, one multi-channel track, is the most interchangeable representation of data. One application of MIDI files is a simple single-track player in a program which needs to make synthesizers make sounds, but which is primarily concerned with something else such as mixers or sound effect boxes. It is very desirable to be able to produce such a format, even if your program is track-based, in order to work with these simple programs. On the other hand, perhaps someone will write a format conversion from format 1 to format 0 which might be so easy to use in some setting that it would save you the trouble of putting it into your program. Programs which support several simultaneous tracks should be able to save and read data in format 1, a vertically one-dimensional form, that is, as a collection of tracks. Programs which support several independent patterns should be able to save and read data in format 2, a horizontally one-dimensional form. Providing these minimum capabilities will ensure maximum interchangeability. MIDI files can express tempo and time signature, and they have been chosen to do so for transferring tempo maps from one device to another. For a format 0 file, the tempo will be scattered through the track and the tempo map reader should ignore the intervening events; for a format 1 file, the tempo map must (starting in 0.04) be stored as the first track. It is polite to a tempo map reader to offer your user the ability to make a format 0 file with just the tempo, unless you can use format 1. All MIDI files should specify tempo and time signature. If they don't, the time signature is assumed to be 4/4, and the tempo 120 beats per minute. In format 0, these meta-events should occur at least at the beginning of the single multi-channel track. In format 1, these meta-events should be contained in the first track. In format 2, each of the temporally independent patterns should contain at least initial time signature and tempo information. We may decide to define other format IDs to support other structures. A program reading an unfamiliar format ID should return an error to the user rather than trying to read further. 3. Meta-Events ============== A few meta-events are defined herein. It is not required for every program to support every meta-event. Meta-events initially defined include: FF 00 02 ssss : Sequence Number ------------------------------- This optional event, which must occur at the beginning of a track, before any nonzero delta-times, and before any transmittable MIDI events, specifies the number of a sequence. The number in this track corresponds to the sequence number in the new Cue message discussed at the summer 1987 MMA meeting. In a format 2 MIDI file, it is used to identify each "pattern" so that a "song" sequence using the Cue message to refer to the patterns. If the ID numbers are omitted, the sequences' locations in order in the file are used as defaults. In a format 0 or 1 MIDI file, which only contain one sequence, this number should be contained in the first (or only) track. If transfer of several multitrack sequences is required, this must be done as a group of format 1 files, each with a different sequence number. FF 01 len text : Text Event --------------------------- Any amount of text describing anything. It is a good idea to put a text event right at the beginning of a track, with the name of the track, a description of its intended orchestration, and any other information which the user wants to put there. Text events may also occur at other times in a track, to be used as lyrics, or descriptions of cue points. The text in this event should be printable ASCII characters for maximum interchange. However, other character codes using the high-order bit may be used for interchange of files between different programs on the same computer which supports an extended character set. Programs on a computer which does not support non-ASCII characters should ignore those characters. (New for 0.06 ). Meta event types 01 through 0F are reserved for various types of text events, each of which meets the specification of text events(above) but is used for a different purpose: FF 02 len text : Copyright Notice --------------------------------- Contains a copyright notice as printable ASCII text. The notice should contain the characters (C), the year of the copyright, and the owner of the copyright. If several pieces of music are in the same MIDI file, all of the copyright notices should be placed together in this event so that it will be at the beginning of the file. This event should be the first event in the first track chunk, at time 0. FF 03 len text : Sequence/Track Name ------------------------------------ If in a format 0 track, or the first track in a format 1 file, the name of the sequence. Otherwise, the name of the track. FF 04 len text : Instrument Name -------------------------------- A description of the type of instrumentation to be used in that track. May be used with the MIDI Prefix meta-event to specify which MIDI channel the description applies to, or the channel may be specified as text in the event itself. FF 05 len text : Lyric ---------------------- A lyric to be sung. Generally, each syllable will be a separate lyric event which begins at the event's time. FF 06 len text : Marker ----------------------- Normally in a format 0 track, or the first track in a format 1 file. The name of that point in the sequence, such as a rehearsal letter or section name ("First Verse", etc.). FF 07 len text : Cue Point -------------------------- A description of something happening on a film or video screen or stage at that point in the musical score ("Car crashes into house", "curtain opens", "she slaps his face", etc.) FF 2F 00 : End of Track ----------------------- This event is not optional. It is included so that an exact ending point may be specified for the track, so that it has an exact length, which is necessary for tracks which are looped or concatenated. FF 51 03 tttttt : Set Tempo, in microseconds per MIDI quarter-note ------------------------------------------------------------------ This event indicates a tempo change. Another way of putting "microseconds per quarter-note" is "24ths of a microsecond per MIDI clock". Representing tempos as time per beat instead of beat per time allows absolutely exact long-term synchronization with a time-based sync protocol such as SMPTE time code or MIDI time code. This amount of accuracy provided by this tempo resolution allows a four-minute piece at 120 beats per minute to be accurate within 500 usec at the end of the piece. Ideally, these events should only occur where MIDI clocks would be located - this convention is intended to guarantee, or at least increase the likelihood, of compatibility with other synchronization devices so that a time signature/tempo map stored in this format may easily be transferred to another device. FF 54 05 hr mn se fr ff : SMPTE Offset -------------------------------------- (New in 0.06 - SMPTE Format specification) This event, if present, designates the SMPTE time at which the track chunk is supposed to start. It should be present at the beginning of the track, that is, before any nonzero delta-times, and before any transmittable MIDI events. The hour must be encoded with the SMPTE format, just as it is in MIDI Time Code. In a format 1 file, the SMPTE Offset must be stored with the tempo map, and has no meaning in any of the other tracks. The ff field contains fractional frames, in 100ths of a frame, even in SMPTE-based tracks which specify a different frame subdivision for delta-times. FF 58 04 nn dd cc bb : Time Signature ------------------------------------- The time signature is expressed as four numbers. nn and dd represent the numerator and denominator of the time signature as it would be notated. The denominator is a negative power of two: 2 represents a quarter-note, 3 represents an eighth-note, etc. The cc parameter expresses the number of MIDI clocks in a metronome click. The bb parameter expresses the number of notated 32nd-notes in a MIDI quarter-note (24 MIDI Clocks). This was added because there are already multiple programs which allow the user to specify that what MIDI thinks of as a quarter-note (24 clocks) is to be notated as, or related to in terms of, something else. Therefore, the complete event for 6/8 time, where the metronome clicks every three eighth-notes, but there are 24 clocks per quarter-note, 72 to the bar, would be (in hex): FF 58 04 06 03 24 08 That is, 6/8 time (8 is 2 to the 3rd power, so this is 06 03), 32 MIDI clocks per dotted-quarter (24 hex!), and eight notated 32nd-notes per MIDI quarter note. FF 59 02 sf mi Key Signature sf = -7: 7 flats sf = -1: 1 flat sf = 0: key of C sf = 1: 1 sharp sf = 7: 7 sharps mi = 0: major key mi = 1: minor key FF 7F len data : Sequencer-Specific Meta-Event ---------------------------------------------- Special requirements for particular sequencers may use this event type: the first byte or bytes of data is a manufacturer ID. However, as this is an interchange format, growth of the spec proper is preferred to use of this event type. This type of event may be used by a sequencer which elects to use this as its only file format; sequencers with their established feature-specific formats should probably stick to the standard features when using this format. 4. Program Fragments and Example MIDI Files =========================================== Here are some of the routines to read and write variable-length numbers in MIDI Files. These routines are in C, and use getc and putc, which read and write single 8-bit characters from/to the files infile and outfile. WriteVarLen (value) register long value; { register long buffer; buffer = value & 0x7f; while ((value >>= 7) > 0) { buffer <<= 8; buffer |= 0x80; buffer += (value & 0x7f); } while (TRUE) { putc(buffer,outfile); if (buffer & 0x80) buffer >>= 8; else break; } } doubleword ReadVarLen () { register doubleword value; register byte c; if ((value = getc(infile)) & 0x80) { value &= 0x7f; do { value = (value << 7) + ((c = getc(infile)) & 0x7f); } while (c & 0x80); } return (value); } As an example, MIDI Files for the following excerpt are shown below. First, a format 0 file is shown, with all information intermingled; then, a format 1 file is shown with all data separated into four tracks: one for tempo and time signature, and three for the notes. A resolution of 96 "ticks" per quarter note is used. A time signature of 4/4 and a tempo of 120, though implied, are explicitly stated. The contents of the MIDI stream represented by this example are broken down here: Delta Time | Event Code | Other Bytes | (decimal) | (hex) | (decimal) | Comment 0 FF 58 04 04 02 24 08 4 bytes: 4/4 time, 24 MIDI clocks/click, 8 32nd notes/24 MIDI clocks 0 FF 51 03 500000 3 bytes: 500,000 5sec per quarter-note 0 C0 5 Ch. 1, Program Change 5 0 C0 5 Ch. 1, Program Change 5 0 C1 46 Ch. 2, Program Change 46 0 C2 70 Ch. 3, Program Change 70 0 92 48 96 Ch. 3 Note On C2, forte 0 92 60 96 Ch. 3 Note On C3, forte 96 91 67 64 Ch. 2 Note On G3, mezzo-forte 96 90 76 32 Ch. 1 Note On E4, piano 192 82 48 64 Ch. 3 Note Off C2, standard 0 82 60 64 Ch. 3 Note Off C3, standard 0 81 67 64 Ch. 2 Note Off G3, standard 0 80 76 64 Ch. 1 Note Off E4, standard 0 FF 2F 00 Track End The entire format 0 MIDI file contents in hex follow. First, the header chunk: 4D 54 68 64 MThd 00 00 00 06 chunk length 00 00 format 0 00 01 one track 00 60 96 per quarter-note Then, the track chunk. Its header, followed by the events (notice that running status is used in places): 4D 54 72 6B MTrk 00 00 00 3B chunk length (59) Delta-time Event Comments 00 FF 58 04 04 02 18 08 time signature 00 FF 51 03 07 A1 20 tempo 00 C0 05 00 C1 2E 00 C2 46 00 92 30 60 00 3C 60 running status 60 91 43 40 60 90 4C 20 81 40 82 30 40 two-byte delta-time 00 3C 40 running status 00 81 43 40 00 80 4C 40 00 FF 2F 00 end of track A format 1 representation of the file is slightly different. Its header chunk: 4D 54 68 64 MThd 00 00 00 06 chunk length 00 01 format 1 00 04 four tracks 00 60 96 per quarter-note First, the track chunk for the time signature/tempo track. Its header, followed by the events: 4D 54 72 6B MTrk 00 00 00 14 chunk length (20) Delta-time Event Comments 00 FF 58 04 04 02 18 08 time signature 00 FF 51 03 07 A1 20 tempo 83 00 FF 2F 00 end of track Then, the track chunk for the first music track. The MIDI convention for note on/off running status is used in this example: 4D 54 72 6B MTrk 00 00 00 10 chunk length (16) Delta-time Event Comments 00 C0 05 81 40 90 4C 20 81 40 4C 00 Running status: note on, vel = 0 00 FF 2F 00 end of track Then, the track chunk for the second music track: 4D 54 72 6B MTrk 00 00 00 0F chunk length (15) Delta-time Event Comments 00 C1 2E 60 91 43 40 82 20 43 00 running status 00 FF 2F 00 end of track Then, the track chunk for the third music track: 4D 54 72 6B MTrk 00 00 00 15 chunk length (21) Delta-time Event Comments 00 C2 46 00 92 30 60 00 3C 60 running status 83 00 30 00 two-byte delta-time, running status 00 3C 00 running status 00 FF 2F 00 end of track 5. MIDI Transmission of MIDI Files ================================== Since it is inconvenient to exchange disks between different computers, and since many computers which will use this format will have a MIDI interface anyway, MIDI seems like a perfect way to send these files from one computer to another. And, while we're going through all the trouble to make a way of sending MIDI Files, it would be nice if they could send any files (like sampled sound files, text files, etc.) Goals ----- The transmission protocol for MIDI files should be reasonably efficient, should support fast transmission for computers which are capable of it, and slower transmission for less powerful ones. It should not be impossible to convert a MIDI File to or from an arbitrary internal representation on the fly as it is transmitted, but, as long as it is not too difficult, it is very desirable to use a generic method so that any file type could be accommodated. To make the protocol efficient, the MIDI transmission of these files will take groups of seven 8-bit bytes and transmit them as eight 7-bit MIDI data bytes. This is certainly in the spirit of the rest of this format (keep it small, because it's not that hard to do). To accommodate a wide range of transmission speeds, files will be transmitted in packets with acknowledge - this allows data to be stored to disk as it is received. If the sender does not receive a response from a reader in a certain amount of time, it can assume an open-loop situation, and then just continue. The last edition of MIDI Files contained a specialized protocol for sending just MIDI Files. To meet a deadline, unfortunately I don't have time right now to propose a new generalized protocol. This will be done within the next couple of months. I would welcome any proposals anyone else has, and would direct your attention to the proposal from Ralph Muha of Kurzweil, available in a recent MMA bulletin, and also directly from him.