16-Bit Stereo Sound Support for RISC OS
=======================================


The Risc PC uses the VIDC20 video controller to provide both video and sound
output facilities.  As standard, the VIDC20's internal sound DACs are used to
implement 8-channel stereo sound, using the 8-bit mu-law format to give wide
dynamic range; this is fully backwards compatible with the sound system
provided on earlier Acorn 32-bit RISC computers.  But VIDC20 also supports a
digital sound output interface, allowing for full 16-bit linear (CD-style)
stereo sound output, when used in conjunction with a suitable sound hardware
upgrade.  Only one of these sound output mechanisms may be used at one time.

To support 16-bit sound output, a revised version of the RISC OS SoundDMA
system software module has been produced.  This module continues to support
the original mu-law format, both as normal on an unexpanded Risc PC, and
also by software emulation, with output through the 16-bit sound hardware,
when the 16-bit sound upgrade has been installed; selection of the relevant
modes of operation is by means of new bits in the computer's CMOS RAM.

This document describes the facilities provided by the new SoundDMA module
(version 1.37 or later), to support sound output through 16-bit linear stereo
sound hardware.


Software emulation of mu-law sound
----------------------------------

The SoundDMA module now supports the output of 8-bit mu-law format
sound data in either of two different modes.  If the CMOS RAM
configuration indicates that the computer does not have 16-bit sound
output hardware, then the standard VIDC20 internal mu-law DACs will be
used, as before.  However if 16-bit sound output hardware is fitted,
and this is reflected in the CMOS RAM configuration, then all sound
output (originated in both mu-law and 16-bit linear formats) will be
performed through the 16-bit sound path and not through the VIDC20
mu-law DACs.  This is because the standard 16-bit sound upgrade
disconnects the analogue sound output coming from VIDC20, taking the
sound fed to the headphone socket and the internal speaker only from
the 16-bit DAC outputs; this maximises the sound quality achieved, but
requires that software emulation be performed to support mu-law sound,
for compatibility.

Mu-law format emulation is done transparently (albeit at a small
additional cost in processor time over direct hardware mu-law output),
and in general no difference from the standard sound system will be
apparent.  However one point in particular - sample rate support -
needs to be considered.  Most applications using mu-law format sound
produce it at the system default sampling rate of 20.83kHz (48
microsecond sample period), and indeed many applications can only use
this rate - all the standard voice generators assume it.  However a
few applications may choose to use other sample rates.  The software
emulation does provide for a wide range of the sample rates available
with the standard sound system, but not all of them.  In those cases
where the exact sample period (in microseconds) requested by means of
the Sound_Configure SWI is not available, a nearby sample period value
will be used instead.  If exact sample rate is important, an
application which uses the Sound_Configure SWI to set a particular
rate can perform a second call of the SWI, with all input registers
set to 0, and check that the current period value, returned in R2, is
as required.  It should be noted that this method is only applicable
for programs which produce mu-law sound using the standard sound
system interfaces.  Programs producing 16-bit linear sound should use
the new SWI calls documented below for all functions, including
setting the sample rate.


New Sound system SWI calls
--------------------------

Three new SWIs are implemented to support 16-bit sound.  They are:

  Sound_Mode

        allows an application to determine sound system configuration,
        including an indication of whether 16-bit sound output is available
        (i.e. a 16-bit sound hardware upgrade is configured).  It is also
        used to switch oversampling on or off.  Oversampling is a method of
        software filtering on generated sound data, to improve its perceived
        quality, especially at lower sample rates.

  Sound_LinearHandler

        provides for the installation of a 16-bit capable sound output
        handler, to generate 16-bit sound data for direct output, or mix it
        with converted mu-law data generated under the original sound system.

  Sound_SampleRate

        gives control, in a flexible and portable manner, over the selected
        sound output sample rate.

These SWIs are described on the following pages.



Sound_Mode (SWI &40144)
-----------------------

        Examine/control sound system configuration (16-bit sound)
        
On entry:

        R0 = function code
        R1 = parameter as required for function

On exit:

        Registers set as determined by function code

Use:
        New sound applications, particularly those capable of 16-bit sound
        output, should always use this SWI first, with function code 0, in
        order to identify the current configuration of the internal sound
        system.  If an older version of the SoundDMA module (prior to 1.37) is
        currently installed, it will appear as a system implementing only the
        original mu-law sound output facility.  Function code 1 allows the
        automatic oversampling facility to be controlled.  

        The new CMOS RAM bits defined below are read only when the SoundDMA
        module is initialised; hence any adjustment of hardware configuration
        cannot be performed without also re-initialising the SoundDMA module.
        However automatic oversampling may be selected dynamically; on
        initialisation it defaults to the value defined in CMOS RAM.



Sound_Mode 0 (SWI &40144)
-------------------------

        Read current sound system configuration

On entry:

        R0 = 0 (function code)

On exit:

        R0 = 0: sound system supports original (mu-law) sound only; SWIs
                Sound_LinearHandler and Sound_SampleRate, and all other
                functions of Sound_Mode, are not supported.
        R0 = 1: sound system is 16-bit capable (and supports mu-law sound
                output by emulation): the SWI calls Sound_LinearHandler and
                Sound_SampleRate, and full Sound_Mode functionality are all
                available.

        R1 is affected differently in different cases.  For versions of the
                SoundDMA module before 1.37, R1 will be unaltered (and R0 will
                be 0).  Otherwise, if R0 on return is 0, R1 will also be set
                to 0; if R0 is 1 on exit, R1 indicates the current sound
                system configuration, as below:

                bits 3 - 0 = sound format/clock control, as read from
                             CMOS RAM at initialisation of SoundDMA module:
                        0 - never returned
                        1 - 16-bit output; sample rates 44.1 kHz, 22.05 kHz,
                            11.025 kHz, and selected original mu-law system
                            compatible sample rates are available
                        2 - 16-bit output; selected original mu-law system
                            compatible sample rates only
                        3..15 - reserved values, not yet defined
                bit 4 = oversampling control:
                        0 - automatic linear 2x oversampling is disabled
                        1 - automatic linear 2x oversampling is enabled
                bits 31 - 5 = reserved for expansion, undefined

Interrupts:

        Interrupt status is undefined
        Fast interrupts are enabled

Processor mode:

        Processor is in SVC mode

Re-entrancy:

        Not defined

Use:

        This SWI call should always be used before attempting to access any of
        the other functionality introduced in support of 16-bit sound output.
        It allows an application to determine whether 16-bit sound output is
        supported by the configured sound output hardware.

        If 16-bit hardware has been configured, indication is given of any
        external sound clock hardware facilities present (a separate oscillator
        is required to support CD-rate (44.1kHz) or other sample rates) and the
        current state of the automatic oversampling flag is also returned in
        R2, for convenience.  A subset of the original sound system's sample
        rates will be available - see the description of Sound_SampleRate for
        more information.

        If 16-bit sound output is not configured in CMOS RAM, R0 will be 0 on
        return, and only the original sound system SWIs, in particular
        Sound_Configure, should be used to determine and control sound output
        parameters such as sampling rate; the sound system will behave in a
        fully backwards compatible manner.



Sound_Mode 1 (SWI &40144)
-------------------------

        Enable or disable automatic oversampling

On entry:

        R0 = 1 (function code)
        R1 = new state:
                0 - disable linear 2x oversampling
                1 - enable linear 2x oversampling 
                other values - do not use

On exit:

        R0 preserved
        R1 = old state of automatic oversampling
                0 - was previously disabled
                1 - was previously enabled

Interrupts:

        Interrupt status is undefined
        Fast interrupts are enabled

Processor mode:

        Processor is in SVC mode

Re-entrancy:

        Not defined

Use:

        This SWI allows automatic oversampling to be used, when 16-bit sound
        output hardware is fitted, to improve the output sound quality at lower
        sample rates.  If automatic oversampling is enabled, then at all sample
        rates up to and including 25kHz, the output data stream will be
        oversampled by a factor of 2, by simple linear interpolation, before it
        reaches the digital-to-analogue converters.  This reduces the audible
        level of the undesirable high frequency image (sometimes inaccurately
        called the `alias') of the sound output signal which is sent to the
        loudspeaker or headphones.  The image signal appears in the analogue
        audio output as a high-pitched noise correlated with the main signal;
        it is a by-product of the digital-to-analogue conversion process, and
        is generally audible only with lower sample rates.  As a side effect of
        the oversampling process, higher frequencies within the sound output
        signal are slightly reduced in amplitude; however in most cases this
        slight loss of `treble' is outweighed in subjective terms by the
        benefit of reduced image noise level.

Note:

        Oversampling when active consumes a small amount of processor time on
        each sound system interrupt, at worst approximately 3% of a 30 MHz
        ARM610 processor with a selected sample rate of 25 KHz.



Sound_LinearHandler (SWI &40145)
--------------------------------

        Declare the 16-bit linear stereo sound handler

On entry:

        R0 = function code:
                0 - return current handler
                1 - install new handler
        R1 = new handler code address (if R0 = 1), or 0 to remove the handler
        R2 = new handler parameter    (if R0 = 1)

On exit:

        R0 preserved
        R1 = current/previous handler code address, or 0 if no handler is/was
             installed
        R2 = current/previous handler parameter, or -1 if no handler is/was 
             installed

Interrupts:

        Interrupt status is undefined
        Fast interrupts are enabled

Processor mode:

        Processor is in SVC mode

Re-entrancy:

        Not defined

Use:

        The 16-bit sound handler is specified as two 32-bit quantities, a code
        address, to which control will pass when more data is required, and a
        parameter which will be passed to the handler in R0 as it is called.
        Typically the parameter will be a pointer to a data area containing any
        information the handler may need to perform its task.  If no handler is
        installed, the code address is specified as 0.

        This SWI must not be used unless 16-bit sound output is configured, as
        determined by a preceding call of Sound_Mode 0.

        The handler is passed the address of a buffer to fill with 16-bit
        linear stereo sound data.  The data in the buffer may already have been
        produced by conversion from mu-law multi-channel data generated in
        compatibility mode via the original sound system interfaces.  In this
        case (as indicated by the flags in R3 on the call), the handler may
        either overwrite the data or else mix its own data with it, as selected
        by a user-configurable option supported by the handler.

        The handler will be called under the following conditions:

        On entry:

              R0 = parameter value as specified on installation
              R1 = base of quadword-aligned buffer, to fill with 16-bit stereo
                   data, stored as pairs of signed (2's complement) 16-bit
                   values; each word has bits 31-16 left channel data, bits
                   15-0 right channel data.
              R2 = end of buffer (address of first word beyond buffer)
              R3 = flags:
                    bits 2 - 0: initial buffer content indicator:
                      0 - data in buffer is invalid and must be overwritten
                      1 - data has been converted from N-channel mu-law sound
                          system, and is not all 0.  It may be either
                          overwritten, or mixed with new data produced by the
                          handler, at the handler's option.  Handlers should in
                          general be user-configurable in respect of this
                          behaviour.
                      2 - data in buffer is all 0: if handler would generate
                          silent output, it may simply return.
                      3..7 - reserved values
                   bits 31 - 3: not yet defined - ignore
              R4 = sample frequency at which data will be played, in units of
                   1/1024 Hz (e.g. for 20kHz, R4 would be 20000*1024 =
                   20480000).

        On exit:

                R0-R10 may be corrupted
                R11,R12,R13 must be preserved
                Processor mode must be preserved
        
        Interrupts:

                Interrupts may be enabled during execution of the handler

        Processor mode:

                Handler may be called in either IRQ mode or SVC mode.

Notes: 

        The size of the buffer passed to the handler is as determined by the
        Sound_Configure SWI, and is independent of the number of channels of
        mu-law sound configured.  R1 as passed in to/out of Sound_Configure
        indicates how many sample-times the data in the buffer represents.
        Since with 16-bit linear stereo sound, the size of the data per
        sample-time is fixed at 32 bits, the size of the buffer is then just
        that number of words.  This is different from the case with
        multi-channel mu-law sound, where the buffer size passed to the channel
        handler is a function of how many channels are active.

        The linear sound handler is called to generate 16-bit stereo data
        before any oversampling is performed.  The value passed in R4 will
        therefore be the same as would be returned by Sound_SampleRate 1.



Sound_SampleRate (SWI &40146)
-----------------------------

        Determine/control sound sample rate

On entry:

        R0 = function code:
                0 - read number of sample rates, NSR
                1 - read current sample rate index and value
                2 - convert sample rate index to sample rate value
                3 - set sample rate by index
        R1 = parameter if required by function code

On exit:

        R0 preserved
        R1, R2 = results as determined by function code


Interrupts:  (for all function codes)

        Interrupt status is undefined
        Fast interrupts are enabled

Processor mode: (for all function codes)

        Processor is in SVC mode

Re-entrancy:  (for all function codes)

        Not defined

Use:
        See individual function code descriptions for further details.

        This SWI must not be used unless 16-bit sound output is configured, as
        determined by a preceding call of Sound_Mode 0.



Sound_SampleRate 0 (SWI &40146)
-------------------------------

        Read number of available sample rates, NSR

On entry:
        R0 = 0 (function code)

On exit:
        R0 preserved
        R1 = total number of available sample rates, NSR.
        R2 preserved

Use:
        Available sample rates are indexed by numbers in the range 1..NSR, and
        increase with increasing index number.  The number of available sample
        rates, and the assignment of index values to specific sample rates, is
        affected by the sound output hardware configuration.  Therefore this
        function code should in general be used before any manipulation of
        sample rates is performed; in particular, the SWIs Sound_SampleRate 2
        and Sound_SampleRate 3 require that their respective parameters be in
        the range 1..NSR.

Notes:
        Future hardware or software developments might result in a change in
        the value of NSR for any given hardware configuration. For maximum
        portability and compatibility with possible future enhancements, sound
        applications should always fully determine the working configuration of
        the sound system before using it, and should not assume any particular
        value for NSR, or any particular binding of sample rates to index
        values (see Sound_SampleRate 2 and 3).



Sound_SampleRate 1 (SWI &40146)
-------------------------------

        Read current sample rate

On entry:

        R0 = 1 (function code)

On exit:

        R0 preserved
        R1 = index of current sample rate
        R2 = current sample rate value


Use:

        This call reads the current sample rate index; for convenience, the
        current sample rate value is also returned.  The sample rate index is
        an integer in the range 1..NSR (as determined by Sound_SampleRate 0).
        The sample rate value is measured in units of 1/1024 Hz.  Hence, e.g.
        20kHz (20,000 Hz) would be reported as 20000*1024 = 20480000.



Sound_SampleRate 2 (SWI &40146)
-------------------------------

        Convert sample rate index to sample rate value

On entry:

        R0 = 2 (function code)
        R1 = sample rate index to be converted, in range 1..NSR

On exit:

        R0 preserved
        R1 preserved
        R2 = sample rate value corresponding to given index

Use:

        This call allows the set of available sample rates to be determined, by
        repeated use of the SWI with varying values of R1.  By setting R1
        successively to all values in the range 1..NSR, the full set of rates
        may be discovered; alternatively, if some particular sample rate is
        required, a "binary chop" algorithm may be used to reduce the cost of
        finding it (or the closest available rate, if an approximation is
        acceptable), since sample rates increase monotonically with increasing
        sample rate index.
        
        As usual, the returned sample rate value is measured in units of 1/1024
        Hz.

Notes:
        The mapping of index numbers to sample rates is fixed for any given
        hardware & software configuration (i.e. with a particular set of
        versions of the sound system modules, and a particular sound system
        configuration setting in CMOS RAM) but is not guaranteed to remain
        constant over future hardware or software changes.



Sound_SampleRate 3 (SWI &40146)
-------------------------------

        Select sound sample rate 

On entry:

        R0 = 3 (function code)
        R1 = new sample rate index, in range 1..NSR

On exit:

        R0 preserved
        R1 = previous sample rate index
        R2 = previous sample rate value

Use:    

        This SWI is provided to select a new sample rate by means of the index
        given in R1 on call.  This must be in the range 1..NSR.  The previous
        values of sample rate index and associated value are returned in R1 and
        R2 respectively.

Notes:

        Never assume a given index corresponds to a particular sample rate
        value; check first using Sound_SampleRate 2.

        For information only (and NOT to be assumed in any code), the following
        rates are available in the initial version of the SoundDMA module
        supporting 16-bit sound, when 16-bit output hardware is configured.
        Rates marked with * are only available if the 16-bit sound hardware
        includes an oscillator providing an 11.2896 MHz signal for input to
        VIDC20's sclk pin; this is indicated by value 1 in the CMOS sound
        control configuration bits (see below).  Period values quoted for these
        rates are approximate, and are used for compatibility via the original
        Sound_Configure interface, in which sample rates are specified in terms
        of the sample period, measured in units of whole microseconds.

        Frequency (kHz)   Period (microseconds)
        -----------------------------------
          5.0                200
          6.25               160
          6.944              144
          7.812              128
          8.928              112
         10.417               96
        *11.025               91
         11.364               88
         12.5                 80
         13.889               72
         15.625               64
         17.857               56
         20.833               48
        *22.05                45
         25.0                 40
         27.778               36
         31.25                32
         35.714               28
         41.667               24
        *44.1                 23
         50.0                 20



New CMOS RAM sound configuration options
----------------------------------------

Three CMOS RAM bits have been allocated to hold new sound hardware and software
configuration options, particularly in support of the 16-bit output facilities.
They are defined below.

CMOS RAM address: &84

Bit assignments:

  Bits 4-0 = other un-related functions, must be preserved
  Bits 6-5 = 16-Bit sound control, on VIDC20-based machines including Risc PC.
                0 - no 16-bit sound output, use standard mu-law (default)
                1 - DAC clock is slave: 11.2896MHz external clock: selected
                    standard VIDC20 rates or 44.1 KHz/{1,2,4} can be used
                2 - DAC clock is slave: no external clock: selected standard
                    VIDC20 rates only
                3 - reserved
  Bit 7 = automatic interpolation flag
                0 - do not automatically interpolate
                1 - automatically interpolate at sample rates <= 25 kHz, to
                    improve sound output quality.

The setting of bits 6-5 must be 0, on a machine without 16-bit sound hardware
fitted, or 1 for the standard Acorn 16-bit sound upgrade.

Bit 7 may be configured as required - refer to the description of oversampling
under SWI Sound_Mode 1; note that it is only effective when 16-bit sound output
hardware is fitted; it is ignored otherwise.


