Skip to content

MML Reference

Damián Silvani edited this page Jan 4, 2017 · 4 revisions

MML Reference

This is mostly taken from http://nesdev.com/mckc-e.txt

Voices

  • A = Pulse Wave 1
  • B = Pulse Wave 2
  • C = Triangle Wave
  • D = White Noise

Macros

MML stands for Music Macro Language - and as such, it relies heavily upon the definition of key sequences and complicated series of operations that are defined once and then called upon later in a sequence. These are just like word-processing macros or macros in other types of programming languages, and they save quite a bit of time as opposed to inputting volume commands, "instrument" sounds, and the like each time by hand.

For someone used to module tracking, this is a huge boon when writing chiptunes with limited timbres and volumes! If, for example, you wanted to have each note start with a 50% square wave attack and then quickly jump to a 25% pulse wave to approximate a piano-like "pling", you'd have to change the instruments on subsequent rows in a tracker every time you put in notes. This is exceptionally inefficient. Consider the difference between the following examples:

			Tracking         vs.          MML

		|C-5 01 ---
		|C-5 02 ---                   Defined once at top of file:
		|--- -- ---                   @01 = { 1 2 }
		|E-5 01 ---
		|E-5 02 ---                   Then, in the composition:
		|--- -- ---                   @@01 c e g
		|G-5 01 ---
		|G-5 02 ---

It very quickly becomes obvious that by using macros you can save yourself a whole lot of time with note entry and timbre/volume/pitch changes. You define these macros before the sequence data, or even in a separate #include file. The following is a list of the various macros you can use.

  • Timbre Macro @[num] = { - | - } Accepting values between 0 ~ 127 for [num] and 0 ~ 15 within the { } brackets, this macro will change the duty ratio (timbre) of the sound while playing, as follows:

             0... 12.5% (thin, raspy pulse wave)
             1... 25.0% (smooth, thickly timbral pulse wave)
             2... 50.0% (clear, thin bell-like square wave)
             3... 75.0% (identical to 25%, but phase-inverted)
    
        Multiple values are separated by spaces or commas.
    
        The first value defines the initial timbre, and the last number the
        final timbre, to be held until the note is stopped. In between,
        however, the timbre will "sweep" through each value, advancing once
        each frame, until it reaches the end. In this manner, you can give
        each note an "attack" that will make it rapidly change from one timbre
        to another when the sound starts.
    
        The versatility of this technique is not to be underestimated; it is
        integral to many fuller-sounding NES soundtracks. It enables the
        composer to choose from a wide range of instrument sounds far beyond
        the simple ping of the pulse wave's four duty ratios.
    
        Using a "|" between numbers will allow for a loop in the macro. Once
        the end of the macro is reached, it will return to the number
        immediately following the "|" and sweep through again. This repetition
        will continue until the note is stopped. A loop with dissimilar
        timbres will lend a thick, burbly character to the sustained sound,
        similar to the "PWM" technique used in C64 and some European NES
        soundtracks.
    
        If the "|" is immediately before the last number in the macro, only
        that last number will loop, rendering the "|" superfluous. Therefore,
        the following two macros function identically:
    
             @0 = { 0, 1, | 2 }
             @02 = { 0 1 2 }
    
        The [num] value is called by the corresponding value accompanying the
        @@ command, as discussed below.
    
        NOTE: If you're using the triangle channel, use @3 - and if you're
        using the noise channel, use either @0 or @1 for a smooth or buzzy
        noise sound.
    
  • Volume Envelope Macro @v[num] = { - | - } Accepting values between 0 ~ 127 for [num] and 0 ~ 15 within the { } brackets, this macro will change the amplitude of the sound while playing. This is known as a volume envelope, and enables a slow gradual fade, a fast fade, or an instant cutoff of sound. This is also a facility by which echoes can be created automatically by turning the sound back on briefly once it has faded out, or to achieve other special volume effects in a reusable macro.

       Using a "|" between numbers will allow for a loop in the macro. Once
       the end of the macro is reached, it will return to the number
       immediately following the "|" and sweep through again. This repetition
       will continue until the note is stopped. If the loop point changes the
       volume back drastically, it will sound like the sound itself has
       restarted, and "stutter".
    
       If the "|" is immediately before the last number in the macro, only
       that last number will loop, rendering the "|" superfluous and
       maintaining the volume level of the final value indefinitely until the
       channel is reused.
    
       The [num] value is called by the corresponding value accompanying the
       @v command, as discussed below
    
       NOTE: The triangle channel, because of the way it produces sound
       (through very rapid volume sweeps) is incapable of playing at any
       volume other than full. This channel is either on or off, never in
       between. Volume Macros should not be used on it.
    
  • Pitch Envelope Macro @EP [num] = { - | - } Accepting values between -127 ~ 126 for [num] and 0 ~ 15 within the { } brackets, this macro will change the frequency (pitch) of the sound while playing. This is known as a pitch envelope. The source of classic video game bwoops and bleeps, this converts the pulse wave voices into exponentially increasing or decreasing sweeps through frequency.

       Using a "|" between numbers will allow for a loop in the macro. Once
       the end of the macro is reached, it will return to the number
       immediately following the "|" and sweep through again. This repetition
       will continue until the note is stopped.
    
       If the "|" is immediately before the last number in the macro, only
       that last number will loop, rendering the "|" superfluous and
       maintaining the pitch change of the final value indefinitely until the
       channel is reused.
    
       The [num] value is called by the corresponding value accompanying the
       EP command, as discussed below.
    
  • Arpeggio (Note Envelope) Macro @EN [num] = { - | - } A more flexible equivalent of module tracking programs' legendary "Arpeggio" functions, this macro will allow you to define a rapid series of note changes to approximate a musical chord, while using only one channel. The result is the synthetic equivalent of gargling, and has long been a trusty standby in the chiptunist's repertoire of texture-thickening tricks. Each value in { } brackets, separated by space or comma, can range from -127 ~ 126, and that value determines the number of semitones to change the note by on each subsequent frame. The pitch does not return to the start after each frame, but remains at the previous pitch and adds or subtracts to it by the amount of the next value, as illustrated in this example:

            @EN00 = { 0, 1, 1, 1, -1, -1, -1 }
    
            If a C is played, the notes in the arpeggio will be:
            C, C#, D, D#, D, C#, and C - each note occupying one frame.
    
       Using a "|" between numbers will allow for a loop in the macro. Once
       the end of the macro is reached, it will return to the number
       immediately following the "|" and gargle its way through again. This
       repetition will continue until the note is stopped.
    
       If the "|" is immediately before the last number in the macro, only
       that last number will loop, rendering the "|" superfluous and
       maintaining the note of the final value indefinitely until the channel
       is reused.
    
       The [num] value is called by the corresponding value accompanying the
       EN command, as discussed below.
    
  • Pitch LFO (Vibrato) Macro @MP[num] = { [delay], [speed], [depth] } Used to define a reusable pitch LFO (Low Frequency Oscillator, in this case a sine-wave pattern of pitch modulation, better known to musicians as vibrato.) [num] can range from 0 ~ 63. An explanation of each parameter follows:

            [delay] is the period of time spent with no vibrato before the
            LFO takes effect. This is useful for many lead voices, as it is
            often not desirable to have the note start with immediate
            vibrato, but to let it come in after a short time. Value can be 0
            ~ 255 ticks.
    
            [speed] is the frequency of the LFO.  Ranges from 1 ~ 255. The
            smaller the value, the faster the pitch will oscillate.
    
            [depth] is how drastic or pronounced the vibrato is. Accepts a
            value of -255 ~ 255. The larger the value, the more the pitch is
            changed. Extremely large values may cause the pitch to "overlap"
            to the bottom of the frequency range or other anomalous behavior.
    
       The [num] value is called by the corresponding value accompanying the
       EN command, as discussed below.
    

Commands

These are the commands used within a sequence, following the song headers and after issuing a channel header, to accompany and modify the notes you enter. They range from changing the character of the sound to altering the flow of the music. The number in (parentheses), following the form illustration, is the hard-wired default value that will be assumed by the player code if the command is not issued in the sequence.

  • Tempo t[num] (120) Sets the tempo of a track, in BPM (beats per minute). Valid range is from 1 ~ 255.

  • Default Note Duration l[len] (4) Sets the default length, in traditional measure/[len] notation, of a note unaccompanied by a duration flag, i.e., "c" instead of "c4" or "c16".

  • Pitch Sweep s[speed],[depth] (0,0) Pitch Sweep, similar to the pitch envelope. The range for [speed] appears to only function in the range of 9 ~ 15, where a higher value will effect a more subtle change every frame, and the range of [depth] appears to function according to this chart:

     					 |1  2  3  4  5  6  7  8  9  10 11 12 13 14 15|
     					 |drastic<--->slight->/^\<-slight<---->drastic|
     					 |       DOWN         OFF          UP         |
    
     			 Here the closer to the ends of the spectrum, the more drastic the
     			 pitch change is, and if the value is 8, nothing happens.
    
  • Timbre Single Select @[num] (0) Sets the duty ratio (timbre) of the square wave accordingly:

     						0... 12.5% (thin, raspy pulse wave)
     						1... 25.0% (smooth, thickly timbral pulse wave)
     						2... 50.0% (clear, thin bell-like square wave)
     						3... 75.0% (identical to 25%, but phase-inverted)
    
     			 This cannot be used at the same time as the @@ command, described
     			 below - whichever command is used last will take priority.
    
  • Timbre Macro Select @@[num] (0) Selects a Timbre Macro to apply to subsequent notes. This cannot be used at the same time as the above @ command - whichever command is used last will take priority.

  • Volume v[num] (0) This is used to directly set the volume of the current channel for subsequent notes, ignoring any volume envelope you may have set. Valid settings are 1 ~ 15. As expected, this cannot be used at the same time as the @v command - whichever is used last will take priority.

  • Volume Up v+[num] (1) This will increase the volume of the current channel for subsequent notes - as an addendum to the v command. This is useful when you want to implement a sequenced volume fade by hand but do not want to have to change every value by hand should you decide to start the fade at another level. Valid range is 1 ~ 15. As with the v command, you cannot use this at the same time as the @v command.

  • Volume Down v-[num] (1) Identical to the above, but for a decrease in volume.

  • Envelope @v[num] (0) Selects a Volume Envelope Macro to apply to subsequent notes. This cannot be used at the same time as the above v command - whichever command is used last will take priority.

  • Octave Select o[num] (4) Chooses an octave in which notes will play. The octaves accessible on the NES range from 2 ~ 7.

  • Octave Up > Increases the octave by one and signals that subsequent notes be played in the next octave. Multiple > commands in series will raise the octave multiple times. The polarity of this command will switch if you issue an #OCTAVE-REV directive in the header.

  • Octave Down < Same as above, except reversed.

  • Play Note c,d,e,f,g,a,b[len] (4)

     			 Just the same as traditional note scales. Here sharps are
     			 represented by + and flats are represented by -. Note that the
     			 assignment of sharps and flats are independent of the scale and
     			 otherwise unconditional, so it is possible to designate
     			 enharmonics. Therefore, A++, C- and d+++++++++ will all produce a
     			 B note. [len] will set the length of the note, in (measure/[len])
     			 notation, such as c16, f32, or b8, but if [len] is left blank,
     			 the value of L will be used as the duration.
    
  • Rest Sign r[len] (4) Just as in traditional notation, the rest is the equivalent of a silent note. The [len] parameter works exactly as in a normal note, but the channel will be silent instead for that period of time.

  • Tuplet { ~ } [len] Best introduced through example, { ccc }8 will play three c notes in the same amount of time it would take to play one normal eighth note. In traditional notation this is called a triplet. Although they might sound muddy or indistinguishable, it is possible by this same method to create quintuplets, septuplets, 25-tuplets. or whatever you can imagine-tuplets.

  • Quantize (Note Cut) Commands q[num] (8) Quantization, slightly different from the typical MIDI definition, controls here the length of the note. The value given here will allow [num]/8 of the note to play. In other words, each note is divided into 8 parts and, using this command, [num] of them will play before the sound is cut off. This is more useful than it seems for lead parts where you might want to abbreviate some of the notes on off-beats to make the lead sound more energetic, instead of letting every note drag until the next one starts. The range of input is, of course, 1 ~ 8.

  • Tie ^ Used to connect two notes of the same pitch, adding their duration together to make one long note. "a8 & a8" will combine together to play as a4, which is twice as long as its components.

  • Detune D[num] Detune gives you fine control over the frequency of the channel in close steps. At low levels it is quite subtle but it can also be used to dramatically alter the pitch of notes. Its main use when subtle is to create a "flanging" effect by playing the same notes on two channels, with one channel slightly detuned. This is another way to create sounds that go beyond the standard four duty ratio timbres of the pulse channels.

     			 The valid range is -127 ~ 126. When the value is set at 255, the
     			 effect is cancelled.
    
  • Pitch LFO Macro Select MP[num] This will choose a particular Pitch LFO Macro to apply to the subsequent notes, and the [num] corresponds directly to the assigned value of the @MP[num] you want.

     			 The valid range is 0 ~ 127, and 255 cancels the effect.
    
  • Pitch LFO OFF MPOF This is equivalent to issuing MP255 - it turns off the Pitch LFO Macro, effective at the beginning of the next note (issuing it after the currently playing note will not cancel it on that note).

  • Pitch Envelope Macro Select EP[num] This will choose a particular Pitch Envelope Macro to apply to the subsequent notes, and the [num] corresponds directly to the assigned value of the @EP[num] you want.

     			 The valid range is 0 ~ 127, and 255 cancels the effect
    
  • Pitch Envelope OFF EPOF This is equivalent to issuing EP255 - it turns off the Pitch Envelope Macro, effective at the beginning of the next note (issuing it after the currently playing note will not cancel it on that note)

  • Note Arpeggio Macro Select EN[num] This will choose a particular Arpeggio Macro to apply to the subsequent notes, and the [num] corresponds directly to the assigned value of the @EN[num] you want.

     			 The valid range is 0 ~ 127, and 255 cancels the effect
    
  • Note Arpeggio OFF ENOF This is equivalent to issuing EN255 - it turns off the Pitch Envelope Macro, effective at the beginning of the next note (issuing it after the currently playing note will not cancel it on that note)

  • Track Loop L The almighty L sets a loop point in your sequence. This will ensure that your chiptune plays forever in the minds of your fans. Until they hit stop. Then, maybe, if you're lucky and skillful, afterwards too.

     			 Simply place the L at the beginning of the sequence you wish to
     			 have looping continuously - make sure that the loop points of all
     			 of the active channels line up, unless you have planned
     			 otherwise, like for a repetitive drum track.
    
  • Repeat [ ~ | ~ ][num] This will repeat any sequence of events (notes or commands) [num] times. For example, [ cdefg ]4 is equivalent to cdefgcdefgcdefgcdefg. Useful as a limited loop.

  • Wait w [len] Delays execution of the next command by [len], and preserves the execution of the current command for the duration of the wait. This is similar to r but it doesn't necessarily impose silence.

Clone this wiki locally