PpMCK

From vgmrips

ppMCK is a MML compiler to compile into NSF format. All expansion audio in the NSF specification is supported. Since NSF does not prohibit the use of multiple expansions at once that it is possible to compile such NSFs.

Some things below are marked "(extended)" meaning it is an unofficial feature, and won't work if you download the official version mentioned below.

Compiler Instructions

The name of compiler instructions are case-insensitive. (This list is incomplete.)

#TITLE

Set title field in header. Official version uses the string "Title" by default; unofficial version uses "<?>" by default.

#COMPOSER

Set composer field in header. Official version uses the string "Composer" by default; unofficial version uses "<?>" by default.

#MAKER

Set copyright field in header. Official version uses the string "Maker" by default; unofficial version uses "<?>" by default.

#PROGRAMER

Specify name of people who put it into the MML; not written into the NSF but it is written into the ASM files generated as an intermediate step. The misspelling is actually the correct usage.

#PROGRAMMER (extended)

Same as #PROGRAMER.

#EX-VRC6

Enable VRC6 expansion audio (channels marked MNO).

#EX-VRC7

Enable VRC7 expansion audio (channels marked GHIJKL).

#EX-DISKFM

Enable FDS expansion audio (channels marked F). (Warning: It might interfere with some other sound chips, except Namco 163 and MMC5.)

#EX-MMC5

Enable MMC5 expansion audio (channels marked ab, lowercase).

#EX-NAMCO106

Enable Namco 163 expansion audio (channels marked PQRSTUVW). Specify number of channels (1 to 8) as the parameter. The frequency of a note will therefore be divided by the number of channels. Although there is no actual N106 chip in existence, this number is actually the correct usage. Example:

#EX-NAMCO106 4

#EX-NAMCO163 (extended)

Same as #EX-NAMCO106.

#EX-FME7

Enable Sunsoft 5B expansion audio (channels marked XYZ).

#EX-SUN5B (extended)

Same as #EX-FME7.

#EX-SUNSOFT5B (extended)

Same as #EX-FME7.

#AUTO-BANKSWITCH

This command automatically handles bankswitching in the most optimized way possible. Use for large files

#PITCH-CORRECTION

Fix pitch in vibratos, and enables pitch macros for N163 channels. It also enables the use of the SA command on N163 channels.

#DPCM-RESTSTOP

Causes DPCM channels to stop if a rest note is played.

#OCTAVE-REV

If set to 1, then the < and > commands are reversed.

#GATE-DENOM

Sets the base value for q command. Default is 8.

#INCLUDE

Include another mml file into current file. Useful for loading default instrument macros.

#CUSTOM-TUNING (extended)

Define a custom tuning for each note, rather than using 12-tone equal temperament.

Macros

Macros are usually defined at the top of an mml file and later called in the song data. It is not necessary to organize your file in this way but it is required to define a macro before calling it. Values are stepped through at a 60hz rate.

@#

Define a duty cycle macro. For defining any macro, the format is like:

@5={0 1 2 2 1 | 0 2}

The first number is a envelope number you can refer later in your music. The numbers before | is the first part, and the afterward part is looped. Range for 2A03 and MMC5 is 0 to 3. Range for VRC6 is 0 to 7.

Define macro using single @# and call using @@#.

@v#

Define a volume envelope. Cannot be used with DPCM and triangle channel. Range for FDS (channel F) and VRC6 saw (channel O) is 0-63. Range for all other channels is 0-15. Example envelope:

@v0={10 10 10 9 9 9 8 8 8 7 7 7 6 6 6 5 5 5 4 4 4 3 3 3 2 2 2 1 1 1 0}

Define macro using @v# and call using the same.

@EN#

Define a note macro (arpeggio). Values entered denote change from previous note, not the starting note. An example major triad:

@EN0={0 | 4 3 -7}

User must be careful to keep note range within the selected channel's range. Define macro using @EN# and call using EN# and ENOF to stop.

@EP#

Define a pitch macro. Values entered denote change from previous note, not the starting note. Range is -127 to 127. Note that the final value will be interpreted as a repeating value. Example:

@EP0={-15}

Is identical to:

@EP1={|-15}

But different from:

@EP2={-15 0}

Define using @EP# and call using EP# and EPOF to stop.

@MP#

Define a vibrato macro. All definition have 3 values for its parameters. First parameter is delay until vibrato effect, in frames. Second argument is speed of the vibrato. Third paramter is depth. An example vibrato:

@MP0={8 2 6}

Define using @MP# and call using MP# and MPOF to stop.

@DPCM#

Define a path for .dmc files and parameters for playback. Must include at least 1 parameter and up to 4. Path must be relative to location of ppmck_e.exe.

  • First parameter is speed of sample. Range is 0 to 15 with 15 being regular speed.
  • Second parameter is the playback size of the sample. Requires that parameter 1 is defined. Specifying 0 or leaving this parameter out will make playback size equal filesize, which is ok. If the sample filesize is less than the size you specify here, the sample will be padded to it at playback.
  • Third parameter is the Initial Delta Counter value, which is written to $4011 on note trigger. $7F is recommended. If you put in $00, you may get clicks. Using a non-zero value may change the volume of Triangle track C and and Noise Track D, as does regular usage of DPCM samples which do not return to position $00 at the final sample.
  • Fourth parameter is DMC Playback mode.
    • 0 = normal playback mode.
    • 1 = looped playback mode.
    • 2 = normal playback mode with IRQ (not recommended).

An example Konami drum with a $4017 pop:

@DPCM0={"samples/LagrangePoint_$FF40.dmc" 15 0 0 0}

The DPCM are assigned to the MIDI note number corresponding to which macro# you define. For this purpose many composers define @DPCM0 which is played on channel E with C at octave 0 and then skip @DPCM1 and define @DPCM2 which is played with D on octave 0.

@OP#

Define a custom OPLL patch (usable with VRC7). Please see documentation of OPLL for more information. Range is 0 to 255 and can be denoted as hex using $## or x## Example:

@OP0={$43 $02 $20 $04 $F1 $F1 $00 $03}

Define using @OP# and call using OP#. Usage of calling a custom patch will take precedence over default patches called using @@#

@FM#

Define an FDS wavetable. Must use 64 values. Range is 0 to 63. Example square wave:

@FM0={
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00}

Define using @FM# and call using @@#

@MW#

Define pitch modulation wavetable for FDS. Must use 32 values. Range is 0 to 7:

  • 0 means mod counter stays at current value.
  • 1 means mod counter is incremented +1.
  • 2 means mod counter is incremented +2.
  • 3 means mod counter is incremented +4.
  • 4 means mod counter is reset to starting value.
  • 5 means mod counter is decremented -4.
  • 6 means mod counter is decremented -2.
  • 7 means mod counter is decremented -1.

Define macro using @MW# and is only called using the 4th parameter in @MH# macro. Requires the use of @MH# command to be audible. Only 8 macros may be defined. Example sine wave:

@MW0={7 7 7 7 7 7 7 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 7 7 7 7 7 7}

See FDS documentation for exact meaning of these values.

@MH#

Define FDS modulation. Requires 4 parameters.

  • First parameter is delay until modulation takes effect, in frames. Range is 0 to 255
  • Second parameter is speed at which the MW0 table is ran through, in hertz. Range is 0 to 4095
  • Third parameter is depth of modulation. Range is 0 to 63.
  • Fourth parameter chooses which MW# to use. Range is 0 to 7.

Example of FM modulation using previous tables for an A440 note:

@MH0={0 440 63 0}

See FDS documentation for exact meaning of the depth values.

@N#

Define N163 wavetable. First value is a parameter indicating where to write the wavetable within the internal space of its 128 slots. Subsequent values are the wavetable. Range for wavetable values is 0 to 15. Must be provided a multiple of 4 values ranging from 4 to 32 samples. If using a table of size 4, then first parameter's range is 0 to 31. Choosing 0 will store the 4-sample wave in the first 4 slots of the available 128 slots (positions 0 to 3). Choosing 1 will store it in the 2nd 4 slots (positions 4 to 7). If using a table of size 32, then first parameter's range is 0 to 3. Choosing 3 will store it in the 4th 32 slots (positions 96 to 127). Example organ of sample size 16 with its data stored in positions 0 to 15:

@N0={0, 11 15 9 13 5 10 9 8 7 6 5 10 2 6 0 4}

Song Data

* (extended)

Define a text macro. After * you put a single ASCII character to indicate the name of macro, and then the data follows.

A to Z and lowercase a&b

Enter the music into a channel. You can enter more than one letter to enter the music into multiple channels at once.

Commands inside of a track

These commands are case-sensitive. (This list is incomplete.)

a b c d e f g

Enter notes into the music. Optionally can be followed by any number of - and + for flat/sharp, and in unofficial version only can also include ' for one octave high. After that, can optionally include note length, and optionally dots to increase a note length.

h i j (extended)

More notes, similar to above. Usable only if #CUSTOM-TUNING is specified.

k

Key off.

l

Set the note length, using number and optionally dots. This applies to further notes without the length explicitly specified. Use numbers like 4 for quarter notes, 8 for eighth notes, etc.

n

Enter a note number directly.

o

Specify octave by number. Which octave number is possible depend on which channel.

q

Set note quantize. This is more like the MS, MN, ML commands in QBASIC, but must be specified by number.

r

Rest. Can optionally include length like notes do.

t

Specify tempo.

v

Specify volume. Possible range depend on which channel.

y

Allow writing directly into the NSF memory map. Use address, comma, and data to write.

D

Detune amount. Zero cancels detune.

K

Transpose amount. The notes played further are transpose by that many keys (can be positive or negative).

L

Song loop start. After the song is finished, it restart from this point. Each channel does so separately, therefore it is possible to have desynchronized loops and ostinato and so on.

^

Tied notes. Uses optional length like above. Causes duration of note just played to be extended.

@

For square channels, set the duty. In the case of 5B, it sets the disable oscillator flags

  • 2A03, MMC5: 0 means 12.5%, 1 means 25%, 2 means 50%, 3 means 75%.
  • VRC6: 0 to 7 is 1/16 up to 8/16.
  • 5B: 0 means both Tone and Noise disabled, 1 means Noise disabled, 2 means Tone disabled, 3 means all oscillators enabled. Envelope is turned on by setting Envelope Speed and turned off only with speed 0.

@@

For square channels (except Sunsoft), activate a duty envelope.

For VRC7, select a OPLL patch. To use built-in patches, specify numbers 1 to 15, and 17 to 31. Note these are different from ordinary OPLL patches! To use custom patches, add 64 to the number you defined it by. Specify 0 to load the same custom patch as it is already loaded. Note that you can only load up to one custom patch at once.

@n

Enter the note period and duration (in frames) directly.

@q

Set note quantize. Causes notes to be stopped a number of frames in advance.

@v

Activate a previously defined volume envelope.

? (extended)

Track questioning. Follow by a letter, and skip commands if not on this channel. Specifying ?. allows commands working in all channels.

* (extended)

Call a text macro.

External links