sdlterm-mck
v1.2.0
Published
SDLTERM Music Creation Kit
Downloads
2
Readme
This is the SDLTERM Music Creation Kit. Provided are the MML compiler, MML
driver, assembler, and playback testing program.
This program is public domain.
To use: Input to mck.js is the MML code you wish to compile. Append the
contents of driver.asm and then that is input to asm.js and then the
output of asm.js is the data which should be passed as the second argument
to the SDL.prototype.music() function. You can also use it as input to the
program play.js to test it; the argument to play.js is the volume. You can
also adjust volume at runtime with the up/down arrow keys, and then you
can push escape to quit.
They are a collection of command-line tools and are not useful to import
into other programs.
The waveforms in play.js are the following:
0 = 50% duty square wave
1 = 25% duty square wave
2 = triangle wave
3 = saw wave
4 = sine wave
5 = half rectified sine wave
6 = full rectified sine wave
7 = regulation rectified sine wave
The waveforms 4,5,6,7 are equivalent to OPL2 waveforms 0,1,2,3.
Since this code is public domain you may copy the code for the waveforms
into your own program freely if you want to do so.
Commands in the MML file can be:
; Indicates a comment from here to the end of this line. Allowed anywhere
inside of any line.
@ Add a number and then = and a list of more numbers to define an
instrument. See section below about instrument definitions please.
@@ Add a number and then = and a list of values to define an envelope.
Use | to indicate the loop point of the envelope; when it reaches the end
it will repeat from this point. Values in envelope must be nonzero. This
envelope can also contain ' and a number after any number, to repeat that
number that many times; and you can use three numbers with : in between in
order to make a linear sequence, with the first number being the start,
the second number being the end, and the third number being the step
amount. The step amount can include fractions.
@EN Add a number and then = and a list of numbers (-127 to 127) to define
an arpeggio envelope. You can use | to indicate loop point like above. The
numbers are the number of semitones relative to the previous note; zero is
allowed for use same note. For example "| 0 4 0 3 0 -7" defines a major
chord arpeggio.
* Define a macro. The next character after the asterisk is the macro name
and then the rest of the text is the contents of the macro.
# Directives. Include the name of directive and then a space and the
value (if applicable). List of directives is below.
ABCDEFGH Use one or more letters followed by a space and then the MML
text of the channel. The MML text is then on all channels of the letters
that you have specified, and you can add additional text on later lines.
Anywhere a number is expected (except directives), it can be decimal, or
use $ at front if it is hexadecimal.
Instrument definitions consists of the following values in order:
- Oscillator 1 multiplier: Should be 256 for normal frequency, or can be
128 for half frequency and so on; use 0 for a fixed frequency (defined by
the detune parameter). Can be any number 0 to 65535.
- Oscillator 2 multiplier
- Oscillator 3 multiplier
- Oscillator 1 volume: A number 0 to 65535. Note that this is only the
amplitude of this oscillator; the channel mode register controls how the
output from this oscillator is used, and may not necessarily be audible.
- Oscillator 2 volume
- Oscillator 3 volume
- Oscillator 1 sample: Range is 0 to 255. The number of the sound wave to
play back. This is the index into the sample list and is not necessarily
the same as the sound effect number.
- Oscillator 2 sample
- Oscillator 3 sample
- Channel mode: A 16-bit number. Bit10 makes oscillator 1 audible, bit9
makes oscillator 2 audible, bit8 makes oscillator 3 audible. Frequency
modulation is controlled by bit4 (osc1 modulates osc3), bit3 (osc2
modulates osc3), and bit2 (osc1 modulates osc2). Bit1 implements ring
modulation. Bit0 enables hard sync (osc2 controlling osc3). Bit5 causes
the frequency modulation to be relative to the carrier frequency.
- Channel filter: Can be 0 to 65535 to specify a low pass filter for the
output of this channel, where 0 means no filter and higher numbers result
in stronger filters.
- Oscillator 1 detune: Can be a number 0 to 255. If greater than 0 then
it is added to the final frequency of the first oscillator. You can use
the #OSC-DETUNE directive to make it to detune the frequency of a
different oscillator instead.
- Octave change: Can be 0 to 8, where 4 means use the normal octave. If
a different number, the note in the MML text will be recorded using a
different octave instead.
The volumes, samples, channnel mode, and filter may use envelopes instead
of a value. If an envelope, use @ and the envelope number. It will then
play through the values in the envelope at one value per frame.
MML text consists of commands:
cdefgab Any of letter to play the note in the current octave. You can
follow by zero or more of + for sharp, - for flat, and ' for high octave.
And then can optionally have the note length afterward.
l Set default note length, by a number. For example 4 is a quarter note
and 8 means eighth note; you can also add dots afterward, each of which is
adding half of the length.
o Give a number to set the octave of subsequent notes. Valid range is 0
to 8. The frequency is more precise for higher octaves because it is
stored as an integer.
< Lower octave. (If #OCTAVE-REV 1 then higher octave instead.)
> Higher octave. (If #OCTAVE-REV 1 then lower octave instead.)
t Set tempo (specify a number). That is the number of frames that make
one whole note.
r Rest. Can optionally include a length. This channel is silence during
this time.
^ Tie. Can optionally include a length. The previous note continues
playing during this time.
@ Follow by a number to select the current instrument.
EN Enable arpeggio. Follow by the number of the arpeggio envelope to use.
ENOF Disable arpeggio.
L Set loop point. If not specified, loops from the beginning. You can set
the loop individually per channel, for example to make ostinato.
K Give a number afterward to set transpose. Can be positive, negative, or
zero. All further notes are transposed by this many semitones, until it is
cancelled by another K command (which is an absolute transpose value, and
is not relative to the previous transpose value).
P Set a linear envelope after the note. Can play only if this command
comes immediately after a note or tie command; otherwise has no effect.
Follow the P with one of the letters F (filter), G (old value for filter),
Q (frequency), S (sample offset), V (volume). If F or G then it is then
immediately followed by the amount of adjustment per frame. If Q or S or V
then put a number 1 to 3 (specifying which oscillator) and then a comma
and the amount of adjustment per frame.
? Track questioning. If followed by a letter A to H, will skip everything
up to the next ? command. If followed by . then don't skip.
* Follow by one character to call a macro. The text of that macro is then
used just as though it were entered directly. Can't nest macros.
[ Begin local loop.
] End local loop. Follow by the number which is the repeat count. Loops
cannot be nested.
@q Set note quantize. The note is cut off by the specified amount of
frames and then the rest of the note duration is silenced.
The valid directives are:
#FRAME-RATE Follow by a number. The frame rate in Hz is 44100 divided by
the specified number; there are sixty frames per second by default.
#OCTAVE-REV If 1 then < and > are reversed.
#OSC-DETUNE By default the setting is 1. Using a different number means
that instruments detune a different oscillator.
#TEXT Follow by text, which includes the null-terminated ASCII text into
the compiled file starting at file offset 3. No effect on music.