Appendix A. Sound File Formats

The following information describes the data formats required of the Fig-Forth internal sound card interface, which allows the generation of a basic audio output within user applications. While Fig-Forth v2 programs are not expected to contain heavy concentrations of either sound or music, the internal drivers recognize two different structures;

WAVE FILE FORMAT

Digital audio tracks are expected to conform to the RIFF standard as outlined for *.WAV files, comprised of a header record and a block of samples. For the purposes of the Fig-Forth player only a portion of this header information is recognized, though the entire header is read when a file is opened. The follow table describes the header;

Offset Expected Contents Size Comment

0

"RIFF"

4

Header prefix

+4

rsize

4

File Size minus header prefix & Length

+8

"WAVE"

4

Type of encoding

+12

"fmt "

4

Format header

+16

16

4

Header size

+20

1

2

Format type

+22

1

2

number of channels

+24

?

4

Samples per second

+28

?

4

Bytes per second

+32

1

2

Number of data blocks

+34

8

2

Bits per sample

+36

"data"

4

Data Block Header

+40

?

4

Size of data

+44

?

?

Data samples

Developers should note that only the Bytes Per Second value is recognized by Fig-Forth's internal player coding, and that data samples are expected at the point of offset 44 bytes and beyond. All other values, including signature headers, are ignored. Thus all such files should be comprised of single channel, 8 bit samples in a single data block, and the recommended play speed is 12k per second or less.

MIDI FILE FORMAT

For FM music generation Fig-Forth v2 utilizes a highly specialized and simplified interface to the synthesizer registers, allowing for the creation of 9 or 18 voice electronic music. Such definition of these voices is based upon 11 registers of the synthesizer operation plus the two registers required to generate a note. The number of independent voices is a factor of the system hardware, (E.g., Monaural or Stereo sound card,) and the mappings of the FM synthesizer control chips. The following tables describes the file format;

Offset Contents Size Comments

0

header

8

signature, either "4MDxx.xx" or "JIMxx.xx" (ignored by the player)

+8

timing word

2

when to execute the command that follows

+10

command

1-2

command type with optional prefix

+11/+12

data

n

command data if any

X

timing word

2

when to execute the command that follows

X+2

command

1-2

command type with optional prefix

X+C

data

n

command data if any

Command Structure
Binary Bits Contents
??????DDDD Optional Command Prefix (see below)
CCCCDDDD C=channel number, D=command. Valid channels are 0-8 or 9 and up which applies the command to all channels. (see exceptions.)
0-n bytes command data if required.

Command List
0 Timing Word overflow synchronization.
1 Note on. Note number follows command (see below)
2 Note off.
3 Set Voice, 11 byte data follows command. (see below)*
4 Set All Voices, 99 bytes follow command. (Set Voice Structure times 9)*
5 Set Loop Count.
6 Decrement Loop Count and Jump to address if count not zero, adjusting timer.
7 Decrement Loop Count and Jump to address if count is zero, adjusting timer.
15 Controller change; channel value ignored, send raw data to FM register.

* Command 3 for channels 9 and up set all voices to same settings after command.

* Command 4 sets channels 0-8 to sequential settings following command.

(Expected to be encountered only at the top of the file.)

Note that additional commands are expected in new versions of the compiler.

Command Prefixes:

At present there are two prefixes that may be applied to any command, in the bit format listed above. Channel Selection Data for these prefixes is ignored but reserved. The Prefixes are;

8 This command applies to the Left Sound Chip in a stereo card. (default)
9 This command applies to the Right Sound Chip.

Note that once applied these command prefixes remain in effect until released by their opposite function.

Note Values (hex)
00 C 0 0C C 1 18 C 2 24 C 3 30 C 4 3C C 5 48 C 6
01 C#0 0D C#1 19 C#2 25 C#3 31 C#4 3D C#5 49 C#6
02 D 0 0E D 1 1A D 2 26 D 3 32 D 4 3E D 5 4A D 6
03 D#0 0F D#1 1B D#2 27 D#3 33 D#4 3F D#5 4B D#6
04 E 0 10 E 1 1C E 2 28 E 3 34 E 4 40 E 5 4C E 6
05 F 0 11 F 1 1D F 2 29 F 3 35 F 4 41 F 5 4D F 6
06 F#0 12 F#1 1E F#2 2A F#3 36 F#4 42 F#5 -- --
07 G 0 13 G 1 1F G 2 2B G 3 37 G 4 43 G 5 -- --
08 G#0 14 G#1 20 G#2 2C G#3 38 G#4 44 G#5 -- --
09 A 0 15 A 1 21 A 2 2D A 3 39 A 4 45 A 5 -- --
0A A#0 16 A#1 22 A#2 2E A#3 3A A#4 46 A#5 -- --
0B B 0 17 B 1 23 B 2 2F B 3 3B B 4 47 B 5 -- --

Set Voice Structure: 11 bytes

Registers 20, 23, 40, 43, 60, 63, 80, 83, C0, E0, E3

0 - Modulator: b7=AM b6=VIB b5=EG b4=KSR b3-b0=multiplier

1 - Carrier: b7=AM b6=VIB b5=EG b4=KSR b3-b0=multiplier

2 - Modulator: b7-b6=KSL b5-b0=Total Level

3 - Carrier: b7-b6=KSL b5-b0=Total Level

4 - Modulator: b7-b4=Attack b3-b0=Decay

5 - Carrier: b7-b4=Attack b3-b0=Decay

6 - Modulator: b7-b4=Sustain b3-b0=Release

7 - Carrier: b7-b4=Sustain b3-b0=Release

8 - Channel: b3-b1=Feedback b0=Connect

9 - Modulator: b1-b0=Wave Select

10 - Carrier: b1-b0=Wave Select

Loop Set: 1 byte

0 - How often to loop. (1=no loop, 2=1 time, 0=255 times)

Loop Jump: 4 bytes

0 - low order address -- low byte*

1 - low order address -- high byte*

2 - high order address -- low byte*

3 - high order address -- high byte*

*Address of loop point is byte offset from the start of the music file to the point of reload for the scroll buffer. Timing is set to the first word encountered at the address specified when the loop begins.

Controller Change: 2 bytes

0 - Register Number

1 - Data

Header Information:

Though the player ignores the first 8 bytes of the file selection to be played, the following formats are recognized by the MIDI Maker program. Note that not all functions are available in all formats, nor are all commands in each format recognized correctly by the player.

"4MDxx.xx" -- File produced by the 4th MIDI Maker. xx.xx=version

"JIMxx.xx" -- Files Produced by Jim Moore's MIDI code. xx.xx=version

"MThd" -- standard MIDI header. (not play-able! For conversion only... if I ever complete that aspect of the MIDI Maker program.)

Using The MIDI Maker Utility

The MIDI Maker program is being distributed with the Fig-Forth package under a variety of names for the file, which identify the version of the program being included. The basic program is under the name MIDI.4TH, which is also available under the file name of MIDI9.4TH. These versions of the program are capable of constructing 9 channel music for the Fig-Forth internal player, without conversion of standard MIDI files as defined in Windows. This same version of the program cannot use, recognize or process the command prefixes listed above, nor the value of command 15. More advanced versions of this program will be released under the file names of MIDI18.4TH and MIDI18E.4TH when I get a chance to complete them. These new versions will use these extra features added to the player as of Fig-Forth v2.21 beyond, and the conversion overlay in the E model. All versions of this program operate in essentially the same way.

Loading the program

The MIDI Maker utility is designed to be loaded from block 20 in the Forth file space, however this is merely convention and useful in making patches or changes to the program as listed under customization. The source text of the file will create a new vocabulary of MIDIMAKER, followed by the single global entry point of MIDI. Note that the program requires a mouse and compiler compatible high resolution video card to operate properly. As a general rule, left clicking on a numeric window will increment the value contained, while right clicking on it will decrement the entry.

Operation

The MIDI Maker interface is very straight forward, displaying a number of icons, the events listed, and some pertinent information about the file. The program is started by saying the word MIDI and pressing Enter, which changes the screen to an HGR mode and displays the tracker screen. This screen is comprised of a musical staff on the upper half of the screen area, Top, Rewind, Position Slider, Forward and Bottom buttons, then a blue field with file characteristics to the left of the yellow icons on the right. (See snapshot.)

To match the snapshot precisely click on the Disk icon and enter the name of TEST.JMF, where the Midi Maker will build a file name block, open and then scan the file for input. During input a pop-up dialogue will appear asking into which instrument bank the voice settings from the file are to be placed, such that these settings may be heard, modified, stored on file, or assigned to channels. There are 128 instruments allowed in the Midi Maker, and the program will automatically seek out a blank entry for the storing of file data. Note that instrument Zero cannot be used unless explicitly defined, by clicking on the number window to increase or decrease its value. Clicking Next will find the next blank instrument in the program reserved space.

Events List

The events in a music file are listed as note values, mostly because I tend to think in that way and dislike lengthy lists of numbers as I've seen in other tracking programs. Note however that some events appear only beneath the score listing; specifically those of Voice Settings, Controller Changes, Loop Begin and Loop Ends. These events will appear as ASCII characters beneath the first staff line, following the interpretation below;
V-- Voice setting, the command contains the parameters to change a channel's sound characteristic.
A-- All voice setting, the command contains the data to change all voices.
C-- Controller setting, the command changes a specific register of the channel.
>-- Loop beginning, the location after the command is remembered for the loop end command.
<-- Loop end, the command contains the decrement and jump data as required by the loop.

Music List

The notes listed in the file come in one of four different colors, and in one of six different varieties. Each note may optionally be followed by a dotted function, meaning this note is played longer than its definition with time. Note definition is based upon the length of the shortest note within the file being examined, such that a 32nd note above is precisely two time ticks. When scanning a file the Midi Maker automatically sets the length of the 32nd note to this smallest note length value, so it may adjust to the tempo of the resulting score. If you would like to change this value it is stored in the variable SOTE within the MIDIMAKER vocabulary, but I doubt you'll need this operation.

The colors of the various notes mean;

Yellow -- this Natural note is an event on the currently focused channel.

White -- this Sharp note is an event on the currently focused channel.

Red -- this Natural note is on one of the other channels.

Gray -- this Sharp note is on one of the other channels.

The channel focus is controlled in the blue screen area under the entry of Channel, which updates the screen to highlight the channel of focus. All events and changes will apply to the current channel only, except the loops and controller changes which are universal functions. The reason I didn't include sharp or flat symbols is obvious, I didn't want to mess around with the extra symbols.

The icons for the Midi Maker are fairly straight forward, comprising a note list and a variety of functions. Please remember however that each musical pip is based upon the SOTE value mentioned under Music List, with each note taking precisely twice as many time ticks as the one which comes prior. As such, the Midi Maker program will attempt to add the note specified into the event list of the file, optionally rolling down all other events for the current channel by the time specified in the note.

All notes added to the file are based upon their Natural tones at the time they are placed, which can then be made Sharp by dragging and dropping the Sharp symbol (#) on to the note. This is an increment function, meaning that attempting to Sharp an already Sharp note will make it a Natural of the next staff line, or the next note in sequence if no Sharp is possible. (Such as E# which is an F.)

The Natural icon performs the opposite function, decrementing the note value to return a Sharp to its base level. This icon may be then be used to form Flats by entering the note value on the staff, then dragging the icon on to the note to decrement it to the next lower note.

Timing Note: If a new note is dropped onto the staff at a time that a previous note is playing, the former note will be shortened by the new entry added. It is up to the programmer to determine the tick time value of where the former note will end when adding new note entries. (All new notes added near the end of a file will appear as dotted whole ones unless a rest is specified as the last event in the file.)

The loop functions should be used only after a passage or file is complete and correct, for they require the length of the file for their proper data. Once a loop is defined, the file cannot be edited before the ending definition of the loop function without first deleting the loop!

Next in line is the Rest Bar, of which only a single type of rest is defined. This is the Note Off function of the FM synthesizer, and if desired may apply to all channels by setting channel 9 in the Midi maker control screen.

Then we have the Voice Setting command, which will ask which instrument from the Midi Maker database should be dropped into the file. Once a voice is set, it will retain that setting until another voice command occurs.

Next is the Eraser icon, which removes events from within a file. As with other operations this function will ask about rolling events up in the current channel, filling in the time removed by the deleted event.

Now we come to the Time setting, which optionally shows each tick of the player while the file is running. This function also uses the Tempo value displayed to mark each bar of the file with a red vertical line, giving an approximate estimation of any downbeat.

The last icons are for Play, Disk access, Instrument Builder and Exit the program, with the following notations;

The Play function calls upon the Midi Maker manual player function, which includes an internal time base for generating sound. Note that this player is easily over loaded by the file list when events become "thick," which can be adjusted somewhat as specified under Customization. This will be heard as erratic tempo when it occurs, due to the length of interpretation loops within the Midi Maker.

The Disk icon will attempt to open a music file for processing and will display the result, catching any error caused by the process. At this time the OLD contents of the file cannot be preserved, as each change updates the whole of the file both on disk and in memory. When a new file is specified, the last file is closed out and the new one opened, providing the last file is the Top file listed by .FILES.

The Instrument icon brings up the Instrument Builder Window, which is explained in detail below.

And lastly, the Circle X icon leaves the Midi Builder program, as does an Enter key when pressed on the system console. The screen is returned to a Text mode and a list of open files is displayed by Fig-Forth, where they may be flushed and closed as normal before BYE.

The Instrument Builder

This utility within the Midi Maker allows you to hear and define the different voices contained in music files, though an explanation of how is almost worthy of another book. Quite simply, each channel has two operator Cells defined for its output, a Modulator and a Carrier. These cells contain a number of registers and option bits, so for the next few entries I'll copy almost verbatim from the Sound Blaster documentation;

Instrument Number

This numeric window selects which instrument in the database is being edited. There are 128 possible entries in the Midi Maker database. (0-127)

Channel Number

This control states which channel caused the loading of the instrument data being displayed, and which channel will be directed to receive this data with a Set All Voices command. Note that this entry is optional and can be changed, though the Midi Maker will only use the first encountered instrument setting for the Set All command in each channel.

Named Field

This optional area holds the name of the instrument defined, if any is chosen.

AM button

This button applies Amplitude Modulation or Tremolo to the Cell's output, at a frequency of 3.7 Hz.

VIB button

This button applies the Vibrato effect of 6.4 Hz to the Cell's output when enabled.

The EG button

This control is used to determine if the note played is to be quickly dampened after attack or if it is to be sustained until the key is released;

Note that with EG turned on the tones generated will require the Rest (Key Off) to reach their end, or another note which toggles Key Off. (The Release Rate would have little meaning without it.)

The KSR button

This control is used to gradually shorten the envelope to be played on higher notes, by increasing the Attack, Decay, Sustain and Release (ADSR) rate values. The amount of shortening that takes place is defined as;

               RATE = 4 * ADSR + KSRoffset

rate 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
KSR off 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3
KSR on 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

The Multiplier Setting

The Multiplier controls the Timbre of each operator cell, given the formula of;

          F(t) = A sin (Mc wc t + I sin (Mm wm t))

     Where

          A = output amplitude

          I = modulation index

          wc = carrier frequency

          wm = modulator frequency

          Mc = carrier multiplication factor

          Mm = modulator multiplication factor

Multiplication factors are;

value 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
mult. .5 1 2 3 4 5 6 7 8 9 10 10 12 12 15 15

This multiplication selects the kind of harmonics produced by the operator cell, following the results outlined below;

Factor Harmonic

0.5 One octave below

1 At base frequency

2 One octave above

3 One octave + one fifth above

4 Two octaves above

5 Two octaves + major third above

6 Two octaves + fifth above

7 Two octaves + major seventh above

8 Three octaves above

9 Three octaves + major second above

10 Three octaves + major third above

12 Three octaves + major fifth above

15 Three octaves + major seventh above.

This value can be changed in the Midi Maker program by clicking on the number displayed, using the left mouse to increment the value and right button to decrement it.

Attenuation Setting

This value adjusts the output of the higher-pitch notes downward, simulating the gradual decrease in output for some instruments. The amount of attenuation is displayed in the window, and applies by octave.

Total Level

This value determines the Cell's total output level, as defined by the formula;

          Attenuation Level = Total Level * 0.75 dB

Note that when a modulator cell's output is attenuated, the frequency spectrum generated by the associated carrier cell is changed.

Attack/Decay/Sustain/Release Rates (ADSR)

These values define the rate of Attack, the rate of Decay after attack, the Release rate and Sustain level of the note envelope. See the diagram under EG.

Wave Select

This control chooses between a Sine wave, Half Sine, Ripple Sine or Sawtooth wave form for the cell.

Feedback value

This controls determines the type of feedback sent to the Modulator, for creating more complex wave forms to modify the Carrier. Note that how this output is used is selected by the Connected button.

Connected button

This control determines the type of mixing that occurs between the Modulator and the Carrier, normally off during FM music and on during Speech Synthesis. When this control is off the Modulator output is applied to the Carrier for the purpose of amplitude modulation encoding, while if this control is on the output of the Modulator and Carrier are electronically added to create a composite signal.

Load & Save

These controls read or write an instrument file from the host system, saving all settings, channel assignments and instrument names.

Play and APlay

These controls will send the current settings to the sound card and initiate a note, one note at a time for Play and a short sequence for APlay. In both cases the length of sound play is determined by the mouse button, for a single note if on Play or a range of notes if on APlay.

Customization of MIDI.4TH or MIDI9.4TH

To adjust the utility to your preferences follow the steps below, repeating them until a satisfactory result is achieved;

1. After loading the EDIT.4TH file, open the MIDI Maker file at block number 20, then load the file.

2. Say MIDI to start the program and click on the DISK icon, (see below) then enter the file name of TEST.JMF. Press Enter.

3. Click on the Play Icon and listen for varying tempo.

4. Press Enter to exit the program or click on the X-circle, then say 27 EDIT.

5. In the word VOICEREG reduce the value of 3 in the do loop slowly, to adjust the time the program waits for the voice chip to respond. then say FORGET VOICEREG and 27 LOAD, go back to step 3. If the voices change or break up during play, increase this value.

6. Move down to screen number 69, or press Escape and say 69 EDIT. in the word @pla on the second line will be a 50 0 DO at the end, which determines play speed time ticks. Change the 50 value until the song is played to your liking. Say FORGET @PLA and 69 load then go to step 3.

7. Bring up the Instrument builder and select any loaded instrument, number 5 or 6 is fine. Click on an hold the APLAY button.

8. Exit the builder and then the Midi Program, then say 35 EDIT and look at the WAIT1 word. Adjust the 100 cycles waited for to a value you're comfortable with, which determines how long each note is played in the Instrument Builder. Say FORGET @C0-1 and 35 LOAD, go to step 7.

9. Exit the Midi Maker and Editor and say FLUSH and RESET-FILES, then BYE. The customization is complete.

Return to Contents.   Next Chapter.   Previous Chapter.