CCCC HH HH IIIIII PPPPPP NN NN SSSSS FFFFFFF XX XX
CC CC HH HH II PP PP NNN NN SS SS FF F XX XX
CC HH HH II PP PP NNNN NN SS FF F XXX
CC HHHHHH II PPPPP NN NNNN SSSSS FFFF XXX
CC HH HH II PP NN NNN SS FF F XX XX
CC CC HH HH II PP NN NNN SS SS FF XX XX
CCCC HH HH IIIIII PPPP NN NN SSSSS FFFF XX XX
CHIPNSFX, cross-platform lightweight music tracker and player
developed by Cesar Nicolas Gonzalez / CNGSOFT
1.- Copyright and warranty
2.- What is CHIPNSFX?
3.- Requirements and setup
4.- Using the tracker
5.- Using the player
A.- Version history
1.- Copyright and warranty
CHIPNSFX was developed by me, Cesar Nicolas Gonzalez (CNGSOFT).
CHIPNSFX is freeware. Shareware distributors can distribute it if they
only take fee for copying. Software and documentation are provided "as
is" with no warranty.
CHIPNSFX is not public domain. I retain the copyright, although I plan
to switch to GPL in the future if I manage to meet certain conditions.
2.- What is CHIPNSFX?
CHIPNSFX is a software suite whose purpose is to let the user write
music to be played on 1980s 8-bit platforms based on the Z80 processor
and three-channel, white-noise sound generators such as the AY-3-8910
and YM2149 chips. This spans several platforms: Amstrad CPC, Sinclair
Spectrum 128, MSX1, Sega Master System... In theory other platforms
such as the Commodore 64 would be supported as well.
The suite is divided in two halves: on one hand, CHIPNSFX.EXE, the
tracker, a Win32 console application that handles both the writing of
the music and the generation of binary data to be used by the player;
on the other hand, CHIPNSFX.I80, the player, a Z80 library to be used
by games and demos requiring a tiny code size (between 600 and 800
bytes) while still allowing for sound effects such as amplitude and
noise envelopes and effects, chord arpeggios and note vibratos.
The suite also includes several songs written with the tracker and a
simple jukebox for Amstrad CPC as an example of how to use the player.
3.- Requirements and setup
The tracker requires Windows 2000 or later to work. The tracker will
try using a sound card to play songs unless told not to.
The player is written for the Z80 assembler AS80, although modifying
it for other assemblers such as MAXAM shouldn't be difficult.
4.- Using the tracker
The tracker can run in two modes: data generator and tracker proper.
The first mode is limited to translating a song into raw data for the
player: it's thus to be used within batch processing, Makefile scripts
and other command-line activities. By default, it simply takes two
command line parameters, the first one being the source song CHP file,
the second one being the target INCLUDE file. Several command line
options let the user fine-tune its behavior:
* -l STRING: sets the prefix of the data within the INCLUDE file. For
example, "-l xyz_" means that the three channels are labelled "xyz_a",
"xyz_b" and "xyz_c" respectively.
* -c N: sets the INCLUDE file maximum width in characters (default 80)
just in case the assembler cannot accept overly long lines.
* -b: generate song with short calls. By default, songs are generated
with long calls: they're heavier but compatible. If a song is small
enough, short calls can save further space. Songs too big for short
calls will cause overflow errors when assembling their INCLUDE files.
* -b1, -b2, -b3: like -b, but for just one channel (A, B or C), if one
or two channels are short enough to benefit from -b but the others are
too long for -b to work correctly.
* -r: forbids loops. Loops are used to compress the song when strings
of identical notes are detected, but they make data generation slower
and also make playback slightly slower.
* -w: export full song into a WAVE file target.
* -W: export song loop into a WAVE file target.
* -y: export full song into a YM3b file target.
* -Y: export song loop into a YM3b file target.
* -F: set playback quality to 48000 Hz rather than the default 44100.
* -L: use linear amplitude rather than the default exponential. It can
be useful in songs requiring very gradual crescendos. See below "Using
the player", compile time CHIPNSFX_FLAG value +64.
The second mode enables the tracker proper and is run with either no
command line parameters or with only one, the song CHP file. It allows
the perviously seen options -F and -L plus the following ones:
* -p: start playing the song after loading it.
* -m: mute mode, don't use the sound card at all.
* -P: cursor follows playback.
* -k STR: set custom key map. By default, the tracker assumes a QWERTY
keyboard, i.e. "-k zsxdcvgbhnjmq2w3er5t6y7ui9o0pl1."
* -k1: set QWERTZ key map, a shortcut to the longer and cumbersome
"-k ysxdcvgbhnjmq2w3er5t6z7ui9o0pl1." that switches Y and Z.
* -k2: set AZERTY key map.
The tracker proper is similar to other musical editors. The general
idea is to define the songs as fragments (the "patterns") arranged on
an ordered list (the "orders") and type the notes on these fragments
as instances of sound wave styles (the "instruments").
The screen layout is divided in five panels: a narrow header (song
title and description), a body divided in three columns (current
pattern, instruments, order list) and a narrow footer (song parameters
and runtime information).
Navigation is to be done with the keyboard, either with Control-Tab or
Control-I to switch to the next panel (Control-Shift-Tab or Control-H
switch to the past panel) or with single keypresses: F2 enables the
pattern panel, F3 enables the instrument panel, F4 enables the order
list panel and F9 enables the parameter panel.
The arrow keys ("cursors") let the user move within a single panel.
In the panels where area selection is possible, Shift-Cursor lets the
user define the span of the currently selected area. Tab, Shift-Tab,
Home, End, Page Up and Page Down allow for faster motion.
The currently loaded song can be played by pressing F5 (whole song
from the beginnign), F6 (current pattern only) and F7 (whole song from
the current location). F8 stops the playback.
F1 shows a simple help screen with the keyboard shortcut list:
* Numberpad + goes to the next order in the order list.
* Numberpad - goes to the past order.
* Numberpad * or Control-Right select the next octave.
* Numberpad / or Control-Left select the past octave.
* > or Control-Down select the next instrument.
* < or Control-Up select the past instrument.
* SPACE either assigns the currently selected instrument to the note
below the cursor (if the pattern panel is active) or plays the note A4
(440 Hz) with the current instrument (if it's the instrument panel).
* ENTER either selects the instrument used by the note below the
cursor (pattern panel) or plays a noise-only version of the current
instrument (instrument panel).
* The letters and numbers in the keyboard either write notes on the
pattern (pattern panel), modify the name and the values of the
instrument (instrument panel) or modify the pattern indices in the
order list (order list panel). As in other trackers, notes are set on
the keyboard as if it were a piano: thus ZXCVBNMQ would play all the
eight major notes of the currently active octave.
* Control-F1 enables all playback channels at once; Control-F2 toggles
channel A, Control-F3 toggles channel B and Control-F4 toggles channel
C. Pressing Control-Shift rather than just Control makes the channel
* Control-Q and Control-A raise and lower the currently selected notes
(pattern panel) or the currently selected patterns (order list panel)
by a semitone. Control-Shift rather than just Control raises or lowers
said notes and patterns by a whole octave.
* Control-T and Control-G shift the active notes, instrument or orders
up and down within their lists. Use them to fix mistakes while writing
the notes, to rearrange the instruments or the pattern order, etc.
* Control-D detects whether the current instrument is used or not
(instrument panel) or whether the current pattern is a duplicate of
another one (pattern and order list panels). Control-Shift rather than
just Control erases the current instrument (if unused) or turns the
current pattern into a link to another one (if a duplicate).
* Control-E is the opposite operation of Control-D and checks whether
the current pattern is a link. Control-Shift rather than just Control
turns the link into a new pattern with equivalent contents.
* Control-W applies the current pattern's transposition to its notes,
then sets the transposition value to zero. Links to this pattern are
carefully adjusted in the order list to ensure consistency.
* Control-K sets the end of the current pattern, the last instrument
or the last pattern in the song at the current panel cursor's
position. By default all patterns grow to accomodate notes as the user
types them, so this can be used to trim patterns that grew longer than
they should. It's also to be used to amend inconsistences when
rearranging patterns within the order list window: inconsistent
pattern lengths are tagged with "!!" in the order list, and using this
shortcut in the right location in the pattern panel will solve said
inconsistency. Data outside the boundaries set by Control-K isn't
saved, so use it to get rid of unused instruments and patterns. Bear
in mind that patterns can be up to 96 notes long, there can be up to
255 different instruments and songs can be up to 256 patterns long.
* Control-L sets the looping point in the song, or resets if pressed
two times. A song that plays its last pattern can either loop to the
pattern pointed by Control-L (tagged in the order list with "**") or
stop if no looping point was set.
* Control-Z and Control-Y undo and redo the last change in the song.
* Control-X, Control-C and Control-V cut, copy and paste respectively
areas previously selected by the user. Control-P pastes data too, but
also moves to the end of the pasted area, effectively allowing for
repeated appending of pasted data.
* Control-N erases the currently loaded song from memory; it will ask
the user for confirmation ("Are you sure? [Y/N]"), who will push
ENTER or Y to accept or ESCAPE or N to cancel.
* Control-O loads a song from disc. It may ask for confirmation if
the current song was edited but not saved yet. A simple user interface
will let the user look for the song to be loaded: ENTER accepts the
song file under the cursor and ESCAPE cancels the loading.
* Control-R reloads the current song from disc. Confirmation will be
requested if any edits have been done.
* Control-S saves the song to disc. The user interface lets the user
select the song (by default, the last one saved or loaded) or enter
a new filename by choosing the last entry in the list, "<new file>".
* ESCAPE quits the tracker. It requests confirmation, especially if
the song was modified but not saved.
The pattern panel allows for certain special notes to be written:
* . clears the current note.
* 1 inserts a rest or silence, shown as "^^^".
* L inserts a noise-only note, shown as "C-B".
The instrument panel defines data with eleven hexadecimal fields:
* The first two digits are the starting amplitude: FF is the maximum
level, 01 is the minimum level that still plays a note. 00 disables
the note altogether.
* The next two digits are the amplitude envelope: 00 keeps the
amplitude constant, the range 01 to 5F makes the amplitude rise as
time goes on (01: slowly; 5F: quickly), the range 60 to 7F makes the
amplitude drop or rise once (60: weak rise; 6F: strong rise; 70:
strong drop; 7F: weak drop), the range 80 to 9F sets a simple tremolo
effect, i.e. amplitude drops and rises in a loop (80: weak rise+drop;
8F: strong rise+drop; 90: strong drop+rise; 9F: weak drop+rise) and
the range A0 to FF makes the amplitude drop as time goes on (A0:
quickly; FF: slowly).
* The following two digits are the starting noise value: 00 means no
noise, 01 means high-pitched noise, and FF means low-pitched noise.
* Similarly, these two digits are followed by two more digits that
define the noise envelope: 00 keeps the noise constant, the range 01
to 7F makes its pitch drop as time goes on (01 very slowly, 7F very
quickly), and the range 80 to FF makes it rise as time goes on (80
quickly, FF slowly).
* The last three digits set the sound effect. The first out of these
three can be either 0 (arpeggio) or 1 (vibrato), while the last two
digits set the sound effect parameter XY:
+ The arpeggio's X and Y set the distances in semitones
between the first and second notes and the second and third
notes, respectively. When Y is 0 the arpeggio is 2-step rather
than 3-step; for example, XY=47 stands for the C major triad.
The value F is a special case: it stands for -12 and, if used
as Y, also stops the arpeggio; for example, XY=0F stands for
the arpeggio +0 +0 -12 -12 -12 -12 -12 -12 -12... while XY=FC
stands for +0 -12 +12 0 -12 +12 0 -12 +12...
+ The vibrato's X sets its speed (1 fastest, F slowest) while
Y sets its depth (1 weakest, F strongest).
Instrument 00 is special because it sets a simple portamento onto the
notes it's used with: for example, "C-4 01 ... D-4 00" starts a new
note (C4) with instrument #01, then raises its frequency to D4 without
resetting the wave style.
Indices in the order list panel are hexadecimal numbers.
Values in the parameter panel can be modified as follows:
* Insert and Delete increase and decrease respectively the clock base
(25 Hz, 50 Hz, 100 Hz). Higher bases allow for more definition in the
song, but are more burdensome for the player.
* Up and Down increase and decrease respectively the clock divider.
The higher the divider, the slower the song.
* Right and Left increase and decrease respectively the transposition
in semioctaves. The higher the transposition, the sharper the song.
The song title can be edited with F11, and the description with F12.
5.- Using the player
The player is hardware-independent: it modifies the Z80 registers AF,
BC, DE, HL and IX, but it's otherwise interruption and stack safe, as
it doesn't modify AF', BC', DE' or HL', or the interrupt status.
The player expects the user to provide some information:
* "chipnsfx" is the location of the player itself. It's required if
the code needs to relocate itself before the player starts running.
When no relocation is needed, the user only has to put the label
"chipnsfx" right before the player code.
* "writepsg" is a function that begins with PUSH BC, writes the value
of register A onto the sound chip register defined by C, then ends
with POP BC and RET. For example, a Spectrum 128 "writepsg" function
could be like this:
* "chipnsfx_bss" points to a buffer; its required length is the
constant CHIPNSFX_TOTAL, whose value depends on the compile time flag.
* "CHIPNSFX_FLAG" is the compile time flag, a number whose bits set
the options of the player itself:
+1 : notes from Spectrum 128 and MSX1 rather than Amstrad CPC.
+2 : dual mode: each channel is divided in two (music and SFX)
and if the SFX half is active the music half stays active but
quiet, thus allowing for sound effects to temporarily override
the background music. The downside is that the player is doing
the work of six channels rather than three, thus requiring
twice as much buffer memory and CPU time.
+4 : extended mode: enables portamentos and tremolos, at the
cost of making the player longer and heavier.
+8 : no noise: disables noise support and makes the player
shorter and lighter.
+64 : linear amplitude: simulates linear amplitudes instead of
using the default exponential amplitudes from the sound chips.
+128 : precalculated octaves: the player becomes faster as
notes are no longer calculated on the fly, but grows heavier.
The player provides four functions:
* "chip_stop" resets the sound chip and all the playback parameters.
The user must use it at least once before playing anything at all, and
whenever he may need to stop the playback. Registers AF, BC, DE and HL
are modified by this function.
* "chip_song" sets all playback channels to point at the beginning of
a song. HL points at the song header, whose format is as follows:
The macro CHIP_HDR can be used instead:
If the player was compiled with the dual mode on, the Carry flag sets
whether the new song is background music (NC) or a sound effect (C).
AF, BC, DE and HL are modified.
* "chip_chan" sets a channel to point at the beginning of a track. DE
points at the track offset and A stands for the channel, ranging from
0 (channel A SFX) to 5 (channel C music) if dual mode is on, or from
0 (channel A) to 2 (channel C) if it's off. Registers AF, BC and HL
* "chip_play" plays one tick of the current playback. It updates the
playback channels and the sound hardware accordingly. A 100 Hz song
requires this function to be called 100 times every second, a 50 Hz
song requires it to be called 50 times, and so on. Registers AF, BC,
DE, HL and IX are modified.
The playback parameters can be examined by the user on runtime. For
example, the user may need to know whether channels A and B are busy:
; channel A is not busy
; neither channel A or B are busy
CHIPNSFX.DSK is a jukebox, a very simple demo of the player at work.
The time spent by the player is shown as as a white stripe on a black
border. Press SPACE to stop the current song and play the next one.
The source code of the jukebox is the file CHIPNSFX.S80.
A.- Version history
2017-05-13: first public release.
2017-05-23: second public release. New command line options -F (48000
Hz) and -L (linear amplitude). A blue bar makes the active items stand
out. Minor changes in the documentation file.
2017-06-02: third public release. New command line options -P (cursor
follows playback), -k1, -k2 and -k STR (set QWERTZ, AZERTY or custom
keyboard map), following a suggestion from Beb.
2017-06-07: fourth public release. New command Control-D tells whether
the current instrument is unused or the current pattern is a duplicate
(Shift: erase unused instrument, turn current pattern into a link to
the pattern it is a duplicate of). Minor bugfixes: inconsistencies in
-P mode and in channel toggling, better compression when generating
INCLUDE files, etc. Minor changes in several songs. New DESPERA1.CHP.
2017-06-16: fifth public release. Fixed a file dialog bug reported by
Garvalf (who also wrote CHIPNSFX's first new song from scratch), as
well as minor internal consistency bugs. Pattern panel allows using
Control-D. New ATOMINO3.CHP and DESPERA2.CHP.
2017-07-07: sixth public release. New command line options -y and -Y
(generate YM3 file, either full song or song loop), commands Control-W
(apply transposition to current pattern), Control-D (detect duplicates
and optionally erase them), Control-E (check for duplicates and
optionally create them). Minor changes in CHIPNSFX.I80 extended mode
vibratos, in the file dialog and the INCLUDE file compression. New
DEFLEKTR.CHP, GRANGEHL.CHP, PHANTIS1.CHP, PHANTIS2.CHP, THINGBBK.CHP
2017-07-19: seventh public release. New extended tremolos (60-9F) lead
to several changes in the amplitude effect byte: old 60-6F become 5F,
old 80 becomes 9E, old 81-8F become 61-6F, old 90-9F become A0; 70-7F
stay the same. New command line options -b1, -b2 and -b3. Minor tweaks
in CHIPNSFX.I80. New CATABALL.CHP, FREDDY_H.CHP, HYDROFOL.CHP and
2017-07-24: eighth public release. Fixed a serious bug in the noise
generator: playback and WAVE output randomly skipped pure noise notes.
New ATEAM.CHP, BURNINR1.CHP, BURNINR4.CHP, SOLOMON2.CHP, UNDERWTR.CHP,
WESTBNK1.CHP, WESTBNK2.CHP and WINGSOD4.CHP: 32 sample songs.
2017-07-31: ninth public release. New special case for arpeggios: the
nibble F stands for -12 and changes the loop behavior. Sound playback
is now wavelength-based rather than frequency-based, and thus closer
to the hardware. Minor bugfixes in the keyboard map handling. Added
CHUBBYGR.CHP, CHUBBYGS.CHP, MEGAPHNX.CHP and MEGAPHNY.CHP.