home *** CD-ROM | disk | FTP | other *** search
- ---------------------------------------------------------------------------
-
- GRASP implementation of Play/R interface
-
- ---------------------------------------------------------------------------
- Copyright 1992, Kevin Weiner, All rights reserved
-
- Proprietary material - not for distribution
- ---------------------------------------------------------------------------
-
- Many of the available Play/D functions have been implemented in GRASP
- code in the accompanying files MIDI.TXT (for GRASP 4) or MIDI_MM (for
- Multimedia GRASP). Those functions may be expanded fairly easily to
- implement any features not included (for example, MIDI input). To add
- MIDI file capability to your GRASP program, simply add the line
- "merge midi" (or "merge midi_mm" for MMGRASP). Then call the functions
- described below to perform assorted MIDI file operations. Be sure you
- are using the version of the file that matches your copy of GRASP; the
- two versions of GRASP have some minor source incompatibilities.
-
- The GRASP interface follows the model described in API.DOC. GRASP
- provides an INT command, which allows the int 2F multiplex call to be
- made with the appropriate machine register values passed as arguments.
- Unless you are modifying the MIDI.TXT or MIDI_MM.TXT code, however, you
- need not be aware of how things are actually working; just call the
- high-level functions. You should, however, review API.DOC because it
- contains other important information on the driver, plus distribution
- licensing terms.
-
- Initialization
- --------------
-
- The function mfinit must always be the first MIDI routine called to
- initialize the driver. When mfinit returns, @0 will be 1 if it was
- successful, or 0 otherwise. Failure generally means that playd.exe has
- not been run, so you should report to the user that the MIDI driver
- (playd.exe) has not been loaded.
-
- Loading a file
- --------------
-
- A MIDI song file is loaded into memory with the mfload function:
-
- mfload <file name>
-
- <filename> must be a valid MIDI file name string, or the name of a play
- list. A play list is a simple text file consisting of one MIDI file
- name per line. A play list is distinguished from a MIDI file by
- prefixing its name with the "@" character. When mfload returns, @0 will
- contain a load status value. Possible load status values are listed
- below:
-
- 0 = File loaded successfully
- 1 = File not found
- 2 = Not MIDI file format
- 3 = Unexpected end of file
- 4 = Format not supported
- 5 = Track not found
- 6 = I/O error reading file
- 7 = Not enough memory
- 8 = Unsupported time base
- 255 = Nothing loaded
-
- Playing and pausing
- -------------------
-
- After a file is loaded, start it with mfplay. A any point, it may be
- stopped with mfpause, and then resumed with mfplay. When the song is
- complete, it will be in a paused state and mfplay will restart it from
- the beginning.
-
- Song positioning
- ----------------
-
- To rewind a song to the beginning at any time during play, use mfrewind.
- This skips to time zero in the file and pauses. Note that if the song
- is already at the beginning, mfrewind will function as a reverse skip to
- the previous song if a play list is loaded.
-
- To skip to a specific point in a song, use mfsetpos:
-
- mfsetpos <pos>
-
- If <pos> is a positive number, it is taken to be the song location in
- milliseconds to which the player will be positioned. Note that it may
- take up to several seconds to seek to the requested position, depending
- upon how far it is from the current position. Skipping to an earlier
- position requires seeking from the beginning.
-
- If <pos> is a negative number, its absolute value specifies the number
- of milliseconds to fast forward from the current position.
-
- Positioning in a play list
- --------------------------
-
- Use mfskip to select a specific song in a play list:
-
- mfskip <num>
-
- <num> is the number of a song in the play list (counting from 1). If
- <num> is beyond the end of the play list, the player will skip to song 1.
- If play is in progress, the new song will begin playing immediately after
- loading. If play has been paused, the new song will wait until the next
- mfplay to begin. As noted above, mfrewind will skip to the previous
- song in the list if already at the beginning of a song. As play
- progresses and the last song completes, the player will cycle back to
- the first song and begin again.
-
- Player status
- -------------
-
- Use mfstatus to obtain the status of the current song and play list.
- Mfstatus returns @0 with one of the following values:
-
- 0 = Paused
- 1 = Playing
- 2 = Done
-
- In addition, three global variables are set:
-
- @etime = Elapsed time of current song in milliseconds
- @songcount = Total number of songs in play list (0 if no list)
- @cursong = Number of the current song in the play list
-
- Song volume
- -----------
-
- The mfvolume adjusts the overall song volume by a specified amount:
-
- mfvolume <vol>
-
- <vol> is a number from -127 to +127, relative to the song's initial
- volume. A value of 0 restores the initial volume. The volume control
- is in terms of MIDI velocity units. Not all devices or instrument
- voices respond to velocity information, so this function may not always
- be effective. Also, if MIDI velocity codes in the file are at maximum,
- only negative adjustments can be used.
-
- Sending MIDI messages
- ---------------------
-
- Individual MIDI messages consisting of one, two, or three bytes may be
- sent with the midisend function:
-
- midisend <status> <data1> <data2>
-
- All MIDI messages contain at least a status byte. Some contain one or
- two additional data bytes. One or both of the arguments <data1> and
- <data2> may be omitted if not needed for a particular message. There
- are many books available which describe MIDI messages in detail,
- however, some simple examples are given here.
-
- MIDI channel messages (such as "note-on") have a two-part status byte.
- The 4 high-order bits determine the type of message, and the 4 low-order
- bits indicate the channel. MIDI channels 1-16 are represented by the
- numbers 0 - 15.
-
- For your convenience, the mfinit function defines three of the most
- common MIDI messages as global variables:
-
- @note_on Note-on message (value 0x90)
- @ctrl_ch Control change message (value 0xb0)
- @prog_ch Program change message (value 0xc0)
-
- To construct a status byte, add one of these message type variables to a
- channel number from 0 to 15 (one less than the nominal channel).
-
- A note-on message consists of a status byte, a note number from 0 to
- 127, and a velocity value (also 0 - 127). To play a middle C note (note
- number 64) on channel 3 (actually 2), with medium-high velocity (96),
- use the following:
-
- midisend @note_on+2 64 96
-
- The "+2" selected channel 3 when constructing the status byte. A note-on
- message with zero velocity turns off the sounding note. To turn off the
- note played above, use:
-
- midisend @note_on+2 64 0
-
- There are many control change messages available, requiring a table to
- use them, but they are also 3-byte messages like note-on. The program
- change message is much simpler, requiring a single data byte to select a
- program (meaning a patch, or instrument type) on a particular channel.
- To change to program 10 (actually numbered 9) on channel 1 (actually
- numbered 0), use:
-
- midisend @prog_ch+0 9
-
- Absolute time
- -------------
-
- The mstimer function returns the value of an absolute millisecond timer
- in @0 for any additional timing operations you may find necessary. This
- timer runs independently of the player, and represents the number of
- milliseconds since playd.exe was loaded.
-
- =========
-