<HTML><HEAD><TITLE>Shared Sound Software Functional Specification</TITLE><LINK REV=MADE HREF="mailto:mtaunton@acorn.co.uk"></HEAD>


<BODY BGCOLOR="#ffffff">

<H1 ALIGN=CENTER>
    Shared Sound Software Functional Specification 
</H1>

<HR>
<P ALIGN=CENTER><STRONG>CONFIDENTIAL</STRONG></P>
<HR>

<TABLE ALIGN=CENTER BORDER=0 WIDTH="40%">
<TR><TD>Document ref:		<TD>2107,746
<TR><TD>Project:		<TD>NC100 1.15
<TR><TD>Revision: 		<TD>$Revision$
<TR><TD>Date:			<TD>$Date$
<TR><TD>Author(s):		<TD>Mark Taunton
<TR><TD>Change:			<TD>ECO 3997
<TR><TD>Classification:		<TD>Acorn Restricted
</TABLE>

<HR>

<H2> Contents </H2>

<TABLE BORDER=0 WIDTH="100%">
<TR><TD WIDTH="8%">1.0		<TD><A HREF="#overview">	Overview </A>
<TR><TD>2.0		<TD><A HREF="#outstanding">	Outstanding issues </A>
<TR><TD>3.0		<TD><A HREF="#technical">	Technical background </A>
<TR><TD>4.0		<TD><A HREF="#user">		User interface </A>
<TR><TD>5.0		<TD><A HREF="#programmer">	Programmer interface </A>
<TR><TD>6.0		<TD><A HREF="#interchange">     Data interchange </A>
<TR><TD>7.0             <TD><A HREF="#formats">         Data formats </A>
<TR><TD>8.0             <TD><A HREF="#external">        External dependencies </A>
<TR><TD>9.0		<TD><A HREF="#acceptance">	Acceptance test </A>
<TR><TD>10.0            <TD><A HREF="#noncompliances">  Non compliances </A>
<TR><TD>11.0		<TD><A HREF="#test">		Development test strategy </A>
<TR><TD>12.0		<TD><A HREF="#organisation">	Product organisation </A>
<TR><TD>13.0		<TD><A HREF="#enhancements">	Future enhancements </A>
<TR><TD>14.0	<TD><A HREF="#glossary">	Glossary </A>
<TR><TD>15.0	<TD><A HREF="#references">	References </A>
<TR><TD>16.0	<TD><A HREF="#history">		History </A>
</TABLE>

<HR>

<H2> <A NAME="overview"> 1.0 Overview </A> </H2>

<p>The purpose of the SharedSound module is to allow multiple,
distinct, simultaneous software sound generation activities (e.g. a
sound codec under Replay, the software MIDI synthesiser, and a
directly generated sound effect) to all output their individual sounds
in a consistent way, to a single sound output device.  Each source can
have its own volume level and sample rate, with the SharedSound module
maintaining this information on its behalf.  In cooperation with code
in the respective client (source) applications to implement the
low-level operations, the SharedSound module supports the conversion
and mixing of the individual streams of data in the appropriate way,
to produce a final composite output stream to be delivered to the
hardware.  The composite stream can also be processed by further
functions, also registered by clients of the module, to achieve any
overall effects which may be desired.

<HR>

<H2> <A NAME="outstanding"> 2.0 Outstanding issues </A> </H2>

<p>There are no outstanding issues.
<HR>

<H2> <A NAME="technical"> 3.0 Technical background </A> </H2>

<h3>Principles</h3><br>

<p>SharedSound allows multiple sound handlers to output through one
sound output route. SharedSound can potentially provide a number of
useful functions such as mixing, sample rate interpolationand volume
scaling. The initial versions of Shared Sound will simply store the
values requested and insist that the handlers provide these functions.
It may be advantageous for a handler to do its own mixing, volume
scaling and frequency conversion if it is already carrying out such
functions as in the case of the MIDI Synthesiser.  Some mixing is
required by SharedSound, however, to mix the 8 bit source and any
immediate sound handlers with the call back handler buffer data.

<p>In any case values are passed to the Handler fill routine 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 as well as
scaling depending on the number of currently active handlers. This is
passed as a Left and Right (Stereo) volume as two 16 bit words packed
into a 32 bit word.  A mixer could be provided that reads that name
and current volume of each handler and allows the user to set the
volume of each handler.  

<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.  It is perfectly feasible for
the InstallDriver SWI to be implemented so that SharedSound could sit
on other sound output hardware devices, although this may not be the
best way of providing a fully integrated sound system.

<p>Initially, Shared Sound will not offer the sample rate required by
a client handler but will use the rate currently set in the hardware.
If there is only one handler present or active (all other handlers
paused) then it could (in principle) change the system rate to suit
the requests of the single handler; however the current version does
not do this.

<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.

<h3>Implementation</h3><br>

<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 handler type 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.  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.
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/drivers for
Replay, the sound effects system and the MIDI Synthesiser.  All sound
sources can be active at once.

<HR>

<H2> <A NAME="user"> 4.0 User interface </A> </H2>

<p>SharedSound has no direct user interface.

<HR>

<H2> <A NAME="programmer"> 5.0 Programmer interface </A> </H2>

<h3>SWI interface</h3>
<p>Shared Sound SWI definitions

<TABLE BORDER=1>
<TR><TD WIDTH="250"><STRONG>SWI Name</STRONG></TD><TD WIDTH="80"><STRONG>SWI-num</STRONG></TD><TD WIDTH="90"><STRONG>r0</STRONG></TD><TD WIDTH="90"><STRONG>r1</STRONG></TD><TD WIDTH="70"><STRONG>r2</STRONG></TD><TD WIDTH="70"><STRONG>r3</STRONG></TD><TD WIDTH="45"><STRONG>Status</STRONG></TD></TR>
<TR><TD>SharedSound_InstallHandler   </TD><TD>0xB440</TD><TD>Handler     </TD><TD>Parameter </TD><TD>Flags </TD><TD>Name </TD><TD>OK</TD></TR>
<TR><TD>SharedSound_RemoveHandler    </TD><TD>0xB441</TD><TD>Handler-num </TD><TD>--        </TD><TD>--    </TD><TD>--   </TD><TD>OK</TD></TR>
<TR><TD>SharedSound_HandlerInfo      </TD><TD>0xB442</TD><TD>Handler-num </TD><TD>--        </TD><TD>--    </TD><TD>--   </TD><TD>OK</TD></TR>
<TR><TD>SharedSound_HandlerVolume    </TD><TD>0xB443</TD><TD>Handler-num </TD><TD>Volume    </TD><TD>--    </TD><TD>--   </TD><TD>OK</TD></TR>
<TR><TD>SharedSound_HandlerSampleType</TD><TD>0xB444</TD><TD>--          </TD><TD>--        </TD><TD>--    </TD><TD>--   </TD><TD>x</TD></TR>
<TR><TD>SharedSound_HandlerPause     </TD><TD>0xB445</TD><TD>--          </TD><TD>--        </TD><TD>--    </TD><TD>--   </TD><TD>x</TD></TR>
<TR><TD>SharedSound_SampleRate       </TD><TD>0xB446</TD><TD>Handler-num      </TD><TD>Rate      </TD><TD>--    </TD><TD>--   </TD><TD>OK</TD></TR>
<TR><TD>SharedSound_InstallDriver    </TD><TD>0xB447</TD><TD>--          </TD><TD>--        </TD><TD>--    </TD><TD>--   </TD><TD>x</TD></TR>
<TR><TD>SharedSound_RemoveDriver     </TD><TD>0xB448</TD><TD>--          </TD><TD>--        </TD><TD>--    </TD><TD>--   </TD><TD>x</TD></TR>
<TR><TD>SharedSound_DriverInfo       </TD><TD>0xB449</TD><TD>--          </TD><TD>--        </TD><TD>--    </TD><TD>--   </TD><TD>x</TD></TR>
<TR><TD>SharedSound_DriverVolume     </TD><TD>0xB44A</TD><TD>--          </TD><TD>--        </TD><TD>--    </TD><TD>--   </TD><TD>x</TD></TR>
<TR><TD>SharedSound_DriverMixer      </TD><TD>0xB44B</TD><TD>--          </TD><TD>--        </TD><TD>--    </TD><TD>--   </TD><TD>x</TD></TR>
<TR><TD>SharedSound_CheckDriver      </TD><TD>0xB44C</TD><TD>None        </TD><TD>--        </TD><TD>--    </TD><TD>--   </TD><TD>OK</TD> </TR>
<TR><TD>SharedSound_ControlWord      </TD><TD>0xB44D</TD><TD>None        </TD><TD>--        </TD><TD>--    </TD><TD>--   </TD><TD>OK</TD> </TR>
<TR><TD>SharedSound_HandlerType      </TD><TD>0xB44E</TD><TD>Handler-num </TD><TD>Type      </TD><TD>--    </TD><TD>--   </TD><TD>OK</TD> </TR>
</table>
OK = implemented, x = not implemented

<H3>SharedSound_InstallHandler</H3>

<p>This SWI is used to install multiple Sound Handlers into the system.

<p><STRONG>On entry</STRONG>
<pre>        R0 =    handler address
        R1 =    parameter to pass
        R2 =    flags
        R3 =    name of handler
        If successful V flag is clear and R0 holds a handler number
        If unsuccessful V flag is set and R0 points to a SWI error block.
</pre>
<STRONG>Interrupts</STRONG>
<pre>        Interrupts status is undefined
        Fast interrupt are enabled
</pre>
<STRONG>Processor mode</STRONG>
<pre>        Processor is in SVC mode
</pre>
<STRONG>Re-entrancy</STRONG>
<pre>        SWI is not reentrant
</pre>

<p><STRONG>Flags</STRONG>
<p>Only one flag is used in this version:
<pre>        Bit 0           if set then use type in R4 otherwise set type to default.
</pre>
<p><STRONG>Type</STRONG>
<p>The handler types are defined as follows:
<pre>        0       Immediate handler
        1       Call back handler
        2       Process handler
</pre>
<p><STRONG>Use</STRONG>

<p>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><STRONG>On entry</STRONG>
<pre>        R0 =  parameter
        R1 =  base address of buffer to fill
        R2 =  end of buffer
        R3 =  flags:
                bit    0   Mix. If set then data must be mixed otherwise overwrite.
                bit    1   Quality. If set then use highest quality e.g. oversampling.
                bits 3-7   0       No overrun
                           1--30   Number of times buffer has been overrun
                           31      Buffer has been overrun by more than 30 times
                bit 29     Reversed Stereo: reverse stereo channels (L&lt;-&gt;R) if set.
                bit 30     Set if to use volume in R7, otherwise use max volume
                bit 31     Mute if set.
        R4 =  sample frequency
        R5 =  sample period
        R6 =  fractional step as specified by SharedSound_SampleRate
        R7 =  LR volume
</pre>
<p>R4, R5 and R6 are updated at the start of a buffer fill to represent
the current sample frequency etc.  Only bit 0 of the above flags is
implemented by SharedSound.  The other flags are currently used by the
Sound16 drivers.

<p><STRONG>On exit</STRONG>
<pre>        R3 contains flags as above, modified according to the action of the handler
</pre>

<H3>SharedSound_RemoveHandler</H3>

<p>This SWI is used to remove a specific handler.

<p><STRONG>On entry</STRONG>
<pre>        R0 =    handler number
</pre>
<p><STRONG>On exit</STRONG>
<pre>        If successful V flag is clear and R0 holds a handler number
        If unsuccessful V flag is set and R0 points to a SWI error block.
</pre>
<p><STRONG>Interrupts</STRONG>
<pre>        Interrupts status is undefined
        Fast interrupt are enabled
</pre>
<p><STRONG>Processor mode</STRONG>
<pre>        Processor is in SVC mode
</pre>
<p><STRONG>Re-entrancy</STRONG>
<pre>        SWI is not reentrant
</pre>

<H3>SharedSound_HandlerInfo</H3>

<p>This SWI is used to provide information on a specific handler.

<p><STRONG>On entry</STRONG>
<pre>        R0 =    handler number
</pre>

<p><STRONG>On exit</STRONG>
<pre>        If successful V flag is clear and
        R0 = number of next available handler or 0 for none
        R1 = Flags
        R2 = name
        R3 = Sample frequency
        R4 = Sample type
        R5 = Volume

        If unsuccessful V flag is set and R0 points to a SWI error block.
</pre>

<p><STRONG>Interrupts</STRONG>
<pre>        Interrupts status is undefined
        Fast interrupt are enabled
</pre>
<p><STRONG>Processor mode</STRONG>
<pre>        Processor is in SVC mode
</pre>
<p><STRONG>Re-entrancy</STRONG>
<pre>        SWI is not reentrant
</pre>


<H3>SharedSound_HandlerVolume</H3>

<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><STRONG>On entry</STRONG>
<pre>        R0 =    Handler number
        R1 =    volume (bits 0-15 left channel, 16-31 right channel) 
</pre>
<p><STRONG>On exit</STRONG>
<pre>        If successful V flag is clear and
        R0  is preserved
        R1 = current volume
        If unsuccessful V flag is set and R0 points to a SWI error block.
</pre>
<p><STRONG>Interrupts</STRONG>
<pre>        Interrupts status is undefined
        Fast interrupt are enabled
</pre>
<p><STRONG>Processor mode</STRONG>
<pre>        Processor is in SVC mode
</pre>
<p><STRONG>Re-entrancy</STRONG>
<pre>        SWI is not reentrant
</pre>

<H3>SharedSound_HandlerSampleType</H3>                          
<p>Not implemented in this version.

<p>This is to set the sample type for the data for a particular handler.
Shared sound can 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.


<H3>SharedSound_HandlerPause</H3>
<p>Not implemented in this version.

<p>This is to turn a particular handler on or off without having to
de-install it.

<H3>SharedSound_SampleRate</H3>

<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><STRONG>On entry</STRONG>
<pre>        R0 = &gt;0  handler number
             =  0 to set the rate for the current output driver
        R1 = sample frequency required
</pre>
<p><STRONG>On exit</STRONG>
<pre>        R1 = current sample frequency
        R2 = current sample period
        R3 = fractional step required to achieve this rate in 8.24 fixed point
</pre>
<p><STRONG>Interrupts</STRONG>
<pre>        Interrupts status is undefined
        Fast interrupt are enabled
</pre>
<p><STRONG>Processor mode</STRONG>
<pre>        Processor is in SVC mode
</pre>
<p><STRONG>Re-entrancy</STRONG>
<pre>        SWI is not reentrant
</pre>

<H3>SharedSound_InstallDriver</H3>                                       
<p>Not implemented in this version.

This is to allow other output devices to be installed.

<H3>SharedSound_RemoveDriver </H3>                                         
<p>Not implemented in this version.

<p>This is to allow other output devices to be installed.


<H3>SharedSound_DriverInfo</H3>                                            
<p>Not implemented in this version.

<p>This provides information for a particular driver.


<H3>SharedSound_DriverVolume</H3>                                          
<p>Not implemented in this version.

<p>This sets the volume for a driver.


<H3>SharedSound_DriverMixer</H3>                                           
<p>Not implemented in this version.

<p>This sets or reads the mixer values for a driver, where relevant.

<H3>SharedSound_CheckDriver</H3>  

<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><STRONG>On entry:</STRONG>
<pre>        none
</pre>
<p><STRONG>On exit:</STRONG>
<pre>        none
</pre>
<p><STRONG>Interrupts</STRONG>
<pre>        Interrupts status is undefined
        Fast interrupt are enabled
</pre>
<p><STRONG>Processor mode</STRONG>
<pre>        Processor is in SVC mode
</pre>
<p><STRONG>Re-entrancy</STRONG>
<pre>        SWI is not reentrant
</pre>
<H3>SharedSound_ControlWord</H3>

<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 "1 audible handler of many" support.

<p><STRONG>On entry:</STRONG>
<pre>        none
</pre>
<p><STRONG>On exit:</STRONG>
<pre>        R0 =    Pointer to  control word
</pre>
<p><STRONG>Interrupts</STRONG>
<pre>        Interrupts status is undefined
        Fast interrupt are enabled
</pre>
<p><STRONG>Processor mode</STRONG>
<pre>        Processor is in SVC mode
</pre>
<p><STRONG>Re-entrancy</STRONG>
<pre>        SWI is not reentrant
</pre>
<H3>SharedSound_HandlerType</H3>

<p>This is used to change the type of a handler from for example, an
immediate handler to a call back handler.

<p><STRONG>        On entry:</STRONG>
<pre>        R0 =    handler number
        R1 =    handler type (see Install handler for type number)
</pre>
<p><STRONG>On exit:</STRONG>
<pre>        none
</pre>
<p><STRONG>Interrupts</STRONG>
<pre>        Interrupts status is undefined
        Fast interrupt are enabled
</pre>
<p><STRONG>Processor mode</STRONG>
<pre>        Processor is in SVC mode
</pre>
<p><STRONG>Re-entrancy</STRONG>
<pre>        SWI is not reentrant
</pre>

<HR>

<H2> <A NAME="interchange"> 6.0 Data interchange </A> </H2>

N/A.

<HR>

<H2> <A NAME="formats"> 7.0 Data formats </A> </H2>

All data processed by the SharedSound module is in 16-bits/sample
linear format.  For stereo data, two samples are packed into one word,
with the default arrangement being that the left channel sample is in
the high order half-word (bits &lt;31:16&gt;) and the right channel sample
is in the low order half-word (bits &lt;15:0&gt;).  In some circumstances
this can be reversed (i.e. left in lower half, right in upper half),
as indicated by flags in the relevant API function interface.

<HR>

<H2> <A NAME="external"> 8.0 External dependencies </A> </H2>

N/A.
<HR>

<H2> <A NAME="acceptance"> 9.0 Acceptance test </A> </H2>

<p>The acceptance test must check that multiple simultaneous sound
sources can correctly function together.  


<HR>

<H2> <A NAME="noncompliances"> 10.0 Non compliances </A> </H2>

<p>Aside from those functions which are explicitly marked in the above
table as being "not implemented", there are no non-compliances.

<HR>

<H2> <a NAME="test"> 11.0 Development test strategy </A> </H2>

<p>Development testing is performed by interactive use of the
facilities of the module to verify correct functioning of the  
function of SharedSound to support multiple simultaneous sound
sources.


By using an EMBED tag, a particular piece of audio content (e.g. Wave,
MIDI) can be set up as a background sound which should continue to
play (without play controls available) either to its end or until the
browser leaves the page.  Any other audio object on the page should
also be playable (with codec controls available) while the background
sound is active.

<HR>

<H2> <A NAME="organisation"> 12.0 Product organisation </A> </H2>
<p>SharedSound is implemented as a standard NC OS relocatable module.

<HR>

<H2> <A NAME="enhancements"> 13.0 Future enhancements </A> </H2>

<p>Possible future enhancements include use of Call-Back-After-Interrupt
(CBAI) to improve timing precision, and filling out of the
implementation to include all functions listed in the API but which
are not currently implemented.

<HR>

<H2> <A NAME="glossary"> 14.0 Glossary </A> </H2>
<TABLE WIDTH="100%" BORDER=0>
<TR><TD WIDTH="20%">API	<TD WIDTH="80%">Application Programmer Interface.
<TR><TD>NC		<TD>Network Computer.
<TR><TD>MIDI		<TD>Musical Instrument Digital Interface.
<TR><TD>OS		<TD>Operating System.
<TR><TD>SWI		<TD>Software Interrupt.
<TR><TD>UI		<TD>User Interface.
</TABLE>
<HR>

<H2> <A NAME="references"> 15.0 References </A> </H2>

<A HREF="http://www.cybervillage.co.uk/acorn/esp/index.htm">ESP Web Site</a><br>
<A HREF="./sounddma.html">SoundDMA Software
Functional Specification (2107,749)</a><br>

<HR>

<H2> <A NAME="history"> 16.0 History </A> </H2>

<PRE>
$Log$
Revision 6.1  1997/08/11 19:41:33  srose
SECTION: header
CHANGE:  ECO 3997 allocated
REASON:  Sign off

Revision 5.1  1997/08/11 16:49:08  srose

SECTION: 15.0 References
CHANGE:  Corrected URL link to the sound dma specification
REASON:  Broken link
IMPACTS: None.

Revision 4.1  1997/08/11 16:45:59  srose

SECTION: header
CHANGE:  renamed project from NC100 to NC100 1.15
REASON:  to avoid confusion between NC100 1.15 and NC100 1.16
IMPACTS: none

Revision 3.1  1997/05/06 10:40:42  srose
AMR number allocated; internal sign off agreed.

Revision 2.8  1997/04/24 16:47:06  srose
HTML updates following weblint checks; automated history section; added
classification and confidential info to header section; had to redo some
updates from previous minutes because the last edited version wasn't the
one which got reviewed - I need to check this specification against all
previously agreed updates and restore what got deleted as necessary.

</PRE>

<HR>

<TABLE BORDER=1 WIDTH="100%">
<TR>
<TD WIDTH="50%" VALIGN=TOP>
<SMALL>
This document is issued under license and must not be copied, reproduced
or disclosed in part or whole outside the terms of the license.
</SMALL>
<TD WIDTH="50%" VALIGN=TOP>
<SMALL>
For NC Inc. by Acorn Network Computing, UK.<BR>
&copy; Acorn Computers Ltd 1997<BR>
</SMALL>
</TABLE>

</BODY>
</HTML>
