This is a package to work with [Midi] files. It can be used to read, create and write midi file. The package is in [tcllib] format. Online help can be found http://wiki.tcl.tk/_repo/htmlfiles/tclmidi.html%|%here%|%. **News** * [jdc] 10-jul-2009 Source code and downloads now available at http://code.google.com/p/tclmidi * [jdc] 19-jun-2009 Project now hosted at http://code.google.com/p/tclmidi/ * [jdc] 20-mar-2008 Minor modifications to better support sequencing in combination with [midistreamdll]. * [jdc] 18-mar-2008 Update to the midi package. New options to the midi-file `flatten` method to skip (specific) Meta and/or SysEx events. * [jdc] 21-feb-2008 Initial public release. **Man page** <> [comment {-*- tcl -*- doctools manpage}] [manpage_begin midi n 0.11] [copyright {2006-2008 Jos Decoster }] [moddesc {Midi file, track and event handling}] [titledesc {Package to handle midi files, tracks and events}] [require Tcl 8.4] [description] [para] This page describes the Tcl [package midi] package to process midi files. The commands to read, write, create and edit midi files are discussed here. [para] The [package midi] package adds the namespace midi to the Tcl interpreter in which it is loaded. In this namespace, the main commands to work with midi files are created: [list_begin definitions] [lst_item midi::file] [lst_item midi::track] [lst_item midi::event] [list_end] [para] The file and track commands have an object interface, much like Tk widgets. Midi events are represented as a list of integers. [section midi::file] [list_begin definitions] [call [cmd midi::file] [opt [arg options]] ...] This command will create a midi file object and returns a unique midi file id. This id should be used to manipulate the midi file later on. Known options are: [list_begin opt] [opt_def -type integer] Set the midi file type. Must be [const 0], [const 1] or [const 2]. Default value is 1. [opt_def -time_division_type string] Set the time divisiob type used in the midi file. Must be [const ticks_per_beat] or [const frames_per_second]. Default values is [const ticks_per_beat]. [opt_def -ticks_per_beat integer] Sets the number of ticks per beat (quarter note), only used when the time division type is [const ticks_per_beat]. Default value is 480. [opt_def -frames_per_second integer] Set the number of frames per second, only used when the time division type is [const frames_per_second]. Default value is -1. [opt_def -ticks_per_frame integer] Set the number of ticks per frame, only used when the time division type is [const frames_per_second]. Default value is -1. [opt_def -tracks listOfTrackIds] Set the track to be included in the midi file. The tracks must be specified as a list of tracks id's obtained by calling the [cmd midi::track] command. By default, no tracks are added. [opt_def "" ""] [list_end] [call [arg midiFileId] [method destroy]] Reset and destroy a midi file object. [call [arg midiFileId] [method reset]] Reset a midi file object. Resetting a midi file object will clear the type and timing information and destroy all tracks (with reference count zero) of the midi file. [call [arg midiFileId] [method validate]] Validates a midi file object, including the tracks. Only the options required for a specific time division type are checked. [call [arg midiFileId] [method validate_option] [arg option] [arg value]] Validates a midi file object-option value. All options will be validated, even if a specified option is not necessary according to the time division type. All options accepted by the [cmd midi::file] command can be specified. [call [arg midiFileId] [method cget] [arg option]] Returns the current value of the configuration option given by [arg option]. [arg Option] may have any of the values accepted by the [cmd midi::file] command. [call [arg midiFileId] [method configure]] Returns a list describing all of the available options. The returned list contains a sublist for each known option with the following elements: the option, the default value and the current value. Information is returned for all options accepted by the [cmd midi::file] command. [call [arg midiFileId] [method configure] [arg option]] Returns list describing the named option. [arg Option] may have any of the values accepted by the [cmd midi::file] command. The returned list contains 3 elements: the option, the default value and the current value. [call [arg midiFileId] [method configure] [arg "option value"] ...] Modifies the given midi file option(s) to have the given value(s). The command returns an empty string. [arg Option] may have any of the values accepted by the [cmd midi::file] command. [call [arg midiFileId] [method read] [arg fileName]] Reads the specified midi file into the midi file object. [call [arg midiFileId] [method write] [arg fileName] [opt [arg "option value ..."]]] Writes the contents of the midi file object into the specified file. Known options are: [list_begin opt] [opt_def -running_status boolean] If set to true, the midi file will be written with running status, making the resulting output file smaller. If set to false (default), the midi file will be written without running status. [opt_def -tracks listOfTrackIds] Only write the specified tracks to the output file. [opt_def "" ""] [list_end] [call [arg midiFileId] [method dump] [opt [arg "option value ..."]]] Writes a textual representation of the midi file object contents into the file specified with the -file option. If no file is specified, returns the textual representation of the midi file as a string. Known options are: [list_begin opt] [opt_def -file path] Dump the midi file to the specified output file. [opt_def -tracks listOfTrackIds] Only dump the specified tracks. [opt_def "" ""] [list_end] [call [arg midiFileId] [method flatten] [opt [arg "option value ..."]]] Creates a one track representation of a multi track midi file. This command will return a list of two element lists. The first element in each sub-list contains the delta time until the event associated with it can be processed. The second element in each sub-list contains a list of events, represented as lists of integers. Known options are: [list_begin opt] [opt_def -include_meta listOfMetaEventTypes] Only include Meta events of specified types in the flattened output. Check [cmd midi::event::type_meta_event] for known Meta event types. [opt_def -no_meta boolean] Do not include Meta events in the flattened output. [opt_def -no_sys_ex boolean] Do not include SysEx events in the flattened output. [opt_def -tracks listOfTrackIds] Only flatten the specified tracks. [opt_def "" ""] [list_end] [call [arg midiFileId] [method clicks] [arg "noteLength"]] Calculates the length of a note in clicks for common note lengths. Lengths understood by this method are: [const 1], [const 1.], [const 1/2], [const 1/2.], [const 1/2t], [const 1/4], [const 1/4.], [const 1/4t], [const 1/8], [const 1/8.], [const 1/8t], [const 1/16], [const 1/16.], [const 1/16t], [const 1/32], [const 1/32.], [const 1/32t], [const 1/64], [const 1/64.] and [const 1/64t.] Lengths with a [const .] (dot) add half of the length to the fraction, lengths with a [const t] are used for triplets. This functions can only be used when the [option -time_division_type] option is set to [const ticks_per_beat] and the [option -ticks_per_beat] option has been initialised. [call [arg midiFileId] [method measure] [opt [arg "option value ..."]]] This command can be used to generate event list from a simplied input format. By only specifying note names and durations, an event list suitable for midi-tracks can be obtained. This command will only generate note-on and note-off event, other event still need to be added to the event list with the [cmd midi::event] command. Only a list of non-overlapping notes can be specified. It durations of notes overlap, create different event-lists with multiple calls to this command and later on merge the resulting event lists with the [cmd midi::merge] command. [list_begin opt] [opt_def -channel integer] Channel on which to play the specified notes. [opt_def -events listOfListOfNotes] A list of note-lists. Each such note-list contains a duration, a list of notes and optionally a velocity. A duration must be specified as a note-length understood by the [cmd midi::file::clicks] method. Notes can be specified using their midi note-number or their note-name. Check the [sectref Notes] section for valid note numbers and valid note names. In addition to the notes found in that section, it is possible to use [const r] or [const R] to specify a rest. The optional velocity must be an integer in the range 0..127. Default value is 127. The following example show how to generate an event list of a C-major scale played as quarter notes and followed by a C-major chord on channel 4: [example_begin] set mf [lb]midi::file -type 1 -time_division_type ticks_per_beat -ticks_per_beat 480[rb] set el [lb]$mf measure -channel 4 -events {{1/4 C5} {1/4 D5} {1/4 E5} {1/4 F5} {1/4 G5} {1/4 A5} {1/4 B5} {1/4 C6} {1/1 {C5 E5 G5 C6}}}[rb] [example_end] Check the [sectref Examples] sections for more examples of using this method. [opt_def "" ""] [list_end] [list_end] [section midi::track] [list_begin definitions] [call [cmd midi::track] [opt [arg options]] ...] This command will create a midi track object and return a unique midi track id. This id should be used to manipulate the midi track later on. Known options are: [list_begin opt] [opt_def -events listOfEvents] Specifies a list of events with associated delta-time for the midi track. An event with its associated delta-time is represented as a list of the delta-time and a list of integers representing the event. By default, no events are added to a track. A delta time specifies the time to wait before processing the associated event. A delta time is expressed in clock ticks. When using [const ticks_per_beat] as time division type, the duration of a note can be calculated based on the specified ticks per beat. When 480 clock clicks are required for a quarter note, the length in clicks of other note lengths is as follows: [example_begin] lengthInClicks = 480.0 * 4 * length [example_end] Using this function, the lengths of different notes can be calculated: [example_begin] length length in clicks ------ ---------------- 1 1920 1/2 960 1/4 480 1/8 240 1/16 120 1/32 60 1/64 30 [example_end] The [cmd midi::file::clicks] method can be used to calculate lengths in clicks for common note lengths. [opt_def "" ""] [list_end] [call [arg midiTrackId] [method destroy]] Reset and destroy a midi track object. [call [arg midiTrackId] [method reset]] Reset a midi track object. Resetting a midi track object removes all events from the midi track. [call [arg midiTrackId] [method validate]] Validates a midi track object, including the events. [call [arg midiTrackId] [method validate_option] [arg option] [arg value]] Validates a midi track object option value. All options accepted by the [cmd midi::track] command can be specified. [call [arg midiTrackId] [method cget] [arg option]] Returns the current value of the configuration option given by [arg option]. [arg Option] may have any of the values accepted by the [cmd midi::track] command. [call [arg midiTrackId] [method configure]] Returns a list describing all of the available options. The returned list contains a sublist for each known option with the following elements: the option, the default value and the current value. Information is returned for all options accepted by the [cmd midi::track] command. [call [arg midiTrackId] [method configure] [arg option]] Returns list describing the named option. [arg Option] may have any of the values accepted by the [cmd midi::track] command. The returned list contains 3 elements: the option, the default value and the current value. [call [arg midiTrackId] [method configure] [arg "option value"] ...] Modifies the given midi track option(s) to have the given value(s). The command returns an empty string. [arg Option] may have any of the values accepted by the [cmd midi::track] command. [call [arg midiTrackId] [method dump]] Returns a textual representation of the midi track. [list_end] [section midi::event] Events are represented as a list of integers. Each integer contains the value of a byte in the binary midi event as stored in a midi file. The commands listed below make it easier to create and manipulate midi events. These commands offer a configure interface. Supported events with associated options can be found in the [sectref Events] section. [list_begin definitions] [call [cmd midi::event] [arg type] [opt [arg options]] ...] Creates a new event of the specified type. Check the [sectref Events] section for valid event types and associated options. The newly created event is returned as a list of integers. This list must be specified with the other event commands or when adding events to a track. [call [cmd midi::event::reset] [arg intList]] This command returns a list of integers for an event of the same type but with all option values set to their defautl values. [call [cmd midi::event::validate] [arg intList]] Checks if the specified list of integers is a valid event. [call [cmd midi::event::validate_option] [arg intList] [opt [arg options]] ...] Validates a midi event object option value. All options accepted by the midi event type can be specified. [call [cmd midi::event::cget] [arg intList] [arg option]] Returns the current value of the configuration option given by [arg option]. [arg Option] may have any of the values accepted by the event type. [call [cmd midi::event::configure] [arg intList]] Returns a list describing all of the available options for the type of the specified event. The returned list contains a sublist for each known option with the following elements: the option, the default value and the current value. [call [cmd midi::event::configure] [arg intList] [arg option]] Returns list describing the named option. [arg Option] may have any of the values accepted by the event type. The returned list contains 3 elements: the option, the default value and the current value. [call [cmd midi::event::configure] [arg intList] [arg "option value"] ...] Modifies the given midi event option(s) to have the given value(s). The command returns an empty string. [arg Option] may have any of the values accepted by the event type. [call [cmd midi::event::type] [arg intList]] Return the type of the specified event. Possible return values are: [const note_off] [const note_on] [const note_aftertouch] [const controller] [const program_change] [const channel_aftertouch] [const pitch_bend] [const Meta] [const SysEx] [call [cmd midi::event::type_meta_event] [arg intList]] Returns meta event type. Possible return values are: [const sequence_number] [const copyright] [const track_name] [const instrument_name] [const lyric] [const marker] [const cue_point] [const program_name] [const device_name] [const channel] [const port] [const end_of_track] [const tempo] [const smpte_offset] [const time_signature] [const key_signature] [const sequencer_specific] [const meta_unknown] [call [cmd midi::event::dump] [arg intList]] Returns a textual representation of the midi event. [list_end] [section Examples] The following example creates a midi file with 4 tracks. All events are generated using the [cmd midi::event] command. [example_begin] package require midi # Create midi file and initialise time division info set mf [lb]midi::file -type 1 -time_division_type ticks_per_beat -ticks_per_beat 480[rb] # Control track set t1el {} lappend t1el [lb]list 0 [lb]midi::event text -value "control track"[rb][rb] lappend t1el [lb]list 0 [lb]midi::event tempo -tempo 0X7A120[rb][rb] ;# 120 Beats per minute lappend t1el [lb]list 0 [lb]midi::event end_of_track[rb][rb] set t1 [lb]midi::track -events $t1el[rb] # Piano track set t2el {} lappend t2el [lb]list 0 [lb]midi::event text -value "Piano track"[rb][rb] lappend t2el [lb]list 0 [lb]midi::event program_change -channel 0 -program "Electric Piano 2"[rb][rb] lappend t2el [lb]list 0 [lb]midi::event note_on -channel 0 -note C4 -velocity 127[rb][rb] lappend t2el [lb]list [lb]$mf clicks 1/1[rb] [lb]midi::event note_off -channel 0 -note C4 -velocity 127[rb][rb] lappend t2el [lb]list 0 [lb]midi::event note_on -channel 0 -note E4 -velocity 127[rb][rb] lappend t2el [lb]list [lb]$mf clicks 1/1[rb] [lb]midi::event note_off -channel 0 -note E4 -velocity 127[rb][rb] lappend t2el [lb]list 0 [lb]midi::event note_on -channel 0 -note G4 -velocity 127[rb][rb] lappend t2el [lb]list [lb]$mf clicks 1/1[rb] [lb]midi::event note_off -channel 0 -note G4 -velocity 127[rb][rb] lappend t2el [lb]list 0 [lb]midi::event note_on -channel 0 -note C5 -velocity 127[rb][rb] lappend t2el [lb]list [lb]$mf clicks 1/1[rb] [lb]midi::event note_off -channel 0 -note C5 -velocity 127[rb][rb] lappend t2el [lb]list 0 [lb]midi::event note_on -channel 0 -note C4 -velocity 127[rb][rb] lappend t2el [lb]list 0 [lb]midi::event note_on -channel 0 -note E4 -velocity 127[rb][rb] lappend t2el [lb]list 0 [lb]midi::event note_on -channel 0 -note G4 -velocity 127[rb][rb] lappend t2el [lb]list 0 [lb]midi::event note_on -channel 0 -note C5 -velocity 127[rb][rb] lappend t2el [lb]list [lb]$mf clicks 1/1[rb] [lb]midi::event note_off -channel 0 -note C4 -velocity 127[rb][rb] lappend t2el [lb]list 0 [lb]midi::event note_off -channel 0 -note E4 -velocity 127[rb][rb] lappend t2el [lb]list 0 [lb]midi::event note_off -channel 0 -note G4 -velocity 127[rb][rb] lappend t2el [lb]list 0 [lb]midi::event note_off -channel 0 -note C5 -velocity 127[rb][rb] lappend t2el [lb]list 0 [lb]midi::event end_of_track[rb][rb] set t2 [lb]midi::track -events $t2el[rb] # Bass track set t3el {} lappend t3el [lb]list 0 [lb]midi::event text -value "Bass track"[rb][rb] lappend t3el [lb]list 0 [lb]midi::event program_change -channel 1 -program "Electric Bass(pick)"[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note C2 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 1 -note C2 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note D2 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 1 -note D2 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note E2 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 1 -note E2 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note F2 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 1 -note F2 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note E2 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 1 -note E2 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note F2 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 1 -note F2 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note G2 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 1 -note G2 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note A2 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 1 -note A2 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note G2 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 1 -note G2 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note A2 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 1 -note A2 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note B2 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 1 -note B2 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note C3 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 1 -note C3 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note C3 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/2[rb] [lb]midi::event note_off -channel 1 -note C3 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note G2 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 1 -note G2 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note E2 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 1 -note E2 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event note_on -channel 1 -note C2 -velocity 127[rb][rb] lappend t3el [lb]list [lb]$mf clicks 1/1[rb] [lb]midi::event note_off -channel 1 -note C2 -velocity 127[rb][rb] lappend t3el [lb]list 0 [lb]midi::event end_of_track[rb][rb] set t3 [lb]midi::track -events $t3el[rb] # Drum track set t4el {} lappend t4el [lb]list 0 [lb]midi::event text -value "Drum track"[rb][rb] lappend t4el [lb]list 0 [lb]midi::event note_on -channel 9 -note "closed hi-hat" -velocity 127[rb][rb] lappend t4el [lb]list 0 [lb]midi::event note_on -channel 9 -note "acoustic bass drum" -velocity 127[rb][rb] lappend t4el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 9 -note "closed hi-hat" -velocity 127[rb][rb] lappend t4el [lb]list 0 [lb]midi::event note_on -channel 9 -note "closed hi-hat" -velocity 127[rb][rb] lappend t4el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 9 -note "closed hi-hat" -velocity 127[rb][rb] lappend t4el [lb]list 0 [lb]midi::event note_on -channel 9 -note "closed hi-hat" -velocity 127[rb][rb] lappend t4el [lb]list 0 [lb]midi::event note_on -channel 9 -note "acoustic snare" -velocity 127[rb][rb] lappend t4el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 9 -note "closed hi-hat" -velocity 127[rb][rb] lappend t4el [lb]list 0 [lb]midi::event note_on -channel 9 -note "closed hi-hat" -velocity 127[rb][rb] for { set i 0 } { $i < 4 } { incr i } { lappend t4el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 9 -note "closed hi-hat" -velocity 127[rb][rb] lappend t4el [lb]list 0 [lb]midi::event note_on -channel 9 -note "closed hi-hat" -velocity 127[rb][rb] lappend t4el [lb]list 0 [lb]midi::event note_off -channel 9 -note "acoustic bass drum" -velocity 127[rb][rb] lappend t4el [lb]list 0 [lb]midi::event note_on -channel 9 -note "acoustic bass drum" -velocity 127[rb][rb] lappend t4el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 9 -note "closed hi-hat" -velocity 127[rb][rb] lappend t4el [lb]list 0 [lb]midi::event note_on -channel 9 -note "closed hi-hat" -velocity 127[rb][rb] lappend t4el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 9 -note "closed hi-hat" -velocity 127[rb][rb] lappend t4el [lb]list 0 [lb]midi::event note_on -channel 9 -note "closed hi-hat" -velocity 127[rb][rb] lappend t4el [lb]list 0 [lb]midi::event note_off -channel 9 -note "acoustic snare" -velocity 127[rb][rb] lappend t4el [lb]list 0 [lb]midi::event note_on -channel 9 -note "acoustic snare" -velocity 127[rb][rb] lappend t4el [lb]list [lb]$mf clicks 1/4[rb] [lb]midi::event note_off -channel 9 -note "closed hi-hat" -velocity 127[rb][rb] lappend t4el [lb]list 0 [lb]midi::event note_on -channel 9 -note "closed hi-hat" -velocity 127[rb][rb] } lappend t4el [lb]list 0 [lb]midi::event end_of_track[rb][rb] set t4 [lb]midi::track -events $t4el[rb] # Add tracks and write file $mf configure -tracks [lb]list $t1 $t2 $t3 $t4[rb] $mf write test.mid $mf destroy exit [example_end] The following examples uses the [cmd midi::file::measure] method to generate the same note-on and note-off events as in the example above. This example requires Tcl 8.5 because it uses the {*} operator. [example_begin] lappend auto_path .. package require Tcl 8.5 package require midi # Create midi file and initialise time division info set mf [lb]midi::file -type 1 -time_division_type ticks_per_beat -ticks_per_beat 480[rb] # Control track set t1el {} lappend t1el [lb]list 0 [lb]midi::event text -value "control track"[rb][rb] lappend t1el [lb]list 0 [lb]midi::event tempo -tempo 0X7A120[rb][rb] ;# 120 Beats per minute lappend t1el [lb]list 0 [lb]midi::event end_of_track[rb][rb] set t1 [lb]midi::track -events $t1el[rb] # Piano track set at2el {} lappend at2el [lb]list 0 [lb]midi::event text -value "Piano track"[rb][rb] lappend at2el [lb]list 0 [lb]midi::event program_change -channel 0 -program "Electric Piano 2"[rb][rb] lappend at2el {*}[lb]$mf measure -channel 0 -events {{1/1 C4} {1/1 E4} {1/1 G4} {1/1 C5} {1/1 {C4 E4 G4 C5}}}[rb] lappend at2el [lb]list 0 [lb]midi::event end_of_track[rb][rb] set t2 [lb]midi::track -events $at2el[rb] # Bass track set at3el {} lappend at3el [lb]list 0 [lb]midi::event text -value "Bass track"[rb][rb] lappend at3el [lb]list 0 [lb]midi::event program_change -channel 1 -program "Electric Bass(pick)"[rb][rb] lappend at3el {*}[lb]$mf measure -channel 1 -events {{1/4 C2} {1/4 D2} {1/4 E2} {1/4 F2}}[rb] lappend at3el {*}[lb]$mf measure -channel 1 -events {{1/4 E2 60} {1/4 F2} {1/4 G2} {1/4 A2}}[rb] lappend at3el {*}[lb]$mf measure -channel 1 -events {{1/4 G2} {1/4 A2} {1/4 B2} {1/4 C3}}[rb] lappend at3el {*}[lb]$mf measure -channel 1 -events {{1/2 C3} {1/4 G2} {1/4 E2}}[rb] lappend at3el {*}[lb]$mf measure -channel 1 -events {{1/1 C2}}[rb] lappend at3el [lb]list 0 [lb]midi::event end_of_track[rb][rb] set t3 [lb]midi::track -events $at3el[rb] # Drum track set at4el {} lappend at4el [lb]list 0 [lb]midi::event text -value "Drum track"[rb][rb] for { set i 0 } { $i < 5 } { incr i } { lappend at4el {*}[lb]$mf measure -channel 9 -events { {1/4 {"closed hi-hat" "acoustic bass drum"}} \ {1/4 {"closed hi-hat"}} \ {1/4 {"closed hi-hat" "acoustic snare"}} \ {1/4 {"closed hi-hat"}} \ }[rb] } lappend at4el [lb]list 0 [lb]midi::event end_of_track[rb][rb] set t4 [lb]midi::track -events $at4el[rb] # Add tracks and write file $mf configure -tracks [lb]list $t1 $t2 $t3 $t4[rb] $mf write test2.mid $mf destroy exit [example_end] This example shows how the rests and the [cmd midi::merge] command can be used to generate an event-list for the first track of the example above: [example_begin] set t1 [lb]midi::track -events $t1el[rb] # Piano track set at2el {} lappend at2el [lb]list 0 [lb]midi::event text -value "Piano track"[rb][rb] lappend at2el [lb]list 0 [lb]midi::event program_change -channel 0 -program "Electric Piano 2"[rb][rb] set te1 [lb]$mf measure -channel 0 -events {{1/1 C4} {1/1 r} {1/1 G4} {1/1 R} {1/1 {r E4 r C5}}}[rb] set te2 [lb]$mf measure -channel 0 -events {{1/1 R} {1/1 E4} {1/1 r} {1/1 C5} {1/1 {C4 r G4 r }}}[rb] lappend at2el {*}[lb]midi::merge $te1 $te2[rb] lappend at2el [lb]list 0 [lb]midi::event end_of_track[rb][rb] set t2 [lb]midi::track -events $at2el[rb] [example_end] This example reads the midi file specified on the command line and dumps the contents to standard output: [example_begin] package require midi set mf [lb]midi::file[rb] $mf read [lb]lindex $argv 0[rb] puts [lb]$mf dump[rb] $mf destroy exit [example_end] The result of the dump command looks like this: [example_begin] MThd header size: 6 format type: 1 number of tracks: 4 time division: 480 ticks per beat MTrk Delta time Absolute time Event ------------- ------------- ---------------------------------------- 0 0 text control track 0 0 tempo 500000 0 0 end_of_track MTrk Delta time Absolute time Event ------------- ------------- ---------------------------------------- 0 0 text Piano track 0 0 program_change channel 0x00, program 0x04 0 0 note_on channel 0x00, note 0x3C, velocity 0x7F 1920 1920 note_off channel 0x00, note 0x3C, velocity 0x7F 0 1920 note_on channel 0x00, note 0x40, velocity 0x7F 1920 3840 note_off channel 0x00, note 0x40, velocity 0x7F 0 3840 note_on channel 0x00, note 0x43, velocity 0x7F 1920 5760 note_off channel 0x00, note 0x43, velocity 0x7F 0 5760 note_on channel 0x00, note 0x48, velocity 0x7F 1920 7680 note_off channel 0x00, note 0x48, velocity 0x7F 0 7680 note_on channel 0x00, note 0x3C, velocity 0x7F 0 7680 note_on channel 0x00, note 0x40, velocity 0x7F 0 7680 note_on channel 0x00, note 0x43, velocity 0x7F 0 7680 note_on channel 0x00, note 0x48, velocity 0x7F 1920 9600 note_off channel 0x00, note 0x3C, velocity 0x7F 0 9600 note_off channel 0x00, note 0x40, velocity 0x7F 0 9600 note_off channel 0x00, note 0x43, velocity 0x7F 0 9600 note_off channel 0x00, note 0x48, velocity 0x7F 0 9600 end_of_track MTrk Delta time Absolute time Event ------------- ------------- ---------------------------------------- 0 0 text Bass track 0 0 program_change channel 0x01, program 0x22 0 0 note_on channel 0x01, note 0x24, velocity 0x7F 480 480 note_off channel 0x01, note 0x24, velocity 0x7F 0 480 note_on channel 0x01, note 0x26, velocity 0x7F 480 960 note_off channel 0x01, note 0x26, velocity 0x7F 0 960 note_on channel 0x01, note 0x28, velocity 0x7F 480 1440 note_off channel 0x01, note 0x28, velocity 0x7F 0 1440 note_on channel 0x01, note 0x29, velocity 0x7F 480 1920 note_off channel 0x01, note 0x29, velocity 0x7F 0 1920 note_on channel 0x01, note 0x28, velocity 0x7F 480 2400 note_off channel 0x01, note 0x28, velocity 0x7F 0 2400 note_on channel 0x01, note 0x29, velocity 0x7F 480 2880 note_off channel 0x01, note 0x29, velocity 0x7F 0 2880 note_on channel 0x01, note 0x2B, velocity 0x7F 480 3360 note_off channel 0x01, note 0x2B, velocity 0x7F 0 3360 note_on channel 0x01, note 0x2D, velocity 0x7F 480 3840 note_off channel 0x01, note 0x2D, velocity 0x7F 0 3840 note_on channel 0x01, note 0x2B, velocity 0x7F 480 4320 note_off channel 0x01, note 0x2B, velocity 0x7F 0 4320 note_on channel 0x01, note 0x2D, velocity 0x7F 480 4800 note_off channel 0x01, note 0x2D, velocity 0x7F 0 4800 note_on channel 0x01, note 0x2F, velocity 0x7F 480 5280 note_off channel 0x01, note 0x2F, velocity 0x7F 0 5280 note_on channel 0x01, note 0x30, velocity 0x7F 480 5760 note_off channel 0x01, note 0x30, velocity 0x7F 0 5760 note_on channel 0x01, note 0x30, velocity 0x7F 960 6720 note_off channel 0x01, note 0x30, velocity 0x7F 0 6720 note_on channel 0x01, note 0x2B, velocity 0x7F 480 7200 note_off channel 0x01, note 0x2B, velocity 0x7F 0 7200 note_on channel 0x01, note 0x28, velocity 0x7F 480 7680 note_off channel 0x01, note 0x28, velocity 0x7F 0 7680 note_on channel 0x01, note 0x24, velocity 0x7F 1920 9600 note_off channel 0x01, note 0x24, velocity 0x7F 0 9600 end_of_track MTrk Delta time Absolute time Event ------------- ------------- ---------------------------------------- 0 0 text Drum track 0 0 note_on channel 0x09, note 0x2A, velocity 0x7F 0 0 note_on channel 0x09, note 0x24, velocity 0x7F 480 480 note_on channel 0x09, note 0x2A, velocity 0x7F 480 960 note_on channel 0x09, note 0x2A, velocity 0x7F 0 960 note_on channel 0x09, note 0x26, velocity 0x7F 480 1440 note_on channel 0x09, note 0x2A, velocity 0x7F 480 1920 note_on channel 0x09, note 0x2A, velocity 0x7F 0 1920 note_on channel 0x09, note 0x24, velocity 0x7F 480 2400 note_on channel 0x09, note 0x2A, velocity 0x7F 480 2880 note_on channel 0x09, note 0x2A, velocity 0x7F 0 2880 note_on channel 0x09, note 0x26, velocity 0x7F 480 3360 note_on channel 0x09, note 0x2A, velocity 0x7F 480 3840 note_on channel 0x09, note 0x2A, velocity 0x7F 0 3840 note_on channel 0x09, note 0x24, velocity 0x7F 480 4320 note_on channel 0x09, note 0x2A, velocity 0x7F 480 4800 note_on channel 0x09, note 0x2A, velocity 0x7F 0 4800 note_on channel 0x09, note 0x26, velocity 0x7F 480 5280 note_on channel 0x09, note 0x2A, velocity 0x7F 480 5760 note_on channel 0x09, note 0x2A, velocity 0x7F 0 5760 note_on channel 0x09, note 0x24, velocity 0x7F 480 6240 note_on channel 0x09, note 0x2A, velocity 0x7F 480 6720 note_on channel 0x09, note 0x2A, velocity 0x7F 0 6720 note_on channel 0x09, note 0x26, velocity 0x7F 480 7200 note_on channel 0x09, note 0x2A, velocity 0x7F 480 7680 note_on channel 0x09, note 0x2A, velocity 0x7F 0 7680 note_on channel 0x09, note 0x24, velocity 0x7F 480 8160 note_on channel 0x09, note 0x2A, velocity 0x7F 480 8640 note_on channel 0x09, note 0x2A, velocity 0x7F 0 8640 note_on channel 0x09, note 0x26, velocity 0x7F 480 9120 note_on channel 0x09, note 0x2A, velocity 0x7F 0 9120 end_of_track [example_end] [section Events] [list_begin definitions] [lst_item sequence_number] Event containing the sequence number of the track in which this event is placed. [list_begin opt] [opt_def -value integer] The sequence number of the track. The default value is [const 0]. [opt_def "" ""] [list_end] [lst_item text] Text describing the track in which this event is placed. [list_begin opt] [opt_def -value string] File or track description. The default value is an empty string. [opt_def "" ""] [list_end] [lst_item copyright] Midi file copyright notice. [list_begin opt] [opt_def -value string] Copyright text. The default value is an empty string. [opt_def "" ""] [list_end] [lst_item track_name] Name of track. [list_begin opt] [opt_def -value string] Track name. The default value is an empty string. [opt_def "" ""] [list_end] [lst_item instrument_name] Name of instrument used in track. [list_begin opt] [opt_def -value string] Instrument name. The default value is an empty string. [opt_def "" ""] [list_end] [lst_item lyric] Lyric to be sung at the point this event is placed. This can be a word or syllable. [list_begin opt] [opt_def -value string] Lyric. The default value is an empty string. [opt_def "" ""] [list_end] [lst_item marker] Marker for specific point in track like rehearsal letter, section name, loop start or loop end. [list_begin opt] [opt_def -value string] Marker text. The default value is an empty string. [opt_def "" ""] [list_end] [lst_item cue_point] Description of something which happens at the point this event is placed. [list_begin opt] [opt_def -value string] Descriptive text. The default value is an empty string. [opt_def "" ""] [list_end] [lst_item program_name] Name of the program used in the events following. [list_begin opt] [opt_def -value string] Program name. The default value is an empty string. [opt_def "" ""] [list_end] [lst_item device_name] Name of the midi device (port) where the track is routed. [list_begin opt] [opt_def -value string] Device name. The default value is an empty string. [opt_def "" ""] [list_end] [lst_item channel] Specifies the channel to which following meta and system exclusive must be sent. (DEPRECATED) [list_begin opt] [opt_def -channel integer] Channel number. The default value is 0. Check the [sectref Channels] section for valid channel numbers. [opt_def "" ""] [list_end] [lst_item port] Midi port to which following midi events must be sent. (DEPRECATED) [list_begin opt] [opt_def -port] Port number. The default value is 0. [opt_def "" ""] [list_end] [lst_item end_of_track] Marks the end of a track. Must be placed at the end of every track. [lst_item tempo] Used to indicate tempo changes. [list_begin opt] [opt_def -tempo integer] Tempo expressed in micro seconds per quarter note. The default value is 0x07A120 which corresponds to 120 BPM. [opt_def "" ""] [list_end] [lst_item smpte_offset] Specifies the start time of the track. [list_begin opt] [opt_def -hours integer] Hours part of start time. Default value is 0. [opt_def -minutes integer] Minutes part of start time. Default value is 0. [opt_def -seconds integer] Seconds part of start time. Default value is 0. [opt_def -frames integer] Frame count part of start time. Default value is 0. [opt_def -framefractions integer] Frame fraction part of start time. Default value is 0. [opt_def "" ""] [list_end] [lst_item time_signature] Used to specify the time signature. [list_begin opt] [opt_def -numerator integer] Numerator part of time signature. Default value is 0. [opt_def -denominator integer] Denominator part of the time signature. This values must be an integer power of 2 (2, 4, 8). Default value is 1. [opt_def -clocks_ticks_between_metronome_clicks integer] The number of midi clock cliks in one metronome click. Default value is 0. [opt_def -notated_32nd_notes_in_quarter_note integer] The number of notated 32nd notes in a midi quarter note. Default value is 0. [opt_def "" ""] [list_end] [lst_item key_signature] Sets the key signature. [list_begin opt] [opt_def -number_of_modifications integer] The number of modifications. Positive numbers (1..7) for sharps, negative numbers (-1..-7) for flats. Default value is 0. [opt_def -scale integer] Set to 0 for major scale or to 1 for minor scale. Default values is 0. [opt_def "" ""] [list_end] [lst_item sequencer_specific] Used to send data to a sequencer. These events are not interpreted by this packages. [list_begin opt] [opt_def -data listOfIntegers] The data to be sent as a list of integers without the size of the data. Default value is an empty list. [opt_def "" ""] [list_end] [lst_item meta_unknown] Meta event. These events are not interpreted by this packages. [list_begin opt] [opt_def -meta_unknown_event_type integer] Meta event type. Default values is 0. [opt_def -data listOfIntegers] Data associated with the meta event specified as a list of integers without the size of the data. Default value is an empty list. [opt_def "" ""] [list_end] [lst_item SysEx] System exclusive event. These events are not interpreted by this packages. [list_begin opt] [opt_def -sysex_event_type] System exclusive event type. Default values is 0. [opt_def -data] Data associated with the system exclusive event specified as a list of integers without the size of the data. Default value is an empty list. [opt_def "" ""] [list_end] [lst_item note_on] Play a note. [list_begin opt] [opt_def -channel integer] Channel on which to play the note. Check the [sectref Channels] section for valid channel numbers. Default value is 0. [opt_def -note note] Note to play. Check the [sectref Notes] section for valid note numbers and valid note names. Default value is 0. [opt_def -velocity integer] Velocity (volume) with which to hit the note. Must be an integer in the range 0..127. Default value is 0. [opt_def "" ""] [list_end] [lst_item note_off] Stop a note. [list_begin opt] [opt_def -channel integer] Channel on which to stop the note. Check the [sectref Channels] section for valid channel numbers. Default value is 0. [opt_def -note note] Note to stop. Check the [sectref Notes] section for valid note numbers and valid note names. Default value is 0. [opt_def -velocity integer] Velocity (volume) with which to stop the note. Must be an integer in the range 0..127. Default value is 0. [opt_def "" ""] [list_end] [lst_item note_aftertouch] Change the pressure with which the note is held down. This can be used to control effects (e.g. a vibrato). [list_begin opt] [opt_def -channel integer] Channel on which to apply the aftertouch. Check the [sectref Channels] section for valid channel numbers. Default value is 0. [opt_def -note note] Note to apply aftertouch to. Check the [sectref Notes] section for valid note numbers and valid note names. Default value is 0. [opt_def -amount integer] Amount of aftertouch to apply to the note. Must be an integer in the range 0..127. Default value is 0. [opt_def "" ""] [list_end] [lst_item controller] Used to set the value of a controller (e.g. modulation wheel). [list_begin opt] [opt_def -channel integer] Channel on which controller will have effect. Check the [sectref Channels] section for valid channel numbers. Default value is 0. [opt_def -controller controller] Controller name or number. Check the [sectref Controllers] section for valid controller names and numbers. Default value is 0. [opt_def -value integer] Value to be set for the specified controller. Must be an integer in the range 0..127. Default value is 0. [opt_def "" ""] [list_end] [lst_item program_change] change the program (patch, instrument) for a channel. [list_begin opt] [opt_def -channel integer] Channel on which program change will have effect. Check the [sectref Channels] section for valid channel numbers. Default value is 0. [opt_def -program program] Program name or number. Check the [sectref Programs] section for valid program names and numbers. Default value is 0. [opt_def "" ""] [list_end] [lst_item channel_aftertouch] Change the pressure with which all notes in the specified channel are held down. This can be used to control effects (e.g. a vibrato). [list_begin opt] [opt_def -channel integer] Channel on which to apply the aftertouch. Check the [sectref Channels] section for valid channel numbers. Default value is 0. [opt_def -amount integer] Amount of aftertouch to apply to the channel. Must be an integer in the range 0..127. Default value is 0. [opt_def "" ""] [list_end] [lst_item pitch_bend] Used to change the pitch of all notes in a channel. [list_begin opt] [opt_def -channel integer] Channel on which to apply the aftertouch. Check the [sectref Channels] section for valid channel numbers. Default value is 0. [opt_def -amount integer] Amount of bend. Must be an integer in the range -8192..8191. Values less than zero lower the pitch, values larger than zero increase the pitch. [opt_def "" ""] [list_end] [list_end] [section Channels] A midi file can store data for 16 channels. Valid channel numbers are in the range 0..15. Real channel numbers must be specified. Often midi channels are numbered starting from 1. When using this package, the first channel is channel zero. [section Notes] A midi file knows 128 notes. They are represented by an integer in the range 0..127. The note with number 69 is an A with pitch of 440Hz. Notes can be specified using their number or using an alphanumeric notation. This notation has the following structure: [example_begin] [example_end] [list_begin bullet] [bullet]Valid notes are [const A], [const B], [const C], [const D], [const E], [const F] and [const G]. The notes can be specified in upper or lower case. [bullet]Valid modifiers are [const #] and [const b]. The modifiers can be specified in upper or lower case. [bullet]Valid octaves are [const -1] to 9. [list_end] Some examples: [example_begin] A4 Bb7 F#3 C##4 abb3 e#b#b#b6 [example_end] When representing notes with their numbers, valid notes are: [example_begin] Number Note Octave ------ ----- ------ 0 C -1 1 C#/Db -1 2 D -1 3 D#/Eb -1 4 E -1 5 F -1 6 F#/Gb -1 7 G -1 8 G#Ab -1 9 A -1 10 A#/Bb -1 11 B -1 12 C 0 13 C#/Db 0 14 D 0 15 D#/Eb 0 16 E 0 17 F 0 18 F#/Gb 0 19 G 0 20 G#Ab 0 21 A 0 22 A#/Bb 0 23 B 0 24 C 1 25 C#/Db 1 26 D 1 27 D#/Eb 1 28 E 1 29 F 1 30 F#/Gb 1 31 G 1 32 G#Ab 1 33 A 1 34 A#/Bb 1 35 B 1 36 C 2 37 C#/Db 2 38 D 2 39 D#/Eb 2 40 E 2 41 F 2 42 F#/Gb 2 43 G 2 44 G#Ab 2 45 A 2 46 A#/Bb 2 47 B 2 48 C 3 49 C#/Db 3 50 D 3 51 D#/Eb 3 52 E 3 53 F 3 54 F#/Gb 3 55 G 3 56 G#Ab 3 57 A 3 58 A#/Bb 3 59 B 3 60 C 4 61 C#/Db 4 62 D 4 63 D#/Eb 4 64 E 4 65 F 4 66 F#/Gb 4 67 G 4 68 G#Ab 4 69 A 4 70 A#/Bb 4 71 B 4 72 C 5 73 C#/Db 5 74 D 5 75 D#/Eb 5 76 E 5 77 F 5 78 F#/Gb 5 79 G 5 80 G#Ab 5 81 A 5 82 A#/Bb 5 83 B 5 84 C 6 85 C#/Db 6 86 D 6 87 D#/Eb 6 88 E 6 89 F 6 90 F#/Gb 6 91 G 6 92 G#Ab 6 93 A 6 94 A#/Bb 6 95 B 6 96 C 7 97 C#/Db 7 98 D 7 99 D#/Eb 7 100 E 7 101 F 7 102 F#/Gb 7 103 G 7 104 G#Ab 7 105 A 7 106 A#/Bb 7 107 B 7 108 C 8 109 C#/Db 8 110 D 8 111 D#/Eb 8 112 E 8 113 F 8 114 F#/Gb 8 115 G 8 116 G#Ab 8 117 A 8 118 A#/Bb 8 119 B 8 120 C 9 121 C#/Db 9 122 D 9 123 D#/Eb 9 124 E 9 125 F 9 126 F#/Gb 9 127 G 9 [example_end] When playing a note on channel 9, one of the following percussion sound names can be used to specify the note: [example_begin] Number Sound ------ ------------------ 35 Acoustic Bass Drum 36 Bass Drum 1 37 Side Stick 38 Acoustic Snare 39 Hand Clap 40 Electric Snare 41 Low Floor Tom 42 Closed Hi-Hat 43 High Floor Tom 44 Pedal Hi-Hat 45 Low Tom 46 Open Hi-Hat 47 Low-Mid Tom 48 Hi-Mid Tom 49 Crash Cymbal 1 50 High Tom 51 Ride Cymbal 1 52 Chinese Cymbal 53 Ride Bell 54 Tambourine 55 Splash Cymbal 56 Cowbell 57 Crash Cymbal 2 58 Vibraslap 59 Ride Cymbal 2 60 Hi Bongo 61 Low Bongo 62 Mute Hi Conga 63 Open Hi Conga 64 Low Conga 65 High Timbale 66 Low Timbale 67 High Agogo 68 Low Agogo 69 Cabasa 70 Maracas 71 Short Whistle 72 Long Whistle 73 Short Guiro 74 Long Guiro 75 Claves 76 Hi Wood Block 77 Low Wood Block 78 Mute Cuica 79 Open Cuica 80 Mute Triangle 81 Open Triangle [example_end] These precussion sound names can be specified case insensitive. [section Controllers] Controllers can be specified with their name or number. Controller names are case insensitive. The defined controllers are: [example_begin] Ctrl Description ---- --------------------------------------------- 0 Bank Select (coarse) 1 Modulation Wheel (coarse) 2 Breath controller (coarse) 4 Foot Pedal (coarse) 5 Portamento Time (coarse) 6 Data Entry (coarse) 7 Volume (coarse) 8 Balance (coarse) 10 Pan position (coarse) 11 Expression (coarse) 12 Effect Control 1 (coarse) 13 Effect Control 2 (coarse) 16 General Purpose Slider 1 17 General Purpose Slider 2 18 General Purpose Slider 3 19 General Purpose Slider 4 32 Bank Select (fine) 33 Modulation Wheel (fine) 34 Breath controller (fine) 36 Foot Pedal (fine) 37 Portamento Time (fine) 38 Data Entry (fine) 39 Volume (fine) 40 Balance (fine) 42 Pan position (fine) 43 Expression (fine) 44 Effect Control 1 (fine) 45 Effect Control 2 (fine) 64 Hold Pedal (on/off) 65 Portamento (on/off) 66 Sustenuto Pedal (on/off) 67 Soft Pedal (on/off) 68 Legato Pedal (on/off) 69 Hold 2 Pedal (on/off) 70 Sound Variation 71 Sound Timbre 72 Sound Release Time 73 Sound Attack Time 74 Sound Brightness 75 Sound Control 6 76 Sound Control 7 77 Sound Control 8 78 Sound Control 9 79 Sound Control 10 80 General Purpose Button 1 (on/off) 81 General Purpose Button 2 (on/off) 82 General Purpose Button 3 (on/off) 83 General Purpose Button 4 (on/off) 91 Effects Level 92 Tremulo Level 93 Chorus Level 94 Celeste Level 95 Phaser Level 96 ata Button increment 97 Data Button decrement 98 Non-registered Parameter (fine) 99 Non-registered Parameter (coarse) 100 Registered Parameter (fine) 101 Registered Parameter (coarse) 120 All Sound Off 121 All Controllers Off 122 Local Keyboard (on/off) 123 All Notes Off 124 Omni Mode Off 125 Omni Mode On 126 Mono Operation 127 Poly Operation [example_end] [section Programs] Program names (also known as patches or instruments) can be specified with their name or number. Names are case insensitive. Programs known in the General Midi standard are: [example_begin] Program Family Description ------- -------------------- ----------- 0 Piano Acoustic Grand 1 Piano Bright Acoustic 2 Piano Electric Grand 3 Piano Honky-Tonk 4 Piano Electric Piano 1 5 Piano Electric Piano 2 6 Piano Harpsichord 7 Piano Clavinet 8 Chromatic percussion Celesta 9 Chromatic percussion Glockenspiel 10 Chromatic percussion Music Box 11 Chromatic percussion Vibraphone 12 Chromatic percussion Marimba 13 Chromatic percussion Xylophone 14 Chromatic percussion Tubular Bells 15 Chromatic percussion Dulcimer 16 Organ Drawbar Organ 17 Organ Percussive Organ 18 Organ Rock Organ 19 Organ Church Organ 20 Organ Reed Organ 21 Organ Accoridan 22 Organ Harmonica 23 Organ Tango Accordian 24 Guitar Nylon String Guitar 25 Guitar Steel String Guitar 26 Guitar Electric Jazz Guitar 27 Guitar Electric Clean Guitar 28 Guitar Electric Muted Guitar 29 Guitar Overdriven Guitar 30 Guitar Distortion Guitar 31 Guitar Guitar Harmonics 32 Bass Acoustic Bass 33 Bass Electric Bass(finger) 34 Bass Electric Bass(pick) 35 Bass Fretless Bass 36 Bass Slap Bass 1 37 Bass Slap Bass 2 38 Bass Synth Bass 1 39 Bass Synth Bass 2 40 Solo strings Violin 41 Solo strings Viola 42 Solo strings Cello 43 Solo strings Contrabass 44 Solo strings Tremolo Strings 45 Solo strings Pizzicato Strings 46 Solo strings Orchestral Strings 47 Solo strings Timpani 48 Ensemble String Ensemble 1 49 Ensemble String Ensemble 2 50 Ensemble SynthStrings 1 51 Ensemble SynthStrings 2 52 Ensemble Choir Aahs 53 Ensemble Voice Oohs 54 Ensemble Synth Voice 55 Ensemble Orchestra Hit 56 Brass Trumpet 57 Brass Trombone 58 Brass Tuba 59 Brass Muted Trumpet 60 Brass French Horn 61 Brass Brass Section 62 Brass SynthBrass 1 63 Brass SynthBrass 2 64 Reed Soprano Sax 65 Reed Alto Sax 66 Reed Tenor Sax 67 Reed Baritone Sax 68 Reed Oboe 69 Reed English Horn 70 Reed Bassoon 71 Reed Clarinet 72 Pipe Piccolo 73 Pipe Flute 74 Pipe Recorder 75 Pipe Pan Flute 76 Pipe Blown Bottle 77 Pipe Skakuhachi 78 Pipe Whistle 79 Pipe Ocarina 80 Synth lead Lead 1 (square) 81 Synth lead Lead 2 (sawtooth) 82 Synth lead Lead 3 (calliope) 83 Synth lead Lead 4 (chiff) 84 Synth lead Lead 5 (charang) 85 Synth lead Lead 6 (voice) 86 Synth lead Lead 7 (fifths) 87 Synth lead Lead 8 (bass+lead) 88 Synth pad Pad 1 (new age) 89 Synth pad Pad 2 (warm) 90 Synth pad Pad 3 (polysynth) 91 Synth pad Pad 4 (choir) 92 Synth pad Pad 5 (bowed) 93 Synth pad Pad 6 (metallic) 94 Synth pad Pad 7 (halo) 95 Synth pad Pad 8 (sweep) 96 Synth effects FX 1 (rain) 97 Synth effects FX 2 (soundtrack) 98 Synth effects FX 3 (crystal) 99 Synth effects FX 4 (atmosphere) 100 Synth effects FX 5 (brightness) 101 Synth effects FX 6 (goblins) 102 Synth effects FX 7 (echoes) 103 Synth effects FX 8 (sci-fi) 104 Ethnic Sitar 105 Ethnic Banjo 106 Ethnic Shamisen 107 Ethnic Koto 108 Ethnic Kalimba 109 Ethnic Bagpipe 110 Ethnic Fiddle 111 Ethnic Shanai 112 Percussive Tinkle Bell 113 Percussive Agogo 114 Percussive Steel Drums 115 Percussive Woodblock 116 Percussive Taiko Drum 117 Percussive Melodic Tom 118 Percussive Synth Drum 119 Percussive Reverse Cymbal 120 Sound effects Guitar Fret Noise 121 Sound effects Breath Noise 122 Sound effects Seashore 123 Sound effects Bird Tweet 124 Sound effects Telephone Ring 125 Sound effects Helicopter 126 Sound effects Applause 127 Sound effects Gunshot [example_end] Some midi devices may provide different drum kits for channel 9. General midi provides only one. [keywords midi] [manpage_end] <> ---- !!!!!! %| [Category Music] |% !!!!!!