<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>
<TITLE>SharedSound functional specification</TITLE>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</HEAD>
<BODY text="#000000" link="#007000" bgcolor="#ffffff" vlink="#90a090" alink="#a0a070">

  <!-- Automatic section numbering in JavaScript browsers -->

  <script language="JavaScript1.1" type="text/javascript">
    <!--

      var section_number = 1;

      // Insert section number into the document. We could do a nicer
      // function and insert section headings entirely, but then you've
      // got to have JavaScript in the browser to read the document.

      function isn()
      {
        document.write(section_number + ".&nbsp;");
        section_number ++;
      }

    // -->
  </script>

<center>

  <table width="100%" cellpadding="0" cellspacing="4">
    <tr>
      <td width="100%" height="4" bgcolor="008000"><img width="1" height="1" src="images/blank.gif" alt=""></td>
    </tr>

    <tr>
      <td align="center">
        <h1 class="banner">SharedSound Functional Specification</h1>
      </td>
    </tr>

    <tr>
      <td width="100%" height="4" bgcolor="008000"><img width="1" height="1" src="images/blank.gif" alt=""></td>
    </tr>
  </table>
</center>
<p>
<center>
  <table cellspacing="0" cellpadding="0" border="0">
    <tr>
      <td align="right"><font size="2">Distribution:&nbsp;&nbsp;</font></td>
      <td align="left"><font size="2">General Release</font></td>
    </tr>
    <tr>
      <td align="right"><font size="2">Title:&nbsp;&nbsp;</font></td>
      <td align="left"><font size="2">Shared Sound Functional Specification</font></td>
    </tr>
    <tr>
      <td align="right"><font size="2">Issue:&nbsp;&nbsp;</font></td>
      <td align="left"><font size="2">1</font></td>
    </tr>
    <tr>
      <td align="right"><font size="2">Author(s):&nbsp;&nbsp;</font></td>
      <td align="left"><font size="2">Andy Pierson</font></td>
    </tr>
    <tr>
      <td align="right"><font size="2">&nbsp;</font></td>
      <td align="left"><font size="2">Robin Watts</font></td>
    </tr>
    <tr>
      <td align="right"><font size="2">Date:&nbsp;&nbsp;</font></td>
      <td align="left"><font size="2">03-Jun-2001</font></td>
    </tr>
    <tr>
      <td align="right"><font size="2">Master&nbsp;Format:&nbsp;&nbsp;</font></td>
      <td align="left"><font size="2">HTML</font></td>
    </tr>
    <tr>
      <td align="right"><font size="2">Revision:&nbsp;&nbsp;</font></td>
      <td align="left"><font size="2">1</font></td>
    </tr>
    <tr>
      <td align="right"><font size="2">Last&nbsp;Issue:&nbsp;&nbsp;</font></td>
      <td align="left"><font size="2">1, revision 1.0</font></td>
    </tr>
  </table>
</center>

<p>
<h2>
  <script language="JavaScript1.1" type="text/javascript">
    <!--
      isn();
    //-->
  </script>
  <a name="Acknowledgements">Acknowledgements</a>
</h2>

<p>All trademarks are acknowledged.

<p>
<h2>
  <script language="JavaScript1.1" type="text/javascript">
    <!--
      isn();
    //-->
  </script>
  <a name="cont">Contents</a>
</h2>

<p>
<ol type="1">
  <li><strong><a href="#Acknowledgements">Acknowledgements</a></strong>
  <li><strong><a href="#cont">Contents</a></strong>
  <li><strong><a href="#irhi">Issue/revision history</a></strong>
  <li><strong><a href="#Introduction">Introduction</a></strong>
  <li><strong><a href="#SWIs">SWIs</a></strong>
  <DL>
    <DT><a href="#SharedSound_InstallHandler">SharedSound_InstallHandler</a>
    <DT><a href="#SharedSound_RemoveHandler">SharedSound_RemoveHandler</a>
    <DT><a href="#SharedSound_HandlerInfo">SharedSound_HandlerInfo</a>
    <DT><a href="#SharedSound_HandlerVolume">SharedSound_HandlerVolume</a>
    <DT><a href="#SharedSound_HandlerSampleType">SharedSound_HandlerSampleType</a>
    <DT><a href="#SharedSound_HandlerPause">SharedSound_HandlerPause</a>
    <DT><a href="#SharedSound_SampleRate">SharedSound_SampleRate</a>
    <DT><a href="#SharedSound_InstallDriver">SharedSound_InstallDriver</a>
    <DT><a href="#SharedSound_RemoveDriver">SharedSound_RemoveDriver</a>
    <DT><a href="#SharedSound_DriverInfo">SharedSound_DriverInfo</a>
    <DT><a href="#SharedSound_DriverVolume">SharedSound_DriverVolume</a>
    <DT><a href="#SharedSound_DriverMixer">SharedSound_DriverMixer</a>
    <DT><a href="#SharedSound_CheckDriver">SharedSound_CheckDriver</a>
    <DT><a href="#SharedSound_ControlWord">SharedSound_ControlWord</a>
    <DT><a href="#SharedSound_HandlerType">SharedSound_HandlerType</a>
  </DL>
</ol>

<p>
<h2>
  <script language="JavaScript1.1" type="text/javascript">
    <!--
      isn();
    //-->
  </script>
  <a name="irhi">Issue / revision history</a>
</h2>
<p>
This document has appeared in several different forms, both as Acorn/Pace
internal documentation and as an ESP document. Previous documents have
often blurred the lines between what was intended, what was planned for future
and what actually is implemented. This revised document is intended to supplant
all previous documents by clearly defining what actually is implemented, and what
is planned for the future.

<p>
<h2>
  <script language="JavaScript1.1" type="text/javascript">
    <!--
      isn();
    //-->
  </script>
  <a name="Introduction">Introduction</a>
</h2>
<P>
The purpose of this module is summarised as follows:
<p>
<ol type="1">
  <li>To provide a well managed facility for shared use of digital sound output
  <li>To provide a 16 bit linear facility for sound output independently from
      the hardware used to output this sound
  <li>To provide good software support to potential users of digital sound
      output
  <li>To provide a call back facility for CPU intensive handlers allowing
      the hardware drivers to operate with interrupts disabled.
  <li>To give provision for effects and other processes to act on the sound
      buffers
</ol>
<p>
SharedSound allows multiple sound handlers to output through one sound source.
<p>
The original intention of SharedSound was that it could be extended to provide
a range of useful functions such as mixing, sample rate interpolation and
volume scaling. Versions prior to version 1.0 never implemented these, and
relied on clients to do the filling/mixing/interpolation as required.
<P>
While this technique avoided the memory bandwidth/CPU overheads that would
have been caused by clients naively filling buffers and SharedSound merging
them, it did force every SharedSound client to implement broadly the same
set of fill routines.
<P>
As from version 1.0 of SharedSound, SharedSound now offers clients a set of
standard fill routines that they can choose to use. This offers a number of
benefits; clients are easier to write, less code is needlessly duplicated
across components (with the consequent memory, cache and maintenance benefits
this gives) and, not least, a degree of future proofing is given to
extensions in the range of fill requests that can be made.
<P>
Some applications may choose not to call the SharedSound provided fillcode
however; it may be advantageous for a handler to do
its own mixing and volume scaling if it is already carrying out such functions
as in the case of the MIDI Synthesiser. AMPlayer uses its custom fill
routines as it also calculates the VU bar positions at this stage.
<P>
Some mixing is performed by SharedSound, however, to mix the 8 bit source
and any immediate sound handlers with the call back handler buffer data.
<P>
Each client wishing to register with SharedSound, passes the address of a
fill handler routine. SharedSound will then call this fill routine with
appropriate register values which indicate the current state of play,
in particular the current sample rate, along with associated values,
as well as the current volume setting. The volume for a handler is
calculated from the current system volume and the volume requested
for the handler. This is passed as a Left and Right (Stereo) volume as
two 16 bit words packed into a 32 bit word.
<P>
It was originally envisaged that the volume scaling would be dependent
on the number of currently active handlers, but this has never been
found to be necessary.
<P>
A public domain application !Mixer is available to control the relative
volumes of the SharedSound sources within a given system. This reads that
name and current volume of each handler and allows the user to set the
volume of each handler.
<P>
This interface is already used from PCSound so that PC software designed
to control the volumes of SoundBlaster devices actually controls the
volumes levels for the PCSound handler installed in SharedSound.
<P>
SharedSound will typically sit on top of the current Sound_LinearHandler.
The register values provided by the LinearHandler fill call are used as
the basis for the parameters passed by SharedSound to the SharedSound
handlers.  In other words the fill buffer size, initial buffer status
and current sample frequency are all derived from the LinearHandler.
<P>
The InstallDriver SWI has been implemented to allow SharedSound to sit
on other sound output hardware devices such as the ESP DMI/PowerWave card.
<P>
Shared Sound never changes the system sample rate in response to new
handlers (unless explicitly told to), but rather uses the rate currently
set. If there in only one handler present or active (all other handlers
paused) then it could change the system rate to suit the requests of the
single handler.
<P>
Warm Silence Software Ltd have implemented a module, RateTracker, that
monitors SharedSound and its registered handlers and sets the system
sample rate to the highest rate currently in use. This would benefit
from minor changes within SharedSound, or even being pulled into
SharedSound.
<P>
As the possession of the Sound_LinearHandler (as with other handlers) is
not in the control of SharedSound it is quite possible that SharedSound
may lose control of the handler.  To cope with this, SharedSound will
check that it is in charge of the handler whenever it is called via
its SWIs, and re-install if it has lost control.  A specific SWI is
provided which will check that SharedSound is still attached and this
can be called by the handler if required.
<P>
The call back mechanism is designed to relieve pressure on interrupts
by calling handlers in a state where interrupts can be enabled; to
provide 'look ahead' so that data is available when the system is busy,
to allow the soundDMA activity to overrun without crashing the computer
and to provide overrun information to handlers so that they can take
action to reduce CPU usage. Overrun detection and reporting is currently
not implemented.
<p>
<h2>
  <script language="JavaScript1.1" type="text/javascript">
    <!--
      isn();
    //-->
  </script>
  <a name="Implementation">Implementation</a>
</h2>
<P>
The current version of SharedSound provides three levels of handler
activity. The first is an immediate handler. This is called when
SharedSound is called by the SoundDMA and is therefore required to
act with interrupts disabled and return as quickly as possible.
Such handlers are likely to be simple 'fill buffer' handlers that
do not require to process any data or a timing device that is using
the Sound interrupt as a timer.
<P>
The second type of handler is a call back handler.  This is called on
a call back and can therefore operate with interrupts enabled and take
more time to execute.
<P>
The third is a process handler.  This is called in the same way as a call
back handler but is called at the end of the call back process to allow
it to add effects or process the current buffer in some way. Effects
produced by the process handler therefore only apply to the callback
handlers.
<P>
The call back buffer is set to 8 times the current SoundDMA buffer size
and the handlers are called repeatedly to attempt to keep the call back
buffer full. In other words, if there is sufficient CPU time then the call
back buffer will have 8 buffers ready for adding to the SoundDMA buffer
when called under interrupts.
<P>
When a handler is installed with SharedSound it can specify which sample
rate it requires.  SharedSound does not attempt to change the system rate
but it does calculate the fractional stepping value required by the handler
to achieve the rate required.  If the system rate is changed by another
application then SharedSound re-calculates the values for each handler
and passes on both the new sample rate and the new fractional step to
the handler on the next buffer fill.
<P>
Similarly, each handler's volume can be changed by an external application
and the current volume is passed on to each handler.
<P>
SharedSound is currently used by the the Sound16 codecs for Replay, the
PCSound support module, the MIDI Synthesiser, AMPlayer and many other
applications.


<p>
<h2>
  <script language="JavaScript1.1" type="text/javascript">
    <!--
      isn();
    //-->
  </script>
  <a name="SWIs">SWI Interface</a>
</h2>

<P>
<pre>
/* Shared Sound SWI definitions */

#define SharedSound_base              0x4B440         // r0           r1         r2       r3        Status
#define SharedSound_InstallHandler    (Synth_base+0)  // Handler      Parameter  Flags    Name      OK
#define SharedSound_RemoveHandler     (Synth_base+1)  // Handler num                                OK
#define SharedSound_HandlerInfo       (Synth_base+2)  // Handler num                                OK
#define SharedSound_HandlerVolume     (Synth_base+3)  // Handler num  Volume                        OK
#define SharedSound_HandlerSampleType (Synth_base+4)  //                                            x
#define SharedSound_HandlerPause      (Synth_base+5)  //                                            x
#define SharedSound_SampleRate        (Synth_base+6)  // Number       Rate                          OK
#define SharedSound_InstallDriver     (Synth_base+7)  //                                            x
#define SharedSound_RemoveDriver      (Synth_base+8)  //                                            x
#define SharedSound_DriverInfo        (Synth_base+9)  //                                            x
#define SharedSound_DriverVolume      (Synth_base+10) //                                            x
#define SharedSound_DriverMixer       (Synth_base+11) //                                            x
#define SharedSound_CheckDriver       (Synth_base+12) // None                                       OK 
#define SharedSound_ControlWord       (Synth_base+13) // None                                       OK 
#define SharedSound_HandlerType       (Synth_base+14) // Handler num  Type                          OK

OK = implemented
x  = not Implemented
</pre>
<P>
<DL>
<DT><H3>
<a name="#SharedSound_InstallHandler">SharedSound_InstallHandler</a>
</H3>
<DD>
<P>
This SWI is used to install multiple Sound Handlers into the system.
<P>
<DL>
<DT>
On entry
<DD>R0 = handler address
<DD>R1 = parameter to pass
<DD>R2 = flags
<DD>R3 = name of handler
<DD>If successful V flag is clear and R0 holds a handler number
<DD>If unsuccessful V flag is set and R0 points to a SWI error block.
<p>
<DT>Interrupts
<DD>Interrupts status is undefined
<DD>Fast interrupt are enabled
<p>
<DT>Processor mode
<DD>Processor is in SVC mode
<p>
<DT>Re-entrancy
<DD>SWI is not reentrant
<p>
<DT>Flags
<DD>Only one flag is used in this version:
<DL type="none">
<DD>Bit 0 if set then use type in R4 otherwise set type to default.
</DL>
<p>
<DT>Type
<DD>The handler types are defined as follows:
<DL>
<DD>0 Immediate handler
<DD>1 Call back handler
<DD>2 Process handler
</DL>
<p>
<DT>Use
<DD>Each handler is called with when the current driver is called if
the handler is an immediate handler or on call back if the handler is
either a call back or process handler.  The handlers in each type are
called in the order in which they were installed.  Process handlers
are called after call back handlers.
<P>
Each handler is passed a buffer to fill with the registers set as follows:
<P>
<DL>
 <DD>R0 = parameter
 <DD>R1 = base address of buffer to fill
 <DD>R2 = end of buffer
 <DD>R3 = flags
 <DL>
  <DD>Bit  0 If set then data must be mixed otherwise overwrite.
  <DD>Bit 30 Set if the volume in R7 is not equal to 0xFFFFFFFF
  <DD>Bit 31 Set if the volume in R7 is 0 (i.e. sound is muted)
  <p>
  <DT>All other bits are currently passed as 0, but it is anticipated
      that they may be used in the following way in future revisions of
      the module:
  <DD>Bit   1  If set then use highest quality e.g. oversampling.
  <DD>Bits 3-7 Overrun count
  <DL>
   <DD>0       No overrun
   <DD>1--30   Number of times buffer has been overrun
   <DD>31      Buffer has been overrun by more than 30 times
  </DL>
  <DD>Bit 29  Stereo. Reverse stereo if set.
 </DL>
 <DD>R4 =    sample frequency
 <DD>R5 =    sample period
 <DD>R6 =    fractional step as specified by SharedSound_SampleRate
 <DD>R7 =    LR volume
 <DD>R8 =    Pointer to table of helpful fill routines
</DL>
<DD>R4, R5 and R6 are set by SharedSound to the current values as passed
in from the lower level Sound Handler, thus may change between calls to
the clients handler.
<p>
<DT>On exit
<DD>R3 contains flags as above, modified according to the action of the
handler. The important requirement on exit is that bit 0 of R3 should be
set if any data has been written into the buffer. In fact, SharedSound
cannot currently cope with no data being filled, so zeros should always
be written.
<p>
<DT>Helpful fill routines
<DD>On entry to the fill code, R8 points to a table in the following
format:
<TABLE>
<TR><TD>[R8,#0]<TD>=<TD>Flags word; currently 0.</TR>
<TR><TD>[R8,#4]<TD>=<TD>Pointer to silence fill routine.</TR>
<TR><TD>[R8,#8]<TD>=<TD>Pointer to data fill routine.</TR>
</TABLE>
<P>This table may be extended in future to include more fill variants; it is
anticipated that the presence/absence of these routines will be indicated by
bits in the flag word.
<P>The data fill routine is called in the following way:
<P>
<DL>
 <DT>On Entry:
 <DD>R1 = Base address of buffer to be filled
 <DD>R2 = End of the buffer to be filled
 <DD>R3 = Flags (as on entry to the fill routine)
 <DD>R4 = Base of buffer to fill from
 <DD>R5 = End of buffer to fill from
 <DD>R6 = Fractional step value
 <DD>R7 = LR volume
 <DD>R9 = Fractional accumulator
 <p>
 <DT>On Exit:
 <DD>R0 = New flags (to be returned from fill handler in R3)
 <DD>R1 = Next byte to be filled
 <DD>R4 = Next byte to fill from
 <DD>R9 = New Fractional accumulator
 <DD>R2,R3,R5,R6,R7,R8,R12 preserved
 <DD>All other registers corrupted.
</DL>
<DD>The fill code will fill/mix from the given buffer to the output buffer.
It will return either when the buffer is filled, or when it runs out of
data.
<p>The silence code is identical except that R4 and R5 are not used, and
no data is read; the code fills/mixes zeros.
<p>The silence/data fill code entry points understand all the currently
defined flags in R3. The intention is that if future flags are added to
R3 then the supplied fill routines will be extended to understand them too.
This should provide a degree of forwards compatibility.
<p>The overall sound fill code in a client can therefore look something
like this (assuming the client is filling from a cyclic buffer):
<P>
<PRE>
fill
	STMFD	r13!,{r0-r2,r4-r12,r14}

	MOV	r12,r0
	; We are filling from play_ptr to where?
	LDR	r4,play_ptr
	LDR	r5,fill_ptr
	LDR	r9,buffer_start
	ADD	r4,r4,r9
	ADD	r5,r5,r9
	LDR	r9,accumulator
	; Are we wrapped, or unwrapped?
	CMP	r4,r5
	BEQ	out_of_data
	BLO	unwrapped
	; |*****-------------------------********|
	;       ^fill ptr                ^play ptr
	LDR	r5,buffer_end	; Fill from fill ptr to buffer_end
	; Call the fill code
	MOV	R14,PC
	LDR	PC,[R8,#8]
	; Did we run out of data?
	CMP	R4,R5		;
	LDRHS	R4,buffer_start	; If r4 >= r5 then we used all the
				; data in the buffer.
	CMP	R1,R2		; Did we finish the fill?
	BHS	finish		; If r1 >= r2 then we finished.
	LDR	R5,fill_ptr	; No, so we ran out of data. Jump
	CMP	R5,#0		; Check if there any data there -
	BEQ	out_of_data	; If not, play silence.
	ADD	R5,R5,R4
unwrapped
	; |-----*************************--------|
	;       ^play ptr                ^fill ptr
	; Call the fill code
	MOV	R14,PC
	LDR	PC,[R8,#8]
	; Either we finished the fill, or we ran out of data.
	CMP	R1,R2		; Did we finish?
	BEQ	finish
out_of_data
	; Fill with silence
	MOV	R14,PC
	LDR	PC,[R8,#4]
finish
	LDR	r3,buffer_start
	STR	R9,accumulator
	SUB	r4,r4,r3
	STR	R4,play_ptr
	MOV	r3,r0

	LDMFD	r13!,{r0-r2,r4-r12,PC}
</PRE>
</DL>
<P>
<DT>
<H3>
<a name="#SharedSound_RemoveHandler">SharedSound_RemoveHandler</a>
</H3>
<P>
<DD>
This SWI is used to remove a specific handler.
<P>
<DL>
 <DT>On entry
 <DD>R0 =    handler number
 <DD>If successful V flag is clear and R0 holds a handler number
 <DD>If unsuccessful V flag is set and R0 points to a SWI error block.
 <p>
 <DT>Interrupts
 <DD>Interrupts status is undefined
 <DD>Fast interrupt are enabled
 <p>
 <DT>Processor mode
 <DD>Processor is in SVC mode
 <p>
 <DT>Re-entrancy
 <DD>SWI is not reentrant
</DL>

<DT>
<H3>
<a name="#SharedSound_HandlerInfo">SharedSound_HandlerInfo</a>
</H3>
<P>
<DD>
This SWI is used to provide information on a specific handler.
<P>
<DL>
 <DT>On entry
 <DD>R0 = handler number or 0 to read number of first handler.
 <p>
 <DT>On exit (if R0 = 0 on entry)
 <DD>If successful V flag is clear and
 <DD>R0 = number of next available handler or 0 for none
 <DD>R1 - R5 corrupted
 <DD>If unsuccessful V flag is set and R0 points to a SWI error block.
 <p>
 <DT>On exit (if R0 non-zero on entry)
 <DD>If successful V flag is clear and
 <DL>
  <DD>R0 = number of next available handler or 0 for none
  <DD>R1 = Flags
  <DD>R2 = name
  <DD>R3 = Sample frequency
  <DD>R4 = Sample type
  <DD>R5 = Volume
 </DL>
 <DD>If unsuccessful V flag is set and R0 points to a SWI error block.
 <p>
 <DT>Interrupts
 <DD>Interrupts status is undefined
 <DD>Fast interrupt are enabled
 <p>
 <DT>Processor mode
 <DD>Processor is in SVC mode
 <p>
 <DT>Re-entrancy
 <DD>SWI is not reentrant
</DL>
<DT>
<H3>
<a name="#SharedSound_HandlerVolume">SharedSound_HandlerVolume</a>
</H3>
<DD>
<P>
This is to set the volume level for a particular handler. Shared sound
can use this information to provide internal mixing or pass it on to
the handler at each buffer fill.
<P>
<DL>
 <DT>On entry
 <DD>R0 =    Handler number
 <DD>R1 =    volume (bits 0-15 left channel, 16-31 right channel) 
 <p>
 <DT>On exit
 <DD>If successful V flag is clear and
 <DD>R0  is preserved
 <DD>R1 = current volume
 <DD>If unsuccessful V flag is set and R0 points to a SWI error block.
 <p>
 <DT>Interrupts
 <DD>Interrupts status is undefined
 <DD>Fast interrupt are enabled
 <p>
 <DT>Processor mode
 <DD>Processor is in SVC mode
 <p>
 <DT>Re-entrancy
 <DD>SWI is not reentrant
</DL>
<DT>
<H3>
<a name="#SharedSound_HandlerSampleType">SharedSound_HandlerSampleType</a>
</H3>
<i>Not implemented in this version.</i>
<DD>
<P>
This is to set the sample type for the data for a particular handler.
It is intended that Shared sound will provide a buffer to the handler
that is to be filled in this particular type.  It will return the buffer
fill type that it will be using.  By default this will be Stereo, 16 bit
Signed as in Sound Linear Handler.
<P>
It seems likely that this SWI will never now be implemented.
<P>
<DT>
<H3>
<a name="#SharedSound_HandlerPause">SharedSound_HandlerPause</a>
</H3>
<i>Not implemented in this version.</i>
<DD>
<P>This is to turn a particular handler on or off without having to
de-install it.
<P>
Its seems likely that this SWI will never now be implemented.
<P>
<DT>
<H3>
<a name="#SharedSound_SampleRate">SharedSound_SampleRate</a>
</H3>
<DD>
<P>This SWI is used to set the sample rate used by a particular handler.
Information is returned to indicate whether Shared Sound can provide
this rate and if not what is the nearest rate it can provide. Along
with this is a fractional step value to suggest how the handler can
achieve it's required rate. Sample frequency is always supplied in
1/1024 Hz.
<P>
<DL>
 <DT>On entry
 <DD>R0 = >0  handler number
 <DD>&nbsp;&nbsp;&nbsp;&nbsp;=  0 to set the rate for the current output driver
 <DD>R1 = sample frequency required
 <p>
 <DT>On exit
 <DD>R1 = current sample frequency
 <DD>R2 = current sample period
 <DD>R3 = fractional step required to achieve this rate in 8.24 fixed point
 <p>
 <DT>Interrupts
 <DD>Interrupts status is undefined
 <DD>Fast interrupt are enabled
 <p>
 <DT>Processor mode
 <DD>Processor is in SVC mode
 <p>
 <DT>Re-entrancy
 <DD>SWI is not reentrant
</DL>
<P>
<DT>
<H3>
<a name="#SharedSound_InstallDriver">SharedSound_InstallDriver</a>
</H3>
<DD>
<P>This is to allow other output devices to be installed.
<DL>
 <DT>On entry
 <DD>R0 = 1 to install linear handler
 <DD>&nbsp;&nbsp;&nbsp;&nbsp;= 2 to install log handler
 <DD>&nbsp;&nbsp;&nbsp;&nbsp;or a pointer to a driver table address.
 <DD>R1 = parameter to pass driver in R12 when called
 <DD>R2 = flags
 <DD>R3 = volume
 <p>
 <DT>On exit
 <DD>All registers preserved.
 <p>
 <DT>Interrupts
 <DD>Interrupts status is undefined
 <DD>Fast interrupt are enabled
 <p>
 <DT>Processor mode
 <DD>Processor is in SVC mode
 <p>
 <DT>Re-entrancy
 <DD>SWI is not reentrant
</DL>
<DT>
<H3>
<a name="#SharedSound_RemoveDriver">SharedSound_RemoveDriver</a>
</H3>
<DD>
<P>This is to allow other output devices to be installed. You cannot
uninstall the linear driver.
<P>
<DL>
 <DT>On entry
 <DD>R0 = 2 to deinstall log handler
 <DD>&nbsp;&nbsp;&nbsp;&nbsp;or a pointer to a driver table address.
 <p>
 <DT>On exit
 <DD>All registers preserved.
 <p>
 <DT>Interrupts
 <DD>Interrupts status is undefined
 <DD>Fast interrupt are enabled
 <p>
 <DT>Processor mode
 <DD>Processor is in SVC mode
 <p>
 <DT>Re-entrancy
 <DD>SWI is not reentrant
</DL>
<P>
<DT>
<H3>
<a name="#SharedSound_DriverInfo">SharedSound_DriverInfo</a>
</H3>
<DD>
<P>This provides information for a particular driver.
<P>
<DL>
 <DT>On entry
 <DD>R0 = Driver number
 <p>
 <DT>On exit
 <DD>R0 = number of next available driver or 0 for none
 <DD>R1 = flags
 <DD>R2 = name
 <DD>R3 = volume
 <DD>R4 = Overrun count
 <DD>All other registers preserved.
 <p>
 <DT>Interrupts
 <DD>Interrupts status is undefined
 <DD>Fast interrupt are enabled
 <p>
 <DT>Processor mode
 <DD>Processor is in SVC mode
 <p>
 <DT>Re-entrancy
 <DD>SWI is not reentrant
</DL>
<P>
<DT>
<H3>
<a name="#SharedSound_DriverVolume">SharedSound_DriverVolume</a>
</H3>
<DD>
<P>
This sets the volume for a driver.
<P>
<DL>
 <DT>On entry
 <DD>R0 = Driver number
 <DD>R1 = new volume
 <p>
 <DT>On exit
 <DD>R0 = current volume
 <DD>All other registers preserved.
 <p>
 <DT>Interrupts
 <DD>Interrupts status is undefined
 <DD>Fast interrupt are enabled
 <p>
 <DT>Processor mode
 <DD>Processor is in SVC mode
 <p>
 <DT>Re-entrancy
 <DD>SWI is not reentrant
</DL>
<P>
<DT>
<H3>
<a name="#SharedSound_DriverMixer">SharedSound_DriverMixer</a>
</H3>
<DD>
<P>This sets or reads the mixer values for a driver, where relevant.
<P>
<DL>
 <DT>On entry
 <DD>R0 = Driver number
 <DD>R1 = function
 <DL>
  <DD>0 = read
  <DD>1 = set
 </DL>
 <DD>R2 = mixer number
 <DD>R3 = value (if set)
 <p>
 <DT>On exit
 <DD>R0 preserved
 <DD>R1 = number of mixers
 <DD>R2 = value
 <DD>R3 = name
 <DD>All other registers preserved.
 <p>
 <DT>Interrupts
 <DD>Interrupts status is undefined
 <DD>Fast interrupt are enabled
 <p>
 <DT>Processor mode
 <DD>Processor is in SVC mode
 <p>
 <DT>Re-entrancy
 <DD>SWI is not reentrant
</DL>
<P>
<DT>
<H3>
<a name="#SharedSound_CheckDriver">SharedSound_CheckDriver</a>
</H3>
<DD>
<P>This is used to force SharedSound to make sure that current driver is
still active. It is needed for situations where another application has
taken control of the Sound Linear handler and note returned control to
SharedSound.
<P>
<DL>
 <DT>On entry:
 <DD>none
 <p>
 <DT>On exit:
 <DD>none
 <p>
 <DT>Interrupts
 <DD>Interrupts status is undefined
 <DD>Fast interrupt are enabled
 <p>
 <DT>Processor mode
 <DD>Processor is in SVC mode
 <p>
 <DT>Re-entrancy
 <DD>SWI is not reentrant
</DL>
<DT>
<H3>
<a name="#SharedSound_ControlWord">SharedSound_ControlWord</a>
</H3>
<DD>
<P>This is used by the Replay Sound16 codecs as part of the
multi-tasking Replay implementation.  It provides a control
word to both Replay and the Sound16 code allowing for a &quot;1 audible
handler of many&quot; support.
<P>
<DL>
 <DT>On entry:
 <DD>none
 <p>
 <DT>On exit:
 <DD>R0 = Pointer to  control word
 <p>
 <DT>Interrupts
 <DD>Interrupts status is undefined
 <DD>Fast interrupt are enabled
 <p>
 <DT>Processor mode
 <DD>Processor is in SVC mode
 <p>
 <DT>Re-entrancy
 <DD>SWI is not reentrant
</DL>
<P>
<DT>
<H3>
<a name="#SharedSound_HandlerType">SharedSound_HandlerType</a>
</H3>
<P>
<DD>This is used to change the type of a handler from for example, and
immediate handler to a call back handler.
<P>
<DL>
 <DT>On entry:
 <DD>R0 =    handler number
 <DD>R1 =    handler type (see Install handler for type number)
 <p>
 <DT>On exit:
 <DD>none
 <p>
 <DT>Interrupts
 <DD>Interrupts status is undefined
 <DD>Fast interrupt are enabled
 <p>
 <DT>Processor mode
 <DD>Processor is in SVC mode
 <p>
 <DT>Re-entrancy
 <DD>SWI is not reentrant
</DL>
</DL>
</BODY>
</HEAD>
