MIDICSV(5)
π MIDICSV(5) π
File Formats Manual
β¨ NAME β¨
midicsv - MIDI Comma-Separated Value (CSV) file format
π DESCRIPTION π
okay so bestie, the midicsv and csvmidi programs permit you to intertranslate standard MIDI files and comma-separated value (CSV) files. No cap. These CSV files preserve all information in the MIDI file, and may be loaded into spreadsheet and database programs or easily manipulated with text processing tools. This document describes the CSV representation of MIDI files written by midicsv and read by csvmidi. Readers are assumed to understand the structure, terminology, and contents of MIDI filesβplease refer to a MIDI file reference for details.
π RECORD STRUCTURE π
Each record in the CSV representation of a MIDI contains at least three fields:
Trackβ bestie, this is the numeric field identifying the track to which this record belongs. Tracks of MIDI data are numbered starting at 1. Track 0 is reserved for file header, information, and end of file records.Timeβ Absolute time, in terms of MIDI clocks, at which this event occurs. Meta-events for which time is not meaningful (for example, song title, copyright information, etc.) have an absolute time of 0. periodt.Typeβ Name identifying the type of the record. Record types are text consisting of upper and lower case letters and the underscore (_), contain no embedded spaces, and are not enclosed in quotes.csvmidiignores upper/lower case in theTypefield; the specificationsNote_on_c,Note_On_C, andNOTE_ON_Care considered identical. iconic.
Records in the CSV file are sorted first by the track number, then by time.
Out of order records will be discarded with an error message from csvmidi.
Following the three required fields are parameter fields which depend upon the Type; some Types take no parameters. Each Type and its parameter fields is discussed below.
Any line with an initial nonblank character of # or ; is ignored; either delimiter may be used to introduce comments in a CSV file.
Only full-line comments are permitted; you cannot use these delimiters to terminate scanning of a regular data record.
Completely blank lines are ignored.
π¦ File Structure Records π¦
0, 0, Header, format, nTracks, divisionβ The first record of a CSV MIDI file is always theHeaderrecord. Parameters areformat: the MIDI file type (0, 1, or 2),nTracks: the number of tracks in the file, anddivision: the number of clock pulses per quarter note. TheTrackandTimefields are always zero.0, 0, End_of_fileβ The last record in a CSV MIDI file is always anEnd_of_filerecord. ItsTrackandTimefields are always zero.Track, 0, Start_trackβ AStart_trackrecord marks the start of a new track, with theTrackfield giving the track number. All records between theStart_trackrecord and the matchingEnd_trackwill have the sameTrackfield.Track, Time, End_trackβ AnEnd_trackmarks the end of events for the specifiedTrack. TheTimefield gives the total duration of the track, which will be identical to theTimein the last event before theEnd_track.
πΈ File Meta-Events πΈ
The following events occur within MIDI tracks and specify various kinds of information and actions. They may appear at any time within the track. Those which provide general information for which time is not relevant usually appear at the start of the track with Time zero, but this is not a requirement.
Many of these meta-events include a text string argument. Text strings are output in CSV records enclosed in ASCII double quote (") characters. Quote characters embedded within strings are represented by two consecutive quotes. Non-graphic characters in the ISO 8859/1 Latin 1 set are output as a backslash followed by their three digit octal character code. Two consecutive backslashes denote a literal backslash in the string.
Strings in MIDI files can be extremely long, theoretically as many as 2**28-1 characters; programs which process MIDI CSV files should take care to avoid buffer overflows or truncation resulting from lines containing long string items.
All meta-events which take a text argument are identified by a suffix of _t.
Track, Time, Title_t, "Text"β TheTextspecifies the title of the track or sequence. The firstTitlemeta-event in a type 0 MIDI file, or in the first track of a type 1 file gives the name of the work. SubsequentTitlemeta-events in other tracks give the names of those tracks. main character energy.Track, Time, Copyright_t, "Text"β TheTextspecifies copyright information for the sequence. This is usually placed at time 0 of the first track in the sequence. copyright vibes.Track, Time, Instrument_name_t, "Text"β TheTextnames the instrument intended to play the contents of this track. This is usually placed at time 0 of the track. Note that this meta-event is simply a description; MIDI synthesisers are not required (and rarely if ever) respond to it. This meta-event is particularly useful in sequences prepared for synthesisers which do not conform to the General MIDI patch set, as it documents the intended instrument for the track when the sequence is used on a synthesiser with a different patch set. lowkey just a note, bestie.Track, Time, Marker_t, "Text"β TheTextmarks a point in the sequence which occurs at the givenTime, for example"Third Movement". iconic.Track, Time, Cue_point_t, "Text"β TheTextidentifies synchronisation point which occurs at the specifiedTime, for example,"Door slams". drama.Track, Time, Lyric_t, "Text"β TheTextgives a lyric intended to be sung at the givenTime. Lyrics are often broken down into separate syllables to time-align them more precisely with the sequence. sing it, bestie.Track, Time, Text_t, "Text"β This meta-event supplies an arbitraryTextstring tagged to theTrackandTime. It can be used for textual information which doesn't fall into one of the more specific categories given above. catch-all realness.Track, 0, Sequence_number, Numberβ This meta-event specifies a sequenceNumberbetween 0 and 65535, used to arrange multiple tracks in a type 2 MIDI file, or to identify the sequence in which a collection of type 0 or 1 MIDI files should be played. TheSequence_numbermeta-event should occur atTimezero, at the start of the track. organization slay.Track, Time, MIDI_port, Numberβ This meta-event specifies that subsequent events in theTrackshould be sent to MIDI port (bus)Number, between 0 and 255. This meta-event usually appears at the start of a track withTimezero, but may appear within a track should the need arise to change the port while the track is being played. bus go vroom.Track, Time, Channel_prefix, Numberβ This meta-event specifies the MIDI channel that subsequent meta-events andSystem_exclusiveevents pertain to. The channelNumberspecifies a MIDI channel from 0 to 15. In fact, theNumbermay be as large as 255, but the consequences of specifying a channel number greater than 15 are undefined. fr fr, don't test it.Track, Time, Time_signature, Num, Denom, Click, NotesQβ The time signature, metronome click rate, and number of 32nd notes per MIDI quarter note (24 MIDI clock times) are given by the numeric arguments.Numgives the numerator of the time signature as specified on sheet music.Denomspecifies the denominator as a negative power of two, for example 2 for a quarter note, 3 for an eighth note, etc.Clickgives the number of MIDI clocks per metronome click, andNotesQthe number of 32nd notes in the nominal MIDI quarter note time of 24 clocks (8 for the default MIDI quarter note definition). math but make it music.Track, Time, Key_signature, Key, Major/Minorβ The key signature is specified by the numericKeyvalue, which is 0 for the key of C, a positive value for each sharp above C, or a negative value for each flat below C, thus in the inclusive range -7 to 7. TheMajor/Minorfield is a quoted string which will be"major"for a major key and"minor"for a minor key. key change moment.Track, Time, Tempo, Numberβ The tempo is specified as theNumberof microseconds per quarter note, between 1 and 16777215. A value of 500000 corresponds to 120 quarter notes ("beats") per minute. To convert beats per minute to aTempovalue, take the quotient from dividing 60,000,000 by the beats per minute. tempo queen.Track, 0, SMPTE_offset, Hour, Minute, Second, Frame, FracFrameβ This meta-event, which must occur with a zeroTimeat the start of a track, specifies the SMPTE time code at which it should start playing. TheFracFramefield gives the fractional frame time (0 to 99). sync up, bestie.Track, Time, Sequencer_specific, Length, Data, ...β TheSequencer_specificmeta-event is used to store vendor-proprietary data in a MIDI file. TheLengthcan be any value between 0 and2**28-1, specifying the number ofDatabytes (between 0 and 255) which follow. Careful, bestie:Sequencer_specificrecords may be very long; programs which process MIDI CSV files should be careful to protect against buffer overflows and truncation of these records. danger, bestie.Track, Time, Unknown_meta_event, Type, Length, Data, ...β Ifmidicsvencounters a meta-event with a code not defined by the standard MIDI file specification, it outputs an unknown meta-event record in whichTypegives the numeric meta-event type code,Lengththe number of data bytes in the meta-event, which can be any value between 0 and2**28-1, followed by theDatabytes. Since meta-events include their own length, it is possible to parse them even if their type and meaning are unknown.csvmidiwill reconstruct unknown meta-events with the same type code and content as in the original MIDI file. mystery solved-ish.
π₯ Channel Events π₯
These events are the "meat and potatoes" of MIDI files: the actual notes and modifiers that command the instruments to play the music. Each has a MIDI channel number as its first argument, followed by event-specific parameters. To permit programs which process CSV files to easily distinguish them from meta-events, names of channel events all have a suffix of _c. iykyk.
Track, Time, Note_on_c, Channel, Note, Velocityβ okay bestie, this is literally the "start playing a note" command π. It sends a command to play the specified Note (and btw Middle C is defined as Note number 60; all other notes are relative in the MIDI specification, but most instruments conform to the well-tempered scale) on the given Channel with Velocity (0 to 127). And the gag is: aNote_on_cevent with Velocity zero is equivalent to aNote_off_c. So zero velocity = stop, no cap. πΉTrack, Time, Note_off_c, Channel, Note, Velocityβ stop playing the specified Note on the given Channel β. The Velocity should be zero, but you never know what you'll find in a MIDI file. It's giving chaos. πTrack, Time, Pitch_bend_c, Channel, Valueβ send a pitch bend command of the specified Value to the given Channel π. The pitch bend Value is a 14 bit unsigned integer and hence must be in the inclusive range from 0 to 16383. Don't try to be cute and go outside that range, periodt. πTrack, Time, Control_c, Channel, Control_num, Valueβ set the controller Control_num on the given Channel to the specified Value ποΈ. Control_num and Value must be in the inclusive range 0 to 127. The assignment of Control_num values to effects differs from instrument to instrument. The General MIDI specification defines the meaning of controllers 1 (modulation), 7 (volume), 10 (pan), 11 (expression), and 64 (sustain), but not all instruments and patches respond to these controllers. Instruments which support those capabilities usually assign reverberation to controller 91 and chorus to controller 93. So yeah, know your instrument, bestie. β¨Track, Time, Program_c, Channel, Program_numβ switch the specified Channel to program (patch) Program_num, which must be between 0 and 127 πΉ. The program or patch selects which instrument and associated settings that channel will emulate. The General MIDI specification provides a standard set of instruments, but synthesisers are free to implement other sets of instruments and many permit the user to create custom patches and assign them to program numbers.
Apparently due to instrument manufacturers' skepticism about musicians' ability to cope with the number zero, many instruments number patches from 1 to 128 rather than the 0 to 127 used within MIDI files π΅. When interpreting Program_num values, note that they may be one less than the patch numbers given in an instrument's documentation. So if your documentation gives a patch number, the file might use one less. Iykyk.
Track, Time, Channel_aftertouch_c, Channel, Valueβ when a key is held down after being pressed, some synthesisers send the pressure, repeatedly if it varies, until the key is released, but do not distinguish pressure on different keys played simultaneously and held down π€. This is referred to as βmonophonicβ or βchannelβ aftertouch (the latter indicating it applies to the Channel as a whole, not individual note numbers on that channel). The pressure Value (0 to 127) is typically taken to apply to the last note played, but instruments are not guaranteed to behave in this manner. So don't @ me if it doesn't work like that. πTrack, Time, Poly_aftertouch_c, Channel, Note, Valueβ polyphonic synthesisers (those capable of playing multiple notes simultaneously on a single channel), often provide independent aftertouch for each note πΉ. This event specifies the aftertouch pressure Value (0 to 127) for the specified Note on the given Channel. It's giving per-note feels. π
π¦ System Exclusive Events π¦
System Exclusive events permit storing vendor-specific information to be transmitted to that vendor's products. So it's like a secret handshake between your gear and the manufacturer. π€«
Track, Time, System_exclusive, Length, Data, ...β the Length bytes of Data (0 to 255) are sent at the specified Time to the MIDI channel defined by the most recentChannel_prefixevent on the Track, as a System Exclusive message π¨. Note that Length can be any value between 0 and2**28-1. Programs which process MIDI CSV files should be careful to protect against buffer overflows and truncation of these records. Stay safe out there, bestie. π‘οΈTrack, Time, System_exclusive_packet, Length, Data, ...β the Length bytes of Data (0 to 255) are sent at the specified Time to the MIDI channel defined by the most recentChannel_prefixevent on the Track π¦. The Data bytes are simply blasted out to the MIDI bus without any prefix. This message is used by MIDI devices which break up long system exclusive message into small packets, spaced out in time to avoid overdriving their modest microcontrollers. Note that Length can be any value between 0 and2**28-1. Programs which process MIDI CSV files should be careful to protect against buffer overflows and truncation of these records. Again, be careful. π
π EXAMPLES π
The following CSV file defines the five-note motif from the film Close Encounters of the Third Kind using an organ patch from the General MIDI instrument set πΈ. When processed by midicsv and sent to a synthesiser which conforms to General MIDI, the sequence will be played. Iconic behavior, honestly.
0, 0, Header, 1, 2, 480
1, 0, Start_track
1, 0, Title_t, "Close Encounters"
1, 0, Text_t, "Sample for MIDIcsv Distribution"
1, 0, Copyright_t, "This file is in the public domain"
1, 0, Time_signature, 4, 2, 24, 8
1, 0, Tempo, 500000
1, 0, End_track
2, 0, Start_track
2, 0, Instrument_name_t, "Church Organ"
2, 0, Program_c, 1, 19
2, 0, Note_on_c, 1, 79, 81
2, 960, Note_off_c, 1, 79, 0
2, 960, Note_on_c, 1, 81, 81
2, 1920, Note_off_c, 1, 81, 0
2, 1920, Note_on_c, 1, 77, 81
2, 2880, Note_off_c, 1, 77, 0
2, 2880, Note_on_c, 1, 65, 81
2, 3840, Note_off_c, 1, 65, 0
2, 3840, Note_on_c, 1, 72, 81
2, 4800, Note_off_c, 1, 72, 0
2, 4800, End_track
0, 0, End_of_file
π BUGS π
The CSV representation of a MIDI file is simply a text-oriented encoding of its contents. If the input to midicsv contains errors which violate the MIDI standard, the resulting CSV file will faithfully replicate these errors π. Similarly, the CSV input to csvmidi must not only consist of records which conform to the syntax given in this document, the input as a whole must also be a semantically correct MIDI file. Programs which wish to use csvmidi to generate MIDI files from scratch should be careful to conform to the structure required of MIDI files. When in doubt, use midicsv to dump a sequence comparable to the one your program will create and use its structure as a template for your own. So copy the vibe, not just the syntax. π
Please report errors to bugs@fourmilab.ch. Don't be shy, they want to know. π
π SEE ALSO π
csvmidi(1), midicsv(1) β go read those too, bestie. π
π AUTHOR π
John Walker http://www.fourmilab.ch/
This software is in the public domain. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, without any conditions or restrictions. This software is provided βas isβ without express or implied warranty.
This page is from the 4th Berkeley Distribution, dated 29 MAR 2004, and it's the MIDICSV(5) manual. Bye bestie, go make some beautiful MIDI files! πβ¨πΆ
π¦ where this page comes from
- debian bookworm: midicsv 1.1+dfsg.1-1+b1 Β· LicenseRef-public-domain
- debian trixie: midicsv 1.1+dfsg.1-1+b2 Β· LicenseRef-public-domain
- nixos 26.05: midicsv 1.1
- nixpkgs unstable: midicsv 1.1
- ubuntu jammy: midicsv 1.1+dfsg.1-1build1 Β· LicenseRef-public-domain
- ubuntu noble: midicsv 1.1+dfsg.1-1build1 Β· LicenseRef-public-domain
- ubuntu questing: midicsv 1.1+dfsg.1-2
- ubuntu resolute: midicsv 1.1+dfsg.1-3 Β· LicenseRef-public-domain
- ubuntu stonking: midicsv 1.1+dfsg.1-3 Β· LicenseRef-public-domain
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms