home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 1B
/
DATAFILE_PDCD1B.iso
/
_pocketbk
/
pocketbook
/
003
/
sndfrc_zip
/
SNDFRC.DOC
next >
Wrap
Text File
|
1992-05-13
|
7KB
|
168 lines
Using SNDFRC.LDD from Opl
=========================
These notes comment the associated program, TESTMUS.OPL.
This demonstrates the use of SNDFRC.LDD, which is an extension of the
Operating System allowing better access to the loudspeaker on the
Series3. Sounds played via the loudspeaker are generally louder than
those played via the buzzer (eg the output of BEEP commands in Opl).
In order for the program to work, the file SNDFRC.LDD should be
placed in M:\ on the Series3. Somebody who wanted to place this LDD
elsewhere could alter the code inside the routine InstMus:.
Overview
--------
TESTMUS.OPL demonstrates:
(1) Installing and removing the LDD
(2) Simple playing of "tunes"
(3) More advanced playing of "tunes" that can be cancelled.
The easiest bit to understand is (2), which involves the routines
OpenMus:, play:, and CloseMus:. (Many users could get by with a
simpler version of OpenMus:, to start with.)
The only variables needed for these are mcb% and vals%().
The variable mcb% is the handle of the control block filled in by
ioopen. It needs to be passed to subsequent calls ioclose and
iowrite.
The essence of OpenMus: is the single line
ioopen(mcb%,"MUS:",-1)
The rest of it is just error handling to cope with the case when
another application already has the sound channel in use (eg an
application which is DTMF dialling).
The way the sounds are actually emitted is in response to the iowrite
call. The buf% parameter here is the address of an array of
integers, as set up by the caller. The len% parameter is how many
notes to play.
Each "note" is made up of three parts: tone, length, and volume.
Eg in
vals%(9) = $3b + (40*256) + (3*64)
the tone is $3b, the length (duration) is 40, and the volume is 3.
There are only 4 possible values of volume: 0 (the quietest), 1, 2,
and 3 (the loudest).
The duration is measured in 1/100 ths of a second, and can have any
value from 1 to 255. Note that because of the limitations of Opl you
cannot type in eg
vals%(2) = $0 + (150*256) + (2*64)
(without getting an OVERFLOW error raised)
but you can instead use
vals%(2) = $0 + ((256-150)*256) + (2*64)
The allowed values of tone in principle range from $0 to $3f.
In practice you may consider using:
DTMF (dual) tones:
------------------
$10 for digit 0, $11 for digit 1, ..., $19 for digit 9, $1a for a
(defined for some telephone systems), ..., $1d for d, $1e for * and
$1f for #.
MODEM tones:
------------
$24 gives 1300 Hz, $25 gives 2100 Hz, then 1200, 2200, 980, 1180,
1070, 1270, 1650, 1850, 2025, and $2f gives 2225 Hz.
MUSICAL tones:
--------------
Twenty five notes are possible, incrementing by semi-tones over a 2
octave interval from D#5 to D#7:
$30, $31, $32, $33, $34, $35, $36, $37, $38, $39, $3a, $29, $3b, $3c,
$3d, $0e, $3e, $2c, $3f, $04, $05, $25, $2f, $06, $07.
Pauses:
-------
If tone is set to $0, the speaker will remain silent for the
specified duration.
When to open and close the MUS: device
--------------------------------------
If you like, just copy TESTMUS.OPL and open and close the device at
the beginning and end of your program.
But this is actually very anti-social!!
For example, if you have MUS: open, it prevents any other application
using the loudspeaker at all. if you wrote a game which opened
MUS: at its beginning, and only made sounds from time to time, and
left this game in the background while you went to the Data
application to look up a telephone number, you would find the DTMF
dialler would be unable to beep, and would report "Sound system in
use" - even though the game is silent at the time.
Far better in these situations for a program to open MUS: just before
it needs to do some playing, and then close it again immediately
afterwards. Ie put the open and close code inside the play: routine.
When to install and free SNDFRC.LDD
-----------------------------------
This is potentially a lengthy topic, and the following notes only
skim the surface.
The best advice is probably that a program which needs to use MUS:
should always call the equivalent of InstMus: on its start up, and
ignore any error message given if the device is already installed.
Further, it should probably *NOT* call FreeMus: at its close, since
this may have an unexpected effect on other applications running
simultaneously, which also access MUS:.
Instead, leave the LDD permanently installed if you can (it takes up
around 1.5k of ram), but provide another OPO whose sole content is
the equivalent of FreeMus:, so that someone who wants to recover the
ram space later can do so.
The magic runes inside InstMus: invoke an operating system routine to
install the LDD, so that any subsequent reference to "MUS:" will be
accepted by the operating system (the code to inplement MUS: being
located inside the LDD).
Allowing tunes to be cancelled
------------------------------
If you run TESTMUS, you will find it has four phases:
A musical scale, with varying volume and duration
A constant note with varying volume
Some DTMF tones
The same DTMF tones repeated.
The difference between the two sets of DTMF tones is just that the
first set can be abandoned part way through, if the user presses Esc.
Pressing Esc during any of the other phases of the program has no
effect.
The sole use of the variables mstat%, kstat%, and key%() in the
program is to allow this cancelling to take place.
(Opl programmers unfamiliar with asynchronous i/o may wish to stop
reading here.)
The best general mechanism for this is demonstrated in the program:
instead of using the (synchronous) IOWRITE, change to the
asynchronous IOA(...,2,...), which supports a later cancel using
IOW(...,3).
The loop of the form
WHILE 1
IOWAIT
....
ENDWH
is the standard way of being able to respond to events which can
occur in an order the program cannot predict (in this case, whether
the user presses a key first, or the DTMF tones finish playing).
After the IOWAIT returns, you test the various stat% variables to see
which of the events has indeed completed.
What various procedure names mean:
----------------------------------
queplay: is the asynchronous form of play:
quekey: queues an asynchronous keyboard read
cankey: cancels any outstanding asynchronous keyboard read
canplay: cancels any ongoing (asynchronously-launched) tone emission
flushkey: flushes the keyboard buffer.
These notes prepared:
---------------------
By DavidW, 13/05/92.