XPMCK - Cross Platform Music Compiler Kit
Mic, 2008
Website: http://jiggawatt.org/muzak/xpmck/
Contact: micol972@gmail.com
What you will need
Some basic knowledge of MML. For syntax information in english, see these guides:
http://www.nullsleep.com/treasure/mck_guide/
http://www.geocities.co.jp/Playtown-Denei/9628/mck/mckc-e.txt (mirror)
To build the SEGA Master System / Game Gear version of the player you need WLA-DX:
http://www.villehelin.com/wla.html
P(P)MCK commands supported in XPMCK
&, ^, <, >, [], {}, D, l, o, q, t, v, v-, v+, @, @@, @EN, @EP, @MP, @q, @v
New commands added in XPMCK
@ADSR, @CS, @MOD, @WT, $, !, AM, FB, M, MF, OP
Commandline options
-h Show help
-v Verbose mode
-w Treat warnings as errors
-gen Output data suitable for the SEGA Genesis
-sgg Output data suitable for the SEGA Game Gear
-sms Output data suitable for the SEGA Master System
If no output filename is specified it will be given the name .asm by
default.
If the output filename has a .vgm extension and the target is gen, sms or sgg the
compiler will generate a .vgm file (uncompressed) instead of an .asm file.
Compiler directives
These are the XPMCK-specific preprocessor commands available:
#ELSE Used together with IFDEF/IFNDEF.
#ELSIFDEF Used together with IFDEF/IFNDEF.
#ENDIF Used together with IFDEF/IFNDEF.
#EN-REV num If num==0 EN macros work similar to other
MML implementations.
If num==1 EN is not cumulative, meaning that
instead of {| 3 4 -7} you write {| 3 7 0}.
#ERROR "message" Output an error message and abort compilation.
#IFDEF, #IFNDEF Conditional compilation depending on if a
symbol is defined or not.
Currently the only symbol defined is the selected
target, so this check would be valid:
#IFDEF SMS
; blah
#ELSIFDEF SGG
; blah
#ENDIF
The boolean operators & (AND) and | (OR) can be
used:
#IFDEF SMS | SGG
; blah
#ENDIF
Note that the boolean operators take opposite
meanings when IFNDEF is used, i.e.:
#IFNDEF SMS | SGG ; Means "If not defined SMS or not defined SGG"
#INCLUDE "filename" Include the contents of another MML file.
#NTSC Inform the compiler that you are going to play the
song with an update frequency of ~60 Hz. Along with
the tempo and the note lengths this is used to
calculate how long each note should be played.
#PAL Specify a 50 Hz update frequency. Mutually exclusive
to #NTSC. Some targets only support 60 Hz playback -
for these targets this command is ignored.
#TUNE Use an alternative frequency table on the SEGA Master
System to lower the error percentage on higher octaves.
#WARNING "message" Output a warning. Aborts compilation if the -w switch has been used.
#UNIFORM-VOLUME num Specify a custom maximum volume for all channels.
The volumes will be scaled to the valid range of
the target machine.
Syntax
Comment
Single line comments start with a ; (semi-colon).
Multiline comments start with /* and end with */
Instrument / algorithm selection
@num
Apart from selecting the duty cycle for channels that support it,
@ also has another purpose in XPMCK. For FM channels it is used to
select the instrument or algorithm for the channel.
On the SEGA Master System (YM2413) the valid range depends on the
channel's current output mode:
M0 (melody):
@0 = Custom
@1 = Violin
@2 = Guitar
@3 = Piano
@4 = Flute
@5 = Clarinet
@6 = Oboe
@7 = Trumpet
@8 = Organ
@9 = Horn
@10 = Synthesizer
@11 = Harpsichord
@12 = Vibraphone
@13 = Synthesizer bass
@14 = Acoustic bass
@15 = Electric guitar
M1 (rhythm):
@0 = Bass drum
@1 = Snare drum
@2 = Hi-hat
@3 = Top cymbal
@4 = Tom-tom
When in rhythm mode, each instrument has a global volume that is shared by
all channels. This means that a channel modifying the volume for one of the
rhythm instruments will affect all other channels that are using the same
instrument.
On the SEGA Genesis (YM2612) the valid range is 0-7 and selects a range
of instrument sounds according to the following table:
@0 = Distortion guitar, high hat chopper bass
@1 = Harp, PSG-like sound
@2 = Bass, electric guitar, brass, piano, woods
@3 = Strings, folk guitar, chimes
@4 = Flute, bells, chorus, bass drum, snare drum, tom-tom
@5 = Brass, organ
@6 = Xylophone, tom-tom, organ, vibraphone, snare drum, bass drum
@7 = Pipe organ
The type of sound generated on the SEGA Genesis also depends on the
current feedback setting (see the FB command).
FM channel ADSR envelope
@ADSRnum = { attack decay sustain release } or
{ attack decay1 decay2 sustain release }
Specify attack rate, decay rate, sustain level and release rate.
On the SEGA Master System (YM2413) the four-parameter version
is used and all values have a range of 0-15 (15 being the fastest
rate / maximum level). Only the custom instrument (@0) uses the
ADSR parameters, all other instruments have fixed ADSR envelopes.
On the SEGA Genesis (YM2612) the five-parameter version is used
and all values have a range of 0-31 (the LSB of sustain and release
is ignored since they are stored as 4-bit values in the YM2612
registers). decay1 is the initial fast decay rate, while decay2 is
the secondary slower decay rate. This command is operator-specific.
Example:
#IFDEF GEN
@ADSR1 = {28 29 4 25 10}
#ELSIFDEF SMS
@ADSR1 = {12 13 11 9}
#ENDIF
F v10 OP0 ADSR1 c4
Channel separation (pan) macro
@CSnum = { ... | ...}
Pans the sound on targets that support it. Valid range is -63-63.
-63 means full left, 0 means center and 63 means full right.
The macro is applied to a channel with CSnum and disabled with CSOF.
Modulator
@MODnum = { lfo ams fms }
Specifies a modulator to be used for modulating the amplitude and/or
frequency of a channel.
lfo selects the frequency of the modulator LFO. Valid range is 0-7
(7 being the maximum frequency). Note that the LFO is shared for all channels,
so issuing a MOD command on one channel will affect all other channels that
are using a modulator.
ams selects the amplitude modulation sensitivity. Valid range is 0-7
(7 being the maximum sensitivity). Amplitude modulation also has to be separately
enabled with the AM command. This can be done per operator.
fms selects the frequency modulation sensitivity. Valid range is 0-3
(3 being the maximum sensitivity).
This command is currently only supported for the FM channels on the SEGA Genesis.
The macro is applied to a channel with MODnum and disabled with MODOF.
Example:
@MOD0 = {4 2 2}
E v100 MOD0 OP0 AM1 c1
Waveform definition
@WTnum = { sample sample sample ... } or
{ "filename.wav" resample volume }
Defines a waveform for playback on channels that supports it.
In the first case the sequence should contain 32 unsigned samples in the
range 0..MAX-VOLUME.
In the second case the first value should be a string specifying a
.wav file to convert. The resample parameter is the frequency to
resample the .wav file to, and volume specifies the upper limit
of the volume range the sample data will be scaled to.
Example:
@WT0 = {"kickdrum.wav" 8000 15}
@WT1 = {0 0 0 15 0 0 0 15 0 0 0 15 0 0 0 15 0 0 0 15 0 0 0 15 0 0 0 15 0 0 0 15}
C v3 WT1 c4
General macro
$id { ... }
Define/use a general macro. These can be used to save typing if a
lot of smilar patterns are used in a song. Parameters are dereferenced
with %num% (%1% being the first parameter).
Example:
$1 { [%1%]4 %2%.. }
A $1(c, a)
The macro invokation on channel A will expand to [c]4 a..
Callback
!id(frequency)
Call a function on the host CPU. E.g. if playing a song on the
SEGA Master System this command would call a function in your
Z80 code. This can be used to synchronize the visual output
of your program with the music.
The frequency parameter specifies how often the function should be
called. The available values are:
0 Never (disable the callback).
1 Once (called during the next update).
EVERY-NOTE Called for every new note that is
played on the channel(s).
Example:
AD !foo(EVERY-NOTE)
A l16 cdef
D l32 [g]8
Here the function foo will be called each time a new note is
played on channel A or D.
Amplitude modulation enable
AMnum
Used for the FM channels on the SEGA Genesis (channels E..J).
Enable/disable amplitude modulation for the currenly selected operator(s).
Valid range of num is 0-1 (0=OFF, 1=ON).
This command is used in conjunction with MOD.
Detune
Dnum
For most targets this command works as usual (num specifies number of semitones
to detune by).
For the FM channels on the SEGA Genesis (channels E..J) the detune
command has a more limited range of -3-3. The reason for this is that
the value is written to the DT1 bits of the selected operator(s).
Detuning for these channels is also controlled by the MF command.
FM feedback
FBnum
Specifies the amount of self-feedback for operator 1. This command
is used in combination with the @ command on the SEGA Genesis FM
channels to select the type of sound generated.
Valid range is 0-7.
Example:
E v9 @2 FB6 c1
Output mode
Mnum
Specifies the output mode for channels that support more than one
output mode.
For the SEGA Master System this command is used for the FM channels
to select melody or rhythm mode (M0 = melody (default), M1 = rhythm).
Example:
E v8 M0 @7 c1
F v9 M1 @0 [d32r32]16
FM detuning multiplier
MFnum
Specifies the amount of detuning together with the D command for the FM
channels on the SEGA Genesis.
Valid range is 0-15.
This command is operator specific.
Example:
E OP1 D1 MF7 ; Set detune and multiplier for operator 1 on channel E
FM Operator select
OPnum
Used for the FM channels on the SEGA Genesis (channels E..J).
Each channel has four operators, which are set up in various configurations
depending on the selected algorithm. Some commands are applied on the channel
while others can be applied per operator. OP selects the operator to apply
subsequent operator-specific commands to.
Valid range of num is 0-4. If num==0 all operators are selected.
Example:
E OP0 ADSR1 ; Set ADSR envelope for all operators on channel E
Implementation specific notes
SEGA Game Gear
Volume range is 0..15. The lowest playable note is A in octave 2.
Channels A, B, C are tone channels that output square waves.
Channel D is used for noise. @0 selects white noise and @1 selects periodic
noise.
Limited panning is supported (negative values means full left, zero means center,
positive values means full right).
EP and MP can be used together, but they will interfere with eachother.
For the noise channel the octave setting is irrelevant. The noise generator has
four different clock settings that is determined by the current note MOD 4. Below
is a list of what each note corresponds to:
c, e, g+: High pitch
c+, f, a: Medium pitch
d, f+, a+: Low pitch
d+, g, b: Pitch determined by channel C.
By selecting periodic noise generation with pitch determined by channel C it is
possible to use the noise channel as a kind of extra tone channel.
SEGA Master System
Volume range is 0..15.
The lowest playable note is A in octave 2 for channels A..D, and C in octave 1 for
channels E..G.
Channels A, B, C are tone channels that output square waves.
Channel D is used for noise. @0 selects white noise and @1 selects periodic
noise. The noise's pitch is determined in the same way as for the SEGA Game Gear.
Channels E, F, G are FM channels that can output a variety and sounds. Note
that if you want to play a song using these channels on an actual console
you will need a modified SMS / Mark-III with an added YM2413 (or a japanese SMS).
EP and MP can be used together, but they will interfere with eachother.
SEGA Genesis
Volume range is 0..15 for channels A..D, and 0..127 for channels E..J.
The lowest playable note is A in octave 2 for channels A..D, and C in ocatve 1 for
channels E..J.
Channels A, B, C are tone channels that output square waves.
Channel D is used for noise. @0 selects white noise and @1 selects periodic
noise. The noise's pitch is determined in the same way as for the SEGA Game Gear.
Channels E, F, G, H, I, J are FM channels that can output a variety and sounds.
EP and MP can be used together, but they will interfere with eachother.
MP is ignored for channels E..J since MOD can achieve pretty much the same thing.
General
Effects are stepped through once per frame.
TODO
Things that would be nice to do, time permitting:
- Fix bugs.
- Write playback libraries for other platforms.
- Implement more effects.
- Create a GUI / player for Windows.
- Optimize the playback libraries.