home *** CD-ROM | disk | FTP | other *** search
- -----------------------------------------------------------------------------
-
- PLAY/R AND PLAY/D APPLICATION PROGRAMMING INTERFACE
-
- -----------------------------------------------------------------------------
- Copyright 1992, Kevin Weiner, All rights reserved
-
- Proprietary material - not for distribution
- -----------------------------------------------------------------------------
-
- Contents
-
- Programming Interface Basics
- API Functions
- Timing Considerations
- Driver Command Line Options
- Langauge Libraries
- Distribution License Terms
-
- -----------------------------------------------------------------------------
-
-
- **********************************
- * Programming Interface Basics *
- **********************************
-
- This document describes the application programming interface (API) for
- the Play/R program. Except where noted, this information also applies
- to the Play/D program (Play/D does not include a pop up control window).
-
- The Play/R API is based on the use of a "software interrupt" (the
- assembly language int instruction), a facility which allows
- independently running programs to communicate with each other. Many
- high level languages provide the ability to set up machine registers and
- then issue the software interrupt. Play/R runs as a TSR - a Terminate
- and Stay Resident program. It employs IDC's TesSeRact memory resident
- support facility which, among other things, acts as an intermediary in
- communications between Play/R and other programs. TesSeRact passes
- command information from the application to Play/R via the DOS multiplex
- interrupt 2Fh.
-
- There are two types of interrupt 2Fh calls which must be made. The
- first type establishes whether or not Play/R is loaded, and obtains an
- id number for subsequent calls. The second type is used for normal
- communications with Play/R. They differ slightly in the set up of
- machine registers prior to the interrupt call.
-
- To test for the presence of Play/R, set up the machine registers as
- follows:
-
- AX TesSeRact's multiplex id - always 5453h.
- BX 0
- CX 0
- DS:SI The segment (DS) and offset (SI) of an eight-character
- string "Play/R ", which identifies the TSR to be located.
- Note - Both Play/R and Play/R share the same internal name.
-
- Then perform the interrupt 2Fh. The value in AX after the call
- determines its success. If AX is FFFFh, Play/R was located and register
- CX contains its TSR id, which must be saved for subsequent calls. If AX
- is other than FFFFh, Play/R was not found.
-
- Calls to perform actual Play/R functions are very similar, with the
- registers set up as follows:
-
- AX 5453h (TesSeRact multiplex id)
- BX 20h (TesSeRact user call function)
- CX The Play/R id number returned by the call described above.
- ES:DI The segment (ES) and offset (DI) of a parameter block to be
- passed to Play/R. This is where all the information passed
- in and out of Play/R is placed.
-
- The parameter area passed to Play/R via this call is an array of at
- least 32 bytes. There is a set of about two dozen API functions which
- may be called. In all cases, the value of the first byte of the
- parameter block selects the function, and the remaining bytes are used
- to send or receive other information. The various functions and the
- layout of the parameter block are described in the following section.
- It is usually convenient to implement a routine in the high-level
- language which checks for the presence of Play/R, and another which
- makes the function calls, maintaining the parameter block as a global
- array.
-
- ------------------------------------------------------------
- Note: See "Language Libraries" section for information on
- included high-level libraries.
- ------------------------------------------------------------
-
-
- *******************
- * API functions *
- *******************
-
- In the following, you should assume that the parameter block used to
- pass information to and from Play/R is a byte array named "param", and
- that it is indexed starting at zero. Then param[0] (using Pascal/C
- index notation) will always contain the number of the API function to be
- performed. The contents of positions 1 thru N will vary depending on
- the nature of the function. Some functions will change the values in
- the param array when data is requested. In some cases, param[0] may
- change during the call, so you should not depend on any array position
- remaining the same after a function completes.
-
-
- Function 0: Pause song. Does not stop already sounding notes. Use
- function 9 after function 0 to completely silence output
- (except possibly for brief pauses).
-
-
- Function 1: Begin playing song (or continue playing if paused). A song
- must have already been loaded via function 4 or 8.
-
-
- Function 2: Trigger pop up of user control window. Play/R only.
-
-
- Function 3: Rewind song and pause. Stops all sounding notes.
-
-
- Function 4: Load MIDI song file and start playing immediately.
-
- Call data: param[1..n] = A zero-byte terminated MIDI file name
- string.
-
- To load a play list (a text file with one MIDI file name
- per line), prefix the file name with "@" to identify it
- as a list.
-
- Return data: param[0] = File load status:
-
- 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
-
-
- Function 5: Get play status
-
- Return data: param[0] = 1 if playing, 0 if paused.
- param[1] = 1 if at end of song, else 0.
- param[2..5] = Song position in milliseconds
- (double word integer).
- param[6] = Number of songs in play list.
- param[7] = Current song number in play list.
-
-
- Function 6: Return file load status (obsolete - use function 5)
-
- Function 7: Return song finished status (obsolete - use function 5)
-
-
- Function 8: Load MIDI file - same as function 4, but play does not begin
- automatically.
-
-
- Function 9: Stop all sounding notes (use with long pauses to quiet
- active notes).
-
-
- Function 10: Enable/disable user initiated pop up. (Play/R only)
-
- Call data: param[1] = 1 - Enable
- 0 - Disable
-
-
- Function 11: Adjust overall volume level.
-
- Call data: param[1] = Amount to adjust volume. May range from
- -127 to +127 as a 1-byte, 2's complement number.
-
-
- Function 12: Reset MIDI interface. Restores playable "UART" status.
-
- Call data: param[1] = 0 (or specific device number - see fcn 20)
-
-
- Function 13: Set timer mode.
-
- Call data: param[1] = 1 to 3 (See "Timing Considerations" below)
-
-
- Function 14: Get channel attributes. Returns one of three possible sets
- of information about MIDI channel usage: channel mapping,
- muting, and transpose.
-
- Call data param[1] = 0 Return channel mapping
- 1 Return channel enable status (muting)
- 2 Return channel transpose
-
- Return data: param[2..17] = 16 channel channel attribute values.
-
- Channel mapping: The returned bytes represent
- the output channels to which the original MIDI
- file channels are now being redirected.
-
- Channel enable: For each corresponding channel,
- if the data byte is 1, the channel is enabled;
- if 0, the channel is disabled (muted).
-
- Channel transpose: The returned bytes indicate
- the note transposition for each channel, from
- -127 to +127. These values are 8-bit two's
- complement numbers.
-
-
- Function 15: Set channel attributes.
-
- Call data param[1] = 0 Set channel mapping
- 1 Set channel enable status
- 2 Set channel transpose
-
- param[2..17] = 16 channel attribute values.
- See function 14 above.
-
-
- Function 16: Set song position in milliseconds
-
- Call data: param[1..4] = Song position n in milliseconds.
- For n less than zero, fast forward abs(n)
- milliseconds. Double word integer.
-
-
- Function 17: Skip forward in play list.
-
- Call data: param[1] = Number of songs to skip. If 0 then
- 1 is assumed. Skipping past the end of the list
- skips to song 1. The current song number and size
- of play list may be obtained using function 5.
-
-
- Function 18: Set song looping mode.
-
- Call data: param[1] = Loop mode:
- 0 = no looping
- 1 = loop song
- 2 = loop play list (startup default)
-
-
- Function 19: Reserved
-
-
- Some of the following functions can work with multiple MIDI interfaces.
- Play/R supports up to 4 devices, each of which is selected in these
- function calls by a "device number". Use function 20 to identify the
- particular type of device associated with each device number. In most
- cases, however, it will be appropriate to use the default device,
- selected as device zero. Each device to be used must appear as a
- separate -d option on the playr/playd command line (or corresponding
- environment variables must be set - see MidiTools manual Appendix A).
-
-
- Function 20: Get MIDI device name and description.
-
- Call data: param[1] = Device number (counting from 1)
-
- Return data: param[1] = Same device number, or 0 if no more
- devices.
- param[2..4] = 3-character device name
- param[5..24] = 20-character device description
-
- Call this function repeatedly, incrementing param[1], until param[1]
- returns with 0 to obtain all available devices. To get just the
- default device, use function 26 first to obtain its device number.
- Then call function 20 with the returned number.
-
-
- Function 21: Send MIDI bytes (short).
-
- Call data: param[1] = Device number (0 = default device)
- param[2] = Number of MIDI bytes to send
- param[3..n] = MIDI data bytes
-
-
- Function 22: Send MIDI bytes (long).
-
- Call data: param[1] = Device number (0 = default device)
- param[2..3] = Number of MIDI bytes (word)
- param[4..7] = 32-bit pointer to MIDI buffer
- param[8..11] = reserved; must be 0
-
-
- Function 23: Check for MIDI input.
-
- Call data: param[1] = Device number (0 = default device)
-
- Return data: param[2] = 1 if data waiting, 0 if none
-
- Note: playr.exe (or playd.exe) must be run with the -s option
- to enable interrupt-driven, buffered input. Otherwise,
- only a very small buffer is allocated, and polled input
- is used, possibly resulting in lost data.
-
-
- Function 24: Get MIDI input bytes.
-
- Call data: param[1] = Device number (0 = default device)
- param[2..3] = Max size of receiving buffer (word)
- param[4..7] = 32-bit pointer to buffer
-
- Return data: param[8..9] = Number of bytes transferred
- param[10] = 1 if more data remains, 0 if no more data
-
-
- Function 25: Get absolute time in milliseconds.
-
- Return data: param[1..4] = Reference time as a double word integer.
-
- The time returned is the number of milliseconds since the driver
- was loaded, and continues incrementing regardless of other machine
- operations.
-
-
- Function 26: Get default MIDI device number.
-
- Return data: param[1] = Default device number
-
- To obtain the name/description of the default device, use the
- returned value with function 20.
-
-
- Function 27: Get direct entry addresses of routines in MIDI driver.
-
- This function returns the addresses of the lowest level routines
- in the MIDI driver. These allow the API calls to be bypassed and
- improve performance where speed is critical. Setting up these
- calls can be a tricky process - see the C and Pascal libraries
- for examples if implementing this yourself.
-
- Return data: param[1..4] = midiPutByte
- param[5..8] = midiInputReady
- param[9..12] = midiGetByte
- param[13..16] = midiClearInput
- param[17..20] = msTimer
- param[21..24] = midiGetMessage
- param[25..28] = midiResend
- param[29..32] = midiPutMessage
-
- midiPutByte - Write a single MIDI byte.
-
- Pascal: procedure midiPutByte(dev, data: integer);
- C: VOID FAR PASCAL midiPutByte ( INT dev, INT data )
-
-
- midiInputReady - Test for input data waiting.
-
- Pascal: function midiInputReady(dev: integer): boolean;
- C: CHAR FAR PASCAL midiPutByte ( INT dev )
-
-
- midiGetByte - Read a single MIDI byte. Returns -1 if no data
- arrives within 200 ms. Use with midiInputReady
- for best results.
-
- Pascal: procedure midiGetByte(dev: integer; var data: integer);
- C: VOID FAR PASCAL midiGetByte ( INT dev, INT FAR *data )
-
-
- midiClearInput - Clear all unread data from device.
-
- Pascal: procedure midiClearInput(dev: integer);
- C: VOID FAR PASCAL midiClearInput ( INT dev )
-
-
- msTimer - Return reference time in milliseconds.
-
- Pascal: function msTimer: longint;
- C: LONG FAR PASCAL msTimer()
-
-
- midiGetMessage - Get a full MIDI message from specified device,
- returning message ordinal, channel, and two
- data bytes (one or both may be unused).
-
- Pascal: procedure midiGetMessage(dev: integer;
- var msg: messages; var chan, data1, data2: byte);
-
- C: VOID FAR PASCAL midiGetMessage ( INT dev,
- messages FAR *msg, byte FAR *chan,
- byte FAR *data1, byte FAR *data2)
-
- midiResend - Resend data just read by midiGetMessage;
-
- Pascal: procedure midiResend(dev: integer);
- C: VOID FAR PASCAL midiResend ( INT dev )
-
-
- midiPutMessage - Send a full MIDI message using specified device,
- message ordinal, channel, and two data bytes.
-
- Pascal: procedure midiPutMessage(dev: integer;
- msg: messages; chan, data1, data2: byte);
-
- C: VOID FAR PASCAL midiPutMessage ( INT dev,
- messages msg, byte chan, byte data1, byte data2)
-
-
- Notes: The dev parameter on all routines specifies the
- MIDI device number to use. It must be 1 or greater,
- unlike the API functions which accept 0.
-
- MIDI input/output bytes in midiGetByte and midiPutByte are
- actually passed in the low byte of an integer parameter.
-
- Data type "byte" is an unsigned char.
-
- Data type "messages" is defined in Pascal as:
-
- messages = (noteoff, noteon, polyat, ctrlchange,
- progchange, chanat, pitchwheel,
- sysex, quarter, songpos, songsel, tune,
- eox, undefsc,
- clock, startc, continue, stopc, actsens,
- mreset, undefrt,
- dummy, none);
-
- and in C as:
-
- typedef enum { ...same list as above... } messages;
-
- (These definitions are included in MIDI.INC and MLIB.H.)
-
-
-
- ***************************
- * Timing Considerations *
- ***************************
-
- Since DOS was not designed as a real time operating system, there is no
- one timing method that is perfect for every application. Because of
- this, Play/R offers several timing modes which you must evaluate in
- terms of your own application. Although the player can generally tell
- within less than a millisecond what time it is, if control is not passed
- to it periodically, play cannot proceed. This is where the various
- modes come in.
-
- Mode 1 is the simplest, relying on DOS to wake up the player
- periodically when it is idling, waiting for keyboard input. Since some
- applications, such as GRASP, bypass DOS and do their own keyboard input,
- control is never passed to the player.
-
- Mode 2 relies on the system clock to wake it up via interrupts
- approximately every 55 milliseconds. Mode 1 idle processing is also
- used if available to smooth timing. This will work much better for most
- applications, but 55 milliseconds may not be precise enough for some
- compositions. Let your ear be the judge.
-
- Mode 3 is a little more forceful than mode 2. Mode 2 is very polite,
- and won't interrupt DOS, but this may cause long pauses while doing
- certain operations which rely heavily on DOS. Although technically
- "unsafe", all but the most time critical operations, such as network
- access, will continue unhindered when using this mode.
-
- When 55 millisecond resolution is not adequate, you may use the -c
- option on playr.exe/playd.exe if running on a 286 or better. This
- replaces the 55 ms timer in modes 2 and 3 with the AT real time clock,
- at a resolution of 1 ms. The disadvantage of this mode is that 1000
- interrupts per second tend to slow down other operations. Again, you
- must decide if this slowdown is significant for the intended application
- and target hardware.
-
-
-
- *********************************
- * Driver Command Line Options *
- *********************************
-
- The following options may be included on the playr/playd command
- line (separated by spaces):
-
- -a Indicates the amount of memory (in K bytes; 1K = 1024 bytes)
- to allocate for MIDI file storage. The default is -a24 (24K bytes).
-
- -m Selects the timer mode: 1, 2, or 3. The default is -m1. See
- "Timing Considerations" above.
-
- -c Use the AT real time clock on 286 or better machines for
- modes 2 and 3. (Not compatible with Microsoft Windows)
-
- -h For use with Microsoft Windows only: Uses the MidiTools virtual
- timer device (timer.386) if it has been installed, and Play/R is
- running in a DOS window in 386 enhanced mode (not supported in
- standard mode). This provides better timer resolution than the
- normal Windows clock.
-
- -l Specifies that LIM EMS (expanded memory) is to be used for
- MIDI file storage if available. This reduces the resident
- size of Play/R.
-
- -d Specifies the type of MIDI interface in use. Also, it is
- used to give additional information about the device if a
- non-standard setup is being used. For the majority of users,
- this option will not be needed. The supported interfaces are
- listed below. Use -d, followed by the device name as shown
- to select one.
-
- Roland MPU-401 and compatibles -dmpu
- IBM PC Music Feature -dmfc
- Sound Blaster MIDI interface -dsbmidi
- Key Electronics MIDIator -dmidiator
- Generic serial interface 38400 baud -dser
- AdLib compatible FM sound -dadlib
- Sound Blaster compatible FM sound -dsbfm
-
- The first 3 letters of the device name are sufficient.
-
- Note: The MIDIator and generic serial interfaces cannot be detected
- automatically and the -dmid or -dser option must always be specified
- if one is in use.
-
- Non-standard IRQ and I/O port information can be added
- following the device id if necessary: -d<dev>:<irq>:<ioaddr>
-
- For example, to define an MPU-compatible interface using IRQ 5
- and I/O address 336 (hex), use: -dmpu:5:336
-
- If only the I/O address was required but the default IRQ
- was alright, use: -dmpu::336
-
- The irq and ioaddr are not relevant for -dmid and -dser, though
- the first option number can be given to indicate use of com
- port 2 instead of the default com 1. (ex: -dmid:2)
-
- -i This option applies to the AdLib and Sound Blaster FM sound
- options, and specifies the name of an instrument bank (.IBK)
- file used to obtain instrument sounds when using standard MIDI
- files. Note that CMF files usually contain their own instrument
- definitions and will override this option.
-
- -v Shows the MIDI device, I/O address, and IRQ number selected
- prior to program startup. You may wish to include this option
- if you suspect that automatic detection is not choosing the
- desired options, or to verify the IRQ being used.
-
-
- -s Determines the size of the MIDI receive buffer. Follow -s
- with a number up to 63, indicating the size of the buffer in
- K bytes (1K=1024 bytes). By default, no buffer is used, and
- Play/R operates in polled input mode.
-
- -r Remove Play/R from memory if it is already loaded.
-
-
-
- ************************
- * Language Libraries *
- ************************
-
- In order to simplify use of the Play/R API, basic interfaces in several
- languages have been included. Not all features have been implemented
- for each language. See the documentation file for the language of
- interest for details on the specific API.
-
- Language Source files Documentation
- ------------------------------ ------------ -------------
- C (Microsoft, Borland) MLIB.C MLIB_C.DOC
- MLIB.H
-
- Pascal (Borland, Stony Brook) MLIB.PAS MLIB_PAS.DOC
- MIDI.INC
-
- MS Quick Basic MLIB.QB MLIB_BAS.DOC
- MLIB.BI
-
- MS Visual Basic for DOS MLIB.VB MLIB_BAS.DOC
- MLIB.BI
-
- GRASP (animation language) MIDI.TXT GRASP.DOC
- MIDI_MM.TXT
-
- A DOS command line program implementing many of the MIDI file
- functions is available as an alternative for use in languages
- which do not support software interrupts, but which can execute
- DOS commands. See PRC.DOC for information on this program.
-
-
-
- ********************************
- * Distribution License Terms *
- ********************************
-
-
- Play/R: The Play/R module MAY NOT be redistributed under any circumstances
- without written permission from FM Software.
-
-
- Play/D: The Play/D module MAY be distributed royalty-free only when used
- as an integral part of a commercial end user application developed
- by the individual (or organization) who purchased MidiTools. The
- playing of MIDI song files must be secondary to the purpose of the
- application. The following statement must be included in the
- documentation for the application: "FM Software Play/D MIDI driver
- distributed by permission."
-
- This distribution license also applies to shareware products with
- required registration, but not to software offered in the public
- domain or without payment required. Unlimited internal use by
- the purchaser is permitted.
-
- Software packages intended for use in applications development
- DO NOT qualify as end user applications under this license.
- Play/D may not be distributed with such products without being
- separately licensed. Royalty and other licensing options are
- available from FM Software.
-
- A keyed demo version of Play/D with no distribution restrictions
- is available. Contact FM Software for details.
-
-
- PRC: The PRC program may be freely distributed with applications using
- Play/D.
-
- Language Libraries:
-
- The high-level language API libraries included may be incorporated
- in your applications which use Play/D and may be distributed in
- binary form only.
-
- Other MidiTools modules:
-
- No other MidiTools modules may be distributed under any
- circumstances without written permission from FM Software.
-
- -------------------------------------------------------------------------------
-