Mscore

A Midi Scoring Tool
1. Introduction 2. Why Mscore? 3. Score Layout 4. MIDI Events 5. Event Types
6. Creating a MIDI File 7. MIDI Dumps 8. Csound to MIDI 9. File Descriptions
Download

News

  • September 10, 2009
    Mscore uograde version 1.2

    Several upgrades and fixes that make Mscore compatible with the recent Ascore MIDI enhancements.


1. Introduction

Mscore is a MIDI scoring tool for Linux. Its capabilities include

  1. Create MIDI files.
  2. Perform an ascii dump on an existing MIDI file.
  3. Converting Csound score files into MIDI files.

The Mscore suite of scripts was designed with the idea of creating MIDI tools for Linux compatible with Csound and compatible with the Ascore utility. A third consideration was to create low level components that do as little as possible (functionality broken up into many separate modules) and do not have built-in graphical interfaces. The components may then be used in different combinations and easily interfaced to other components. Consider how the unix operating system was designed; consider how the ALSA sound system was designed, and you will understand what I had in mind. My thinking for these tools is to have (eventually) a GUI as a separate component which helps to visually consolidate the configuration of the low level components. You use the GUI to automate similar, repeated configurations but don't let it get in the way of batch processing.

Above and beyond the preceding considerations, this tool was intended to provide the MIDI musician with a way to see, and work with, the MIDI notes aligned in a time-synchonized fashion. The notes in each MIDI track are listed in parallel columns down the page, and any notes on the same line start at the same time. I looked around for other Linux MIDI tools before I started on this one. I think Midge is especially impressive. You may find Midge easier to use than Mscore. But I needed the parallel tracking arrangement of the notes, so I embarked on writing my own tool. This afforded me the opportunity to make Ascore a front end for Mscore. As you will see, Mscore can be a stand-alone scoring tool. But any some ways it might be viewed as an intermediate file type.


2. Why Mscore?

An Mscore MIDI score is an ASCII text file with a specially defined MIDI language that arranges notes in parallel "tracks" so that note synchronization can be seen visually. The following example shows a typical representation.

 0.587647*  @3{55__0.587647*}70   @8{36__0.587647*}100            |
 0.587663*  @3{60__0.587647*}70             |           @10{42__0.587647*}100
 0.587633*  @3{62__0.587647*}70   @8{36__0.587647*}95             |
 0.587633*  @3{55__0.587647*}70             |           @10{42__0.587647*}90
 0.587667*  @3{60__0.587647*}70             |           @10{38__0.587647*}85
 0.587633*  @3{64__0.587647*}70             |           @10{42__0.587647*}80
 0.587667*  @3{62__0.587647*}70   @8{36__0.587647*}90             |
 0.587633*  @3{55__0.587647*}70             |           @10{42__0.587647*}85
 0.587667*  @3{60__0.587647*}70   @8{36__0.587647*}90             |
 0.587633*  @3{62__0.587647*}70             |           @10{42__0.587647*}100
 0.587633*  @3{55__0.587647*}70   @8{36__0.587647*}95             |
 0.587667*  @3{64__0.587647*}70             |           @10{42__0.587647*}90
    

The above piece of score contains three MIDI tracks and a timing column at the far left. Every line contains notes that start at the same time.

The * symbol represents an eighth note. On the first line, 0.587647* is a 0.587647 fraction of an eighth note and is the amount of time that will elapse before the following line is played.

The note representation contains four non-whitespace delimited, order-dependent parameters that represent the MIDI channel, the MIDI note number, the note duration and the MIDI velocity number. Consider the note in column 2 (track 1) on the first line:


        @3{55__0.587647*}70

    

The symbols in this note specification have the following meaning:

@3 The "@3" specifies MIDI channel 3. The MIDI channels are numbered from 1 to 16.
{ The "{" symbol is a separator.
55 The number "55" is the MIDI note number, numbered 0 to 127.
__ The "__" symbol is two consecutive underscores, which is a separator.
0.587647* The "0.587647*" symbol is the note duration, where "*" is an eighth note.
} The "}" symbol is a separator.
70 The number "70" is the MIDI velocity number, numbered 0 to 127.

Notice the separators

{ __ }

There is no whitespace (spaces or tabs) in the note specification. The "|" symbol in the above code block means that the note in the preceding line is still playing, or that there is a rest.


3. Score Layout

There is a rough correspondence between the structure of a MIDI file and the layout of the Mscore score file. The exception to that similarity is that tracks in a MIDI file are contained in separate blocks, or chunks. The notes in each track are not interlaced according to start times as they are in the Mscore score. Aside from that, the parameters and their positions in the score follow the MIDI sequence of events.

There are basically two sections: the header and the list of notes. The header starts with 3 global parameters followed by setup parameters for each track:

Global Parameters
midi format
number of tracks
tics per beat
Tracks Parameters 1
midi port
tempo
time signature
---
---
Tracks Parameters 2
---
---
Tracks Parameters N

The follow header example might be used for the above notes section:


MIDI_FORMAT multi_track
TRACKS 3
TICS_PER_BEAT 220
 0    META   TK1   MIDIPORT   0
 0    META   TK1   TEMPO   100
 0    META   TK1   TIME_SIGNATURE    04    02    36    08
 0    MIDI   TK1   CH3   CT7   VL80
 0    META   TK1   TEXT   Dummy   Note
 0    META   TK2   MIDIPORT   0
 0    META   TK2   TEMPO   100
 0    META   TK2   TIME_SIGNATURE    04    02    36    08
 0    MIDI   TK2   CH8   CT7   VL80
 0    META   TK3   MIDIPORT   0
 0    META   TK3   TEMPO   100
 0    META   TK3   TIME_SIGNATURE    04    02    36    08
 0    MIDI   TK3   CH10  CT7   VL80

        

The lines following the the three global parameters are MIDI events. While these should be included as headings to each track, they are not necessarily required. Also, these MIDI events may be interspersed with the MIDI notes.

Combining the header and notes block, the following example represents the Mscore score layout:


#
#   A complete Mscore score
#
#   Header Block
#
#
MIDI_FORMAT multi_track
TRACKS 3
TICS_PER_BEAT 220
 0    META   TK1   MIDIPORT   0
 0    META   TK1   TEMPO   100
 0    META   TK1   TIME_SIGNATURE    04    02    36    08
 0    MIDI   TK1   CH3   CT7   VL80
 0    META   TK1   TEXT   Dummy   Note
 0    META   TK2   MIDIPORT   0
 0    META   TK2   TEMPO   100
 0    META   TK2   TIME_SIGNATURE    04    02    36    08
 0    MIDI   TK2   CH8   CT7   VL80
 0    META   TK3   MIDIPORT   0
 0    META   TK3   TEMPO   100
 0    META   TK3   TIME_SIGNATURE    04    02    36    08
 0    MIDI   TK3   CH10  CT7   VL80
#
#
#   Notes Block
#
#
 0.587647*  @3{55__0.587647*}70   @8{36__0.587647*}100            |
 0.587663*  @3{60__0.587647*}70             |           @10{42__0.587647*}100
 0.587633*  @3{62__0.587647*}70   @8{36__0.587647*}95             |
 0.587633*  @3{55__0.587647*}70             |           @10{42__0.587647*}90
 0.587667*  @3{60__0.587647*}70             |           @10{38__0.587647*}85
 0.587633*  @3{64__0.587647*}70             |           @10{42__0.587647*}80
 0.587667*  @3{62__0.587647*}70   @8{36__0.587647*}90             |
 0.587633*  @3{55__0.587647*}70             |           @10{42__0.587647*}85
 0.587667*  @3{60__0.587647*}70   @8{36__0.587647*}90             |
 0.587633*  @3{62__0.587647*}70             |           @10{42__0.587647*}100
 0.587633*  @3{55__0.587647*}70   @8{36__0.587647*}95             |
 0.587667*  @3{64__0.587647*}70             |           @10{42__0.587647*}90

        

4. MIDI Events

Notice that after the three global parameters the setup parameters for each track follow with a start time at the far left column. The track 1 parameters are given with the keyword TK1. Likewise, the track parameters for tracks 2 and 3 are given by TK2 and TK3. These track parameters all translate into MIDI events in the MIDI file. I am using the term MIDI event broadly. In the General Midi file specification, events are subclassed as MIDI, META and SYETEM EXCLUSIVE. As such, "MIDI events" are a specific group of events that include note on, note off, program change, control change, and others. The "META events" are things like tempo, time signature, track name and text information. The "SYSTEM EXCLUSIVE events" are manufacturer-specific messages for controlling a synthesizer.

With the exception of the MIDI notes, all events in the Mscore score are given with the same general syntax:

Time Type Track Channel / Event Parameters

In the case of META events, the 4th argument is the name of the event, such as TEMPO, and the parameters are hexidecimal byte sequences (this is low-level MIDI). In the case of MIDI events, the 4th argument is the channel (1-16), and the parameters are 2 keyword-number fields that specify the type of MIDI event and its value. For example,

 0    MIDI   TK3   CH10  CT7   VL80
        

Is a controller 7 change (volume) with value 80 (range 0-127) on MIDI channel 10 in track 3 The controller numbers as given in the range 0 to 127.

A program change event (changing the synthesizer preset number) does not include the VLnn (e.g., VL80) field. The program numbers are numbered 0 to 127. For example,

 0    MIDI   TK3   CH10  PG22
        

will change the channel 10 preset number to 22, where the first preset would be numbered 0.



5. Event Types

You should consult your low-level General MIDI specification. Events are divided into subcatagories.

  • MIDI events
  • META events
  • SYSEX (system exclusive) events
  • SYSCM (system common) events
  • SYSRT (system real time) events

The MIDI events are the most commonly use events for controlling a synthesizer. They include the following list:

  • Note On
  • Note Off
  • Key Pressure (Polyphonic Pressure)
  • Control Change
  • Program Change (Preset Change)
  • Channel Pressure (Channel Aftertouch)
  • Pitch Bend (Pitch Wheel)

Mscore combines the NOTE ON and NOTE OFF messages into a single note representation as shown above.

The special MIDI events, that is, the non-note events are coded in Mscore using the following two-character keywords:

KP Key Pressure
CT Control Change
PG Program Change
CP Channel Pressure
PB Pitch Bend

As shown above these keywords given by combining these two-character codes with a 7-bit number into a single token. For example, control change 7 (volume change) is CT7, and program change to 22 is PG22. These codes can be followed by a data value, depending on which code is being used. The data value is given in Mscore by combining the two-character code VL with a 7-bit number to create a single token. KP, CT and PB events require a data value, whereas PG and CP do not.

The numbers combined with these character codes are decimal numbers. The number combined with CT, for example, ranges from 0 to 127, and the number combined with VL ranges from 0 to 127.

The META events are also given a start time and track number. Here is the list of META events.

  • TEMPO
  • SEQNUM
  • TEXT
  • COPYRIGHT
  • TRACKNAME
  • INSTRNAME
  • LYRICS
  • MARKER
  • CUE
  • CHANNEL
  • MIDI_PORT
  • TIME_SIGNATURE
  • KEY_SIGNATURE
  • SMPTE_OFFSET
  • SEQUENCER_SPECIFIC

Some of these META events have string arguments, such as TEXT. Others have arguments that are raw byte values from the file. For example, the SEQUENCER_SPECIFIC values are a hexidecimal byte dump. There are several META events for which I saw no useful purpose, and so they are included but represented as raw data. Of these, TIME_SIGNATURE and KEY_SIGNATURE use a sequence of decimal bytes. SMPTE_OFFSET and SEQUENCER_SPECIFIC are followed by a sequence of hexidecimal bytes. As of the current build of Mscore you will have to translate these yourself if you use them. The exception is TEMPO, which is given as the decimal beats per minute.

Time Type Track Channel / Event Parameters
0 MIDI TK1 CH1 CT7 VL80
0.2* MIDI TK2 CH2 PG34
1.7q MIDI TK3 CH9 CP104
2.6! MIDI TK1 CH16 PB60 VL110
0.14o MIDI TK5 CH3 KP21 VL20
3.5* META TK1 TEMPO 110
1.9h META TK8 SEQNUM 1
5.0! META TK4 TEXT 1-P91 Synth Pads
3.0* META TK2 COPYRIGHT copyright text
1.0o META TK1 TRACKNAME track one
0.1h META TK1 INSTRNAME alto sax
0.4* META TK6 LYRICS The world is round.
0.5q META TK1 MARKER Marker 3
0.1* META TK2 CUE Cue it here.
0.5* META TK5 TIME_SIGNATURE 04 02 36 08
0.2! META TK1 SMPTE_OFFSET 60 0 0 0 0
0.02q META TK8 SEQUENCER_SPECIFIC 0 0 41

The SYSEX (system exclusive) events are obviously handled as raw hexidecimal byte sequences. As of the current version, the SYSEX, SYSCM (system common) and SYSRT (system real-time) events are ignored, because these are usually found only in real-time MIDI keyboard control. I have yet to encounter a MIDI file with these codes.



6. Creating a MIDI File

To create a MIDI file you must first create an ascii text score with the above syntax and format--an Mscore score. You then convert this score file, say "scorefile", into a hex dump with the mscore.awk script as follows:

awk -f mscore.awk scorefile > tempfile.hex

Or, another way to run it would be

cat scorefile | awk -f mscore.awk > tempfile.hex

The result, tempfile.hex, will be an ascii text file that is a single column of hexidecimal 8-bit numbers. When this file is converted into a binary file you have a MIDI file. You can use your own program if you like, or perhaps the GNU hexdump program does that? If not, a hex to binary converter is provided in the Mscore package called hexxer.c. Compile this simple C program, then run it as follows:

hexxer tempfile.hex midifile b

Note that the argument "b" is necessary for using hexxer to convert ascii to binary.



7. MIDI Dumps

To start with an existing MIDI binary file, that is, a "standard midi file" (SMF) and create an ascii text dump of the file you can use the utility mid2score.awk included in the Mscore package. However, you must first convert the binary file into a hex dump file. The hexxer.c utility in the Mscore package can be used for that according to the following syntax:

hexxer midifile hexfile

Then convert the ascii hex dump into an equivalent Mscore score file with the following command:

cat hexfile | awk -f mid2score.awk > mididump

The following example listing was produced with the mid2score.awk tool from a MIDI file downloaded from the Yamaha ES6 keyboard synthesizer's sequencer.


#   -----------------
#	MIDI SCORE FILE
#	generated by mid2score.awk	(Alfred Steffens Jr.	2007)
#	mid2score ver. 1.03
#   -----------------
#
#	Unix Text
MIDI_FORMAT single_track (0)
TRACKS 1
TICS_PER_BEAT 480
#	sequencer specific event
#	total events 149
 0    META   TK1   SEQUENCER_SPECIFIC  43  7b  0  58  46  30  32  0  2
 0    META   TK1   TRACKNAME
 0    META   TK1   TEMPO   120
 o    META   TK1   TIME_SIGNATURE  04  02  24  08
#   -----------------
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100
 q  @1{38__0.9!}100
 q  @1{36__0.9!}100

    

You can get a dump that shows the hex bytes as they are translated into Mscore statements by giving the debug_messages argument to mid2score.awk as follows:

cat hexfile | awk -f mid2score.awk debug_messages=1 > raw_mididump

An example of re-running the above MIDI dump using the debug_messages=1 argument can be found here.



8. Csound to MIDI

Converting a Csound score into a MIDI file can be done with the Mscore package using a tool called cs2mtx.awk (CSound 2 Midi TeXt). A Bash shell script, cs2mtx.sh, is provided that illustrates how this is done.

Csound scores are simple (to a programmer) structures that just contain rows of notes in ascii text format. The first three columns in the score are assumed to have standard meaning: the instrument, the start time, and the duration. Any columns after that have an arbitrary meaning depending on your particular score.

The first thing that must be done to the Csound score is to sort the lines according to start time. There is an AWK script included in the Mscore package to help do this: cs2sort.awk. The output from the sorter is then given as input to cs2mtx.awk. There are some command-line arguments that need to be passed to cs2mtx.awk in order to resolve ambiguities: you need to specify how instruments are assigned to MIDI channels.

The following example shows the command-line arguments to cs2mtx.awk for a particular Csound orchestra. You would change this to meet your own needs:

cat sorted_scorefile | awk -f cs2mtx.awk \

bpm=120 \

tracks=1,10,2 \

drums=50,51,52,53,54,55,56,57 \

alias2=30,31,32,33,34,35,36,37,38,39,40,41,42 \

nshift=12,0,12 \

> body.mtx

The tempo is given with the bpm argument. The argument with "tracks" is saying that the first track will be assigned to MIDI channel 1, the second track to MIDI channel 10 and the third track to MIDI channel 2. This argument is obviously order-dependent. The argument specifying "drums" says assign instruments 50, 51, 52, 53, 54, 55, 56, 57 to MIDI channel 10 (drums). The argument that starts with "alias2" say that MIDI channel 2 will be assigned to instruments 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42. The list of instruments in these arguments is independent of order. The "nshift" argument will shift the pitch of track 1 up by 12 half tones, track 2 by 0 half tones and track 3 by 12 half tones. This argument is obviously order-dependent. Care must be taken that no whitespace should appear in these comma-separated arguments.

The columns of the resulting Mscore body may be aligned with the supplied utility, malign.awk, a code beautifier.

Now the appropriate Mscore header is added with the help of another AWK script called mtxheader.awk. The information that was used in the call to cs2mtx.awk can be used again for creating the header. The mtxheader.awk script takes similar arguments.

echo "nothing" | awk -f mtxheader.awk \

bpm=120 \

ticks=220 \

name=SONG1 \

tracks=1,10,2 \

programs=34,-1,0 \

volumes=80,60,80 \

> header.mtx

The program (preset numbers) for tracks 1, 2 and 3 will be 34, nothing and 0. The volumes for tracks 1, 2 and 3 will be 80, 60 and 80.

These two files, header.mtx and body.mtx, are simply concatenated. The resulting Mscore score can then be converted into the ascii hex representation of the SMF using mscore.awk, then transformed into the binary MIDI file with hexxer.



9. File Descriptions

The script tools included in the Mscore are shown in the following list.

mscore.awk Converts an Mscore score file into MIDI, where the binary data represented as ascii hexidecimal numbers.
mid2score.awk The reverse operation of mscore.awk. This script converts the standard MIDI file (SMF), represented in ascii hexidecimal numbers, in to a corresponding Mscore file.
hexxer.c Transforms a binary file into a column of ascii hexidecimal 8-bit numbers, or the reverse.
cs2sort.awk Takes a Csound score file as input and sorts the score according to start times.
cs2mtx.awk Takes a sorted Csound score file as input and creates a corresponding Mscore score using instrument-to-channel information provided on the command line.
mtxheader.awk Creates the Mscore header for the body of script created with the cs2mtx.awk tool.
malign.awk Formats an existing Mscore script file so that the track columns are aligned.
stripd.awk Strips out the carriage return (ascii 0x0D) from DOS/Windows text files so that they will be Unix-compatible. If you use a Windows text editor it will insert 0x0D at the end of the line and Unix-based tools will complain. This script will remove the 0x0D characters.



Download Mscore

Lastest version is 1.2

The installation package is just a set of awk scripts and shell scripts. When the tar-gzip file is unpacked it creates a directory called mscore (not mscore-1.2) and copied the files into it.




Linux Music Synthesis
[JPG image artwork that is a companion to the text]
© Alfred Steffens Jr., 2009