AdLib Programmer's Manual

From Sierra Wiki
Jump to navigationJump to search


AdLib Programmer's Manual
Copyright 1990



Introduction

This diskette is divided into four directories: BASIC, C, LIB and ROL2MIDI. Each directory contains its own README.TXT file which contains further information regarding that particular directory.

BASIC contains a program written in QuickBASIC to read and playback a MIDI 1.0 format file.

C contains two sub-directories: ROLPLAY and MIDI10. ROLPLAY contains source code to read and playback a .ROL music file (as created by Visual Composer). MIDI10 contains source code to read and playback a MIDI 1.0 format file.

LIB contains object code libraries which are used by the C programs.

ROL2MIDI contains a utility program to convert a .ROL file to MIDI 1.0 format, a description of the MIDI 1.0 File format and a sample MIDI 1.0 format file.


Ad Lib, June 1990
Version 1.51 Update
-------------------

Changes have been made to ROL2MIDI.EXE. See the README file in the directory ROL2MIDI. The midi playback program in the directory C\MIDI10 has been changed. See the README file in that directory for details.


Ad Lib, August 1990
Version 1.52 Update
-------------------

For C programmers using the MIDI 1.0 utility, the file MIDIPLAY.C has been modified slightly to solve a noise problem which occurred when a file with a lot of data at the beginning was played.

For QuickBASIC users, the object files for the quick library have been added so that you can remake the library if you are using a version of QuickBASIC other than 4.5. See the README file in the \BASIC directory for more details.


Directory BASIC

This directory contains a QuickBASIC program which reads and plays back a MIDI 1.0 format file. This program is divided into two modules:

MIDIPLAY.BAS and AdLib.BAS.

MIDIPLAY is the main module. It contains the user interface and reads the MIDI file. AdLib contains the code which writes to the card. You should load the quick library AdLib.QLB when starting QuickBASIC:

qb /lAdLib.QLB

This will allow you to run the program from within the QuickBASIC environment. If you wish to compile from the DOS command line, link with \BASIC\AdLib.LIB.


V1.52 UPDATE
------------

A charming feature of QuickBASIC is that the .QLB library is good only for the version of QuickBASIC with which it was linked: version 4.5 in this case. That is, if the library was made with the linker supplied with V4.5, then the library is only good for V4.5: it is neither upward nor downward compatible. The three object files which make up the library have been added to the diskette so that you can remake the quick library. The object files are in the directory \BASIC\OBJECT. You will also find the file MAKEQLB.BAT which shows how to link the files under V4.5. However, you should check your manual in case the procedure varies in your version.


Directory C

This directory contains 2 sub-directories: MIDI10, which contains a program for playing back MIDI 1.0 format files, and ROLPLAY, which contains a program to play .ROL files.

The program in ROLPLAY uses the memory resident sound driver SOUND.COM to play back the file. The main module is ROLPLAY.C. The README.TXT file in this directory contains further information on compiling and linking.

The program in MIDI10 plays back a MIDI 1.0 format file. It contains all the code necessary to do timing and accesses the card directly (it does not use the memory resident sound driver.) The main module is MIDIMAIN.C. The README.TXT file in this directory contains further information on compiling and linking.


Directory MIDI10

This directory contains a program to playback a MIDI 1.0 format file. The executable file is named MIDIPLAY.EXE. To make your own copy, the following files must be compiled: MIDIMAIN.C, MIDIPLAY.C and AdLib.C. These three files must then be linked with the appropriate library in the directory \LIB.

\LIB contains three libraries named xAdLib.LIB, where x is S, M or L (small, medium or large). The libraries consist of the three assembler (.ASM) files which you will find in this directory.

MIDITC.PRJ is the project file for Turbo C. MIDIQC.MAK is the make file for Quick C. If you are using a memory model other than large, you will have to modify these files to indicate a different memory model. There is a compilation flag for Turbo C in the file CFLAGS.H. Make sure that this flag is defined if you are using Turbo C and not defined otherwise.

IMPORTANT: You will probably have to tell the linker to be case insensitive (ignore upper/lower case differences). For both QuickC and Turbo C, be sure to check that this link flag is correctly set.

There is a MIDI 1.0 file, BRAHMS1.MDI, in the directory \ROL2MIDI which you may use to test your program. In the same directory is a program for converting from .ROL to MIDI 1.0 format.


Ad Lib, June 1990
Version 1.51 Update
-------------------

The program has been changed to play back several files. This involves initializing some global variables, which is done in MIDIPLAY.C. MIDIMAIN.C has been changed to read in multiple file names from the DOS command line input.


Ad Lib, September 1990
Version 1.52 Update
-------------------

MIDIPLAY.C has been changed slightly. The routines affected are Start_Melo() and TimeOut(). This was done to solve a noise problem which occurred when a file with a lot of data at the beginning was played.

 


Directory ROLPLAY

This directory contains a program to playback a .ROL file using the Ad Lib sound driver SOUND.COM. The following files must be compiled and linked together: ROLPLAY.C, ROLREAD.C, INSBANK.C and CSOUNDC.C.

ROLTC.PRJ is the project file for Turbo C. ROLQC.MAK is the make file for Quick C. If you are using a memory model other than large, you will have to modify these files to indicate a different memory model. There is a compilation flag for Turbo C in the file CFLAGS.H. Make sure that this flag is defined if you are using Turbo C and not defined otherwise.

Before loading and running this program, you must have loaded the sound driver SOUND.COM. If it is not loaded, you will receive and error message. Load the sound driver before loading your editor.

 


Directory LIB

\LIB contains three libraries named xAdLib.LIB, where x is S, M or L (small, medium or large). The libraries were built from the three assembler (.ASM) files OUTCHIP.ASM, SETFREQ.ASM and TIMER.ASM. You will find these three files in the directory \C\MIDI10.


Directory ROL2MIDI

This directory contains a program for converting from .ROL to MIDI 1.0 file format. It is used as follows:

rol2midi <in_file>

where <in_file> is the complete name of the input file. There are two optional parameters which can be given: /Oout_file out_file is the name of the output file. The default is the input file name with the extension .MDI added. /Bbnk_file bnk_file is the name of an instrument bank file. The default is STANDARD.BNK.

A pre-converted file, BRAHMS1.MDI, is included in this directory. You may find it useful for testing if you are developing a program to read MIDI files.

The file MIDI10.TXT contains an description of the MIDI 1.0 File format.


Ad Lib, June 1990
Version 1.51 Update
--------------------

The previous version of ROL2MIDI had note-off events sent with note 0 and volume 0. This may bother some sequences which look for pitches in the note-off event (channels may be polyphonic). The new version of ROL2MIDI places the correct value for pitch and volume in the note-off event.


Standard MIDI Files 1.0

The following is excerpted from the official MIDI File 1.0 documentation (July 1988) published by The International MIDI Association. If you wish to have the complete document, contact:

The International MIDI Association
5316 W. 57th St.
Los Angeles, CA 90056
213-649-6434


1. Sequences, Tracks, Chunks: File Block Structure


Conventions

In this document, bit 0 means the least significant bit of a byte, and bit 7 is the most significant.

Some numbers in MIDI Files are represented in a form called a variable-length quantity. These numbers are represented 7 bits per byte, most significant bits first. All bytes except the last have bit 7 set, and the last byte has bit 7 clear. If the number is between 0 and 127, it is thus represented exactly as one byte.

Here are some examples of numbers represented as variable-length quantities:

  Number (hex)     Representation (hex)  
00000000 00
00000040 40
0000007F 7F
00000080 81 00
00002000 C0 00
00003FFF FF 7F
00004000 81 80 00
00100000 C0 80 00
001FFFFF FF FF 7F
00200000 81 80 80 00
08000000 C0 80 80 00
0FFFFFFF FF FF FF 7F

The largest number which is allowed is 0FFFFFFF so that the variable-length representation must fit in 32 bits in a routine to write variable-length numbers.


Files

To any file system, a MIDI File is simply a series of 8-bit bytes.


Chunks

MIDI Files are made up of chunks. Each chunk has a 4-character type and a 32-bit length, which is the number of bytes in the chunk. This structure allows future chunk types to be designed which may easily be ignored if encountered by a program written before the chunk type is introduced. Your programs should expect alien chunks and treat them as if they weren't there.

Each chunk begins with a 4-character ASCII type. It is followed by a 32-bit length, most significant byte first (a length of 6 is stored as 00 00 00 06). This length refers to the number of bytes of data which follow: the eight bytes of type and length are not included. Therefore, a chunk with a length of 6 would actually occupy 14 bytes in the disk file.

MIDI Files contain two types of chunks: header chunks and track chunks. A header chunk provides a minimal amount of information pertaining to the entire MIDI file. A track chunk contains a sequential stream of MIDI data which may contain information for up to 16 MIDI channels. The concepts of multiple tracks, multiple MIDI outputs, patterns, sequences, and songs may all be implemented using several track chunks.

A MIDI file always starts with a header chunk, and is followed by one or more track chunks.

MThd <length of header data>
<header data>
MTrk <length of track data>
<track data>
MTrk <length of track data>
<track data>
...


2. Chunk Descriptions


Header Chunks

The header chunk at the beginning of the file specifies some basic information about the data in the file. Here's the syntax of the complete chunk:

<Header Chunk> = <chunk type><length><format><ntrks><division>

As described above, <chunk type> is the four ASCII characters 'MThd'; <length> is a 32-bit representation of the number 6 (high byte first).

The data section contains three 16-bit words, stored most-significant byte first.

The first word, format, specifies the overall organization of the file. Only three values of format are specified:

0 the file contains a single multi-channel track
1 the file contains one or more simultaneous tracks
2 the file contains one or more sequentially independent single-track patterns

More information about these formats is provided below.

The next word, ntrks, is the number of track chunks in the file. It will always be 1 for a format 0 file.

The third word, division, specifies the meaning of the delta-times. It has two formats, one for metrical time, and one for time-code-based time. If bit 15 of division is zero, the bits 14 through 0 represent the number of delta-time "ticks" which make up a quarter-note. For instance, if division is 96, then a time interval of an eighth-note between two events in the file would be 48. If bit 15 of division is one, then the 14 through 0 describe a SMPTE time-code-based time.

Formats 0, 1, and 2

A Format 0 file has a header chunk followed by one track chunk. It is the most interchangeable representation of data.

A Format 1 or 2 file has a header chunk followed by one or more track chunks. Programs which support several simultaneous tracks should be able to save and read data in format 1, a vertically one-dimensional form, that is, as a collection of tracks. Programs which support several independent patterns should be able to save and read data in format 2, a horizontally one-dimensional form. Providing these minimum capabilities will ensure maximum interchangeability.

All MIDI Files should specify tempo and time signature. If they don't, the time signature is assumed to be 4/4, and the tempo 120 beats per minute. In format 0, these meta-events should occur at least at the beginning of the single multi-channel track. In format 1, these meta-events should be contained in the first track. In format 2, each of the temporally independent patterns should contain at least initial time signature and tempo information.

We may decide to define other format IDs to support other structures. A program encountering an unknown format ID may still read other MTrk chunks it finds from the file, as format 1 or 2, if its user can make sense of them and arrange them into some other structure if appropriate. Also, more parameters may be added to the MThd chunk in the future: it is important to read and honor the length, even if it is longer than 6.


Track Chunks

The track chunks (type MTrk) are where actual song data is stored. Each track chunk is simply a stream of MIDI events (and non-MIDI events), preceded by delta-time values. The format for Track Chunks (described below) is exactly the same for all three formats (0, 1 and 2: see "Header Chunk" above) of MIDI Files.

Here is the syntax of an MTrk chunk (the + means "one or more": at least one MTrk event must be present):

<Track Chunk> = <chunk type> <length> <MTrk event>+

The syntax of an MTrk event is very simple:

<MTrk event> = <delta-time> <event>

<delta-time> is stored as a variable-length quantity. It represents the amount of time before the following event. If the first event in a track occurs at the very beginning of a track, or if two events occur simultaneously, a delta-time of zero is used. Delta-times are always present. Delta-time is in some fraction of a beat.

<event> = <MIDI event> | <SysEx event> | <meta-event>

<MIDI event> is any MIDI channel message. Running status is used: status bytes of MIDI channel messages may be omitted if the preceding event is a MIDI channel message with the same status. The first event in each MTrk chunk must specify status. Delta-time is not considered an event itself: it is an integral part of the syntax for an MTrk event. Notice that running status occurs across delta-times.

<SysEx event> is used to specify a MIDI system exclusive message, either as one unit or in packets, or as an "escape" to specify any arbitrary bytes to be transmitted. A normal complete system exclusive message is stored in a MIDI File in this way:

F0 <length> <bytes to be transmitted after F0, F7>

The length is stored as variable-length quantity. It specifies the number of bytes which follow it, not including the F0 or the length itself. The last byte in the message should be F7.

Another form of SysEx event is provided which does not imply that an F0 should be transmitted. This uses the F7 code:

F7 <length> <all bytes to be transmitted>

<meta-event> specifies non-MIDI information useful to this format or to sequences, with this syntax:

FF <type> <length> <bytes>

All meta-events begin with FF, then have an event type byte (which is always less than 128), and then have the length of the data stored as a variable-length quantity, and then the data itself. If there is no data, the length is 0. As with chunks, future meta-events may be designed which may not be known to existing programs, so programs must properly ignore meta-events which they do not recognize, and indeed, should expect to see them. Programs must never ignore the length of a meta-event which they do recognize, and they shouldn't be surprised if it's bigger than they expected. If so, they must ignore everything past what they know about. However, they must not add anything of their own to the end of a meta-event.

SysEx events and meta-events cancel any running status which was in effect. Running status does not apply to and may not be used for these messages.


3. Meta Events

FF 51 03 tttttt Set Tempo, microseconds per MIDI quarter-note

This event indicates a tempo change. tttttt is a 24-bit value, stored most-significant-byte first. Another way of putting "microseconds per quarter-note" is "24ths of a microsecond per MIDI clock".

FF 58 04 nn dd cc bb Time Signature

The time signature is expressed as four numbers. nn and DD represent the numerator and denominator of the time signature as it would be notated. The denominator is a negative power of two: 2 represents a quarter-note, 3 represents an eighth-note, etc. The cc parameter expresses the number of MIDI clocks in a metronome click. The bb parameter expresses the number of notated 32nd-notes in a MIDI quarter-note (24 MIDI Clocks). This was added because there are already multiple programs which allow the user to specify that what MIDI thinks of as a quarter-note (24 clocks) is to be notated as, or related to in terms of, something else.

Therefore, the complete event for 6/8 time, where the metronome clicks every three eighth-notes, but there are 24 clocks per quarter-note, 72 to the bar, would be (in hex):

FF 58 04 06 03 24 08

That is, 6/8 time (8 is 2 to the 3rd power, so this is 06 03), 36 MIDI clocks per dotted-quarter (24 hex), and eight notated 32nd-notes per MIDI quarter note.

FF 7f len data Sequencer-Specific Meta-Event

Special requirements for particular sequences may use this event type: the first byte or bytes of data is a manufactured ID (these are one byte, or, if the first byte is 00, three bytes). The length of the data includes the ID bytes. The data is defined by the ID owner. The Ad Lib ID is 00 00 3F.

 


References


See Also

  •