inty-midi
is a program which will convert a MIDI file into a
format playable by IntyBASIC on an Intellivision game
console. Specifically, inty-midi
generates an IntyBASIC file
containing MUSIC
lines, which can then be included in an IntyBASIC
program with the include
directive. (Or, when given the -m
command-line option, inty-midi
generates a stand-alone IntyBASIC
file which will play the music when run.)
IntyBASIC and the Intellivision support a maximum of three voices, or
six when the optional ECS component is used. If the MIDI file
contains more than three voices (simultaneous notes), then inty-midi
automatically uses the ECS. If more than six voices are used, then
inty-midi
will drop some notes to stay within the voice limit.
inty-midi
will also drop notes if they are outside the range
supported by IntyBASIC (C2 to C7).
IntyBASIC has some support for drums, and inty-midi
will convert any
note on Channel 10 into an M1
drum note. (This has only been
minimally tested.) Notes on any other MIDI channel are played on one
of the four IntyBASIC instruments: piano, clarinet, flute, or bass.
(See "Program Change", below.)
inty-midi
reads the time signature from the MIDI file, and
automatically places a blank line in the output between each measure,
to make the output somewhat more human-readable. If the MIDI file
does not begin with a complete measure, you'll need to help it out
with the -p
option (see below). inty-midi
does not currently
support changes in time signature, or changes in tempo, in the middle
of a file.
For some example MIDI files and the resulting IntyBASIC files produced
by inty-midi
, see the examples directory.
Usage: inty-midi [-i inst] [-m] [-p n] [-q n] input.mid output.bas
inty-midi -v
-i inst use specified instrument (W, X, Y, or Z)
-m include a main program in output
-p n number of quarter notes in first measure (can be fractional)
-q n quantize to 1/n notes (e. g. 16 for 16th notes)
-v print version number and exit
The -i
option specifies an instrument. If specified, this
instrument will override all of the Program Change messages (see
below). Instruments are:
- W - Piano
- X - Clarinet
- Y - Flute
- Z - Bass
The -m
option outputs a complete, stand-alone IntyBASIC program,
rather than an IntyBASIC fragment meant to be included from another
program. This can be useful for easily previewing the results of a
conversion.
If the MIDI file does not start with a complete measure, -p
can be
used to specify the number of quarter notes in the first measure.
This number can be fractional, such as 0.5
for a single eighth-note
pickup. Note that this only affects where blank lines are printed in
the output; it does not change how the music sounds.
The -q
option can be used to quantize the MIDI file before
converting it. For example, -q 16
would quantize to sixteenth
notes, while -q 32
would quantize to thirty-second notes. See below
for more information about quantization.
Input to inty-midi
must be quantized. If your MIDI file is not
already quantized, you can ask inty-midi
to do it for you with the
-q
option (see above).
The following could all be signs that you need to quantize the input:
-
inty-midi
fails with the errorNeeds quantization
-
inty-midi
takes a long time to run (normally it should be almost instantaneous) -
the generated
.bas
file is huge -
as1600
fails with the errorAddress overflow
-
the resulting ROM crashes when run
Generally you want to quantize as much as possible (i. e. a -q
parameter as small as possible) without losing notes or making the
rhythm sound wrong.
Unfortunately, the IntyBASIC music player does not handle triplets well. In order to play triplets accurately, while also playing sixteenth notes accurately, you would need to quantize to forty-eighth notes, which generally is not quantized enough for good results.
IntyBASIC supports four instruments: Piano (W), Clarinet (X), Flute
(Y), and Bass (Z). inty-midi
does its best to map the
General MIDI Program Change messages to the four instruments:
- Bass (33-40) maps to Bass (Z)
- Reed (65-72) maps to Clarinet (X)
- Pipe (73-80) maps to Flute (Y)
- Everything else maps to Piano (W)
This feature has only been minimally tested.
Binaries for Mac OS X, Linux, and Windows are available under the releases tab on GitHub.
inty-midi
is written in Haskell. If you're familiar with
Haskell, you already know how to build inty-midi
. inty-midi
can
be built with either Cabal or Stack.
If you're not familiar with Haskell, here's the quick-start:
- Clone this repo (or download a source distribution from releases)
- Install Stack
- In the top directory of this repo, run
stack --install-ghc install
- Wait a really long time (it only takes this long the first time)
This will copy inty-midi
to the directory ~/.local/bin
. (Or on
Windows, %APPDATA%/local/bin
.) You can either put that directory on
your PATH
, or copy the binary to wherever you want to have it.
If you get a weird-sounding error, such as AesonException
, it
probably means your version of stack
is not new enough.
If your file requires more than three voices, you will need the ECS to run your program. If you are running on real Intellivision hardware, you will need the physical ECS hardware component.
If you are using jzIntv, you will need to have ecs.bin
in your
ROM search path in order to enable emulation of the ECS. To obtain
ecs.bin
, do the following:
- Go to the jzIntv home page, and download the latest jzIntv source archive, which is currently jzintv-20200712-src.zip.
- Extract the zipfile you downloaded, and find the file
jzintv-20200712-src/src/emscripten/fake_ecs.bin
within it. - Rename
fake_ecs.bin
toecs.bin
and copy it into a directory which is on your ROM search path.
This is not the first program to convert MIDI files to IntyBASIC programs. AtariAge user "decle" previously wrote the program MusoCheat, which does much the same thing.
The two programs take different approaches, so you may find one or the
other more to your liking. MusoCheat gives the user a lot more
options, although this may also require the user to do more work.
inty-midi
has very few options, and tries to "do the right thing"
automatically.