RISCOS.com

www.riscos.com Technical Support:
Programmer's Reference Manual

 

Sound


Introduction and Overview

From RISC OS 3.6 onwards the SoundDMA module has been extended to support 16 bit sound, as well as the 8 bit [MU]-law sound used by all earlier versions of RISC OS. This module is also supplied with the 16 bit Audio Card upgrade for the Risc PC.

Hardware

Machines using the new architecture all output sound using the VIDC20 video controller - whether it is a separate chip, or integrated into the ARM 7500 chip. VIDC20 provides two different types of sound output:

  • It provides 8 bit [MU]-law sound on 8 channels; this is fully backward compatible with the sound provided by VIDC1 under earlier versions of RISC OS.

    This is output as an analogue signal, via internal sound DACs (digital to analogue converters) - just as with VIDC1.

  • It also provides 16 bit linear stereo sound (ie CD-style).

    This is output as digital data, and requires an external DAC. The 16 bit Audio Card upgrade for the Risc PC provides such a DAC; one is fitted as standard to later designs of computer.

You may only use one of these types of sound output at a time; when 16 bit sound is fitted, the circuitry for 8 bit sound is disconnected or absent.

Configuration

The type of hardware fitted is set in CMOS RAM using the new command *Configure SoundSystem. The configured sound hardware must match the actual hardware present, or you will get no sound output, and may get other unpredictable results. This configuration is read only when the SoundDMA module is initialised; hence you cannot adjust the hardware configuration without also re-initialising the SoundDMA module.

Under RISC OS 3.5, the default configuration is for an 8 bit sound system (ie no external 16 bit DAC is fitted). Under RISC OS 3.6 the kernel can detect the presence of 16 bit sound hardware and sets the default configuration accordingly: for a 16 bit sound system if it detects the hardware, and for an 8 bit sound system otherwise.

Technical details

The way the new SoundDMA module works depends on which type of VIDC20 sound output it is configured to use: 8 bit or 16 bit. You can determine how the sound system is configured by calling the new SWI Sound_Mode 0.

8 bit sound output

When the new SoundDMA module uses VIDC20's 8 bit sound output, it works just as on earlier versions of RISC OS. The standard VIDC20 internal [MU]-law DACs are used, as with VIDC1 and earlier versions of RISC OS.

16 bit sound output

The new features of the SoundDMA module become available when it is using VIDC20's 16 bit sound output.

16 bit sound is generated by a linear handler, which places 16 bit linear stereo sound samples in the sound DMA buffer. The SoundDMA module is responsible for requesting the linear handler to fill the buffer, and for outputting the data from this buffer to the external 16 bit DAC.

As before, the maximum size of the sound DMA buffer is one page, which is 4 Kbytes under RISC OS 3.6. Thus the maximum number of 16 bit stereo samples in the buffer is 1K, since each stereo pair takes up 32 bits (ie 4 bytes).

Sample rates

Sample rates for the 16 bit sound system are set and stored using a sample rate index:

  • The sample rate index is an integer in the range 1 - nsr (the number of sample rates). As the index increases, so does the corresponding sample rate.

    You should not assume any particular value for nsr, nor any particular binding of index values to sample rates. Both may be affected by the sound hardware's configuration, and by future hardware or software developments.

For maximum portability and future compatibility, you should always fully determine the sample rates available from the sound system before using it:

  • You can find the value of nsr by calling Sound_SampleRate 0.
  • Once you have done this, you can then use Sound_SampleRate 2 to enumerate the available sample rates, or to find a match for a required sample rate.

Other reason codes for Sound_SampleRate allow you to read and set the sample index, and hence the sample rate:

  • You can read the current sample rate index, and the corresponding sample rate, by calling Sound_SampleRate 1.
  • You can set the current sample rate index by calling Sound_SampleRate 3.
Oversampling

Any digital sound system can generate an undesirable high-pitched noise that is correlated with the main signal; this is a by-product of the digital-to-analogue conversion process, and is more audible at lower sample rates. This high frequency image of the output analogue signal is sometimes inaccurately called the alias.

This effect can be reduced by a technique called oversampling. Extra samples are added between existing samples (typically by interpolation); the new sample is then played back at a higher rate, thus making the image noise less audible. A side effect can be a slight reduction in amplitude of higher frequencies; however in most cases this slight loss of 'treble' is outweighed in subjective terms by the benefit of reduced image noise level

You can make the RISC OS 16 bit sound system automatically use oversampling at all sample rates up to and including 25kHz:

  • You can configure your preference using *Configure SoundSystem
  • Applications can enable or disable oversampling, overriding the configured preference, by calling the new SWI Sound_Mode 1.

The output data stream is oversampled by a factor of two, by simple linear interpolation, before it reaches the DACs. This 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.

Note that when you are using oversampling the maximum number of samples a linear handler can place in the sound DMA buffer is halved to 512, so there is room for the extra interpolated samples.

Support for 8 bit sound

The new SoundDMA module also supports 8 bit [MU]-LAW SOUND. THE SOUND IS GENERATED IN THE SAME WAY AS BEFORE: THE 8 BIT CHANNEL HANDLER GENERATES [MU]-LAW DATA WHICH IT PLACES IN THE SOUND DMA BUFFER. (FOR FULL DETAILS SEE The Sound system.) The SoundDMA module converts this data from multiple channels in 8 bit [MU]-LAW FORMAT TO TWO STEREO CHANNELS IN 16 BIT LINEAR FORMAT. IT THEN CALLS THE LINEAR HANDLER (IF ANY) TO FILL THE DMA BUFFER WITH ITS OWN SOUND DATA; THE LINEAR HANDLER CAN EITHER OVERWRITE THE CONVERTED 8 BIT SOUND DATA ALREADY IN THE BUFFER_ OR CAN MERGE IT WITH ITS OWN SOUND DATA. ALL LINEAR HANDLERS SHOULD ALLOW THE USER TO CONFIGURE THEIR PREFERENCE FOR THIS.

Restrictions of the 8 bit emulation

This conversion of 8 bit sound to 16 bit sound is transparent, and in general no difference from the old 8 bit sound system will be apparent. However:

  • Although the 16 bit sound system provides many of the sample periods possible under the old 8 bit sound system - including the default period of 48[MU]s used by the standard voice generators and many applications - there are a few less commonly used periods for which it can only provide a close match.
  • The 8 bit samples must fit within the sound DMA buffer when they are converted to 16 bit stereo sound, and hence must total less than a page in size. This means that the number of 8 bit samples is limited to 1K without oversampling, or 512 with oversampling. Again, this is not a problem with the 8 bit default of 208 samples per channel.

Changes to existing SWIs

Sound_Configure

When the computer is configured for 16 bit sound, this call affects both 16 bit sound and the emulated 8 bit sound:

  • R0 gives the number of channels for 8 bit sound, just the same as ever. It is ignored by the 16 bit sound system, which always has two channels (the left and right stereo pair).
  • R1 was originally defined as the 'sample length (in bytes per channel)'. You should now think of R1 as giving 'the number of samples per channel' for both 8 and 16 bit sound. The two definitions are effectively the same for 8 bit sound, but the new definition also covers 16 bit sound.
  • R2 sets the sample period for both 8 bit and 16 bit sound. However, the new SWI Sound_SampleRate is the preferred way to control sample rates for 16 bit sound.

When you have 16 bit sound configured, the values of R0 and R1 must be such that 8 bit, converted 8 bit and 16 bit sound data can all fit within a page, which is the maximum size of the sound DMA buffer. If not, the number of samples is set to the highest value for which all three types of data will fit. Also, not all sample periods can be provided; in such cases the sample period is set to the closest match. As always, you can check the number of samples and sample period actually set by calling Sound_Configure with null parameters.

Linear handlers

Registering linear handlers

A linear handler registers itself with SoundDMA by calling the new SWI Sound_LinearHandler 1. When registering, you give the address of the handler code - which is called to fill the sound DMA buffer - and a parameter passed to the handler in R0. Typically the parameter will be a pointer to a data area containing any information the handler may need to perform its task. The address and parameter of the previous linear handler (if any) are returned.

Only one linear handler can be registered with the SoundDMA module. You should therefore only register your linear handler immediately before starting to play sound, and should re-register the previous handler as soon as you have finished.

You can find which linear handler is currently registered by calling Sound_LinearHandler 0.

How linear handlers are called

The handler is passed the address of the sound DMA buffer for it to fill with 16 bit linear stereo sound data. Each sample is stored in a word as a pair of signed (2's complement) 16 bit values, with the right channel data in bits 0 - 15, and the left channel data in bits 16 - 31. A flag indicates if the buffer already contains sound data converted from multiple channels in 8 bit [MU]-LAW FORMAT; SEE Support for 8 bit sound for more details of the action the linear handler should take in this case.

The full conditions for entry and exit are as follows:

On entry

R0 = parameter passed in R2 to Sound_LinearHandler 1 when registering
R1 = pointer to quadword-aligned sound DMA buffer
R2 = pointer to word immediately after sound DMA buffer
R3 = flags:

bits 0 - 2 initial buffer content indicator:
0 data in buffer is invalid and must be overwritten
1 data in buffer has been converted from multiple channels in 8 bit [MU]-law format, and is not all 0.
2 data in buffer is all 0: if handler would generate silent output, it may simply return.
3 - 7 reserved
bits 8 - 31 reserved, and should be ignored
R4 = sample rate for playback, measured in units of 1/1024 Hz; for example 20 kHz (20000 Hz) would be passed as 20000 × 1024, which is 20480000

On exit

R0 - R10 may be corrupted
R11, R12, R13 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
Processor mode must be preserved on exit

SWI calls


Sound_Mode
(SWI &40144)

Examines and controls the 16 bit sound system's configuration

On entry

R0 = reason code
Other registers depend on reason code

On exit

Registers depend on reason code

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This call examines and controls the 16 bit sound system's configuration.

The particular action of Sound_Mode is given by the reason code in R0 as follows:

R0 Action Page
0 Reads the current sound system configuration Sound_Mode 0
1 Enables or disables automatic oversampling Sound_Mode 1
Related SWIs

None

Related vectors

None


Sound_Mode 0
(SWI &40144)

Reads the current sound system configuration

On entry

R0 = 0 (reason code)

On exit

R0 = sound system capabilities:

0 => THE SOUND SYSTEM ONLY SUPPORTS 8 BIT [MU]-law sound; R1 is 0, and R2 preserved
1 => THE SOUND SYSTEM SUPPORTS 16 BIT SOUND_ AND ALSO 8 BIT [MU]-law sound by emulation; other registers as below
R1 = the configuration stored in SoundSystem bits at offset 132 of CMOS RAM allocation:
bits 0 - 1 16 bit sound control configuration, from bits 5 - 6
bits 2 - 3 reserved
bit 4 16 bit sound quality configuration, from bit 7
bits 5 - 31 reserved
Use

This call reads the current sound system configuration. Any new sound applications you write - particularly those capable of 16 bit sound output - should always call this SWI to determine whether the configured sound output hardware supports 16 bit sound output.

  • If the configured hardware does not support 16 bit sound output, R0 is 0 on return. You should only use the original sound system SWIs - in particular Sound_Configure - to determine and control sound output parameters such as sampling rate. Other Sound_Mode reason codes are not available, nor are SWIs in the range &40145 - &4017F inclusive. The sound system will behave in a fully backward compatible manner.
  • If the configured hardware does support 16 bit sound output, R0 is 1 on return. You can use all Sound_Mode reason codes, and the Sound_LinearHandler and Sound_SampleRate SWIs. R1 gives an indication of any external sound clock hardware facilities present, and the configured state of automatic oversampling. A subset of the original sound system's sample rates are available; see Restrictions of the 8 bit emulation.

Sound_Mode 1
(SWI &40144)

Enables or disables automatic oversampling

On entry

R0 = 1 (reason code)
R1 = new state of automatic linear 2× oversampling: 0 => DISABLED_ 1 => enabled

On exit

R0 preserved
R1 = previous state of automatic linear 2× oversampling: 0 => DISABLED_ 1 => enabled

Use

This call enables or disables automatic linear 2× oversampling, overriding the default set in CMOS RAM by *Configure SoundSystem.

For a description of oversampling, see Oversampling.


Sound_LinearHandler
(SWI &40145)

Examines and controls the 16 bit linear stereo sound handler

On entry

R0 = reason code
Other registers depend on reason code

On exit

R0 preserved
Other registers depend on reason code

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This call examines and controls the 16 bit linear stereo sound handler.

The particular action of Sound_LinearHandler is given by the reason code in R0 as follows:

R0 Action Page
0 Returns the current 16 bit linear stereo sound handler Sound_LinearHandler 0
1 Registers or removes the 16 bit linear stereo sound handler Sound_LinearHandler 1

You must not use this call unless 16 bit sound hardware is configured, as determined by a preceding call of Sound_Mode 0.

Related SWIs

None

Related vectors

None


Sound_LinearHandler 0
(SWI &40145)

Returns the current 16 bit linear stereo sound handler

On entry

R0 = 0 (reason code)

On exit

R0 preserved
R1 = pointer to current handler code, or 0 if no handler is installed
R2 = parameter passed in R0 to current handler, or -1 if no handler is installed

Use

This call returns the current 16 bit linear stereo sound handler, giving the address of the handler code, and the parameter passed to it in R0.


Sound_LinearHandler 1
(SWI &40145)

Registers or removes the 16 bit linear stereo sound handler

On entry

R0 = 1 (reason code)
R1 = pointer to new handler code, or 0 to remove the handler
R2 = parameter passed in R0 to handler, or -1 if removing the handler

On exit

R0 preserved
R1 = pointer to previous handler code, or 0 if no handler was installed
R2 = parameter passed in R0 to previous handler, or -1 if no handler was installed

Use

This call registers or removes the 16 bit linear stereo sound handler. When registering, you give the address of the handler code - which is called to fill the sound DMA buffer - and a parameter passed to the handler in R0. The address and parameter of the previous linear handler (if any) are returned.

Only one linear handler can be registered with the SoundDMA module. You should therefore only register your linear handler immediately before starting to play sound, and should re-register the previous handler as soon as you have finished.


Sound_SampleRate
(SWI &40146)

Determine/control sound sample rate

On entry

R0 = reason code
Other registers depend on reason code

On exit

R0 preserved
Other registers depend on reason code

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This call controls the sound sample rate.

The particular action of Sound_SampleRate is given by the reason code in R0 as follows:

R0 Meaning Page
0 Reads the number of available sample rates Sound_SampleRate 0
1 Reads the current sample rate index, and the corresponding sample rate Sound_SampleRate 1
2 Reads the sample rate corresponding to a sample rate index Sound_SampleRate 2
3 Sets the current sample rate index Sound_SampleRate 3

You must not use this call unless 16 bit sound hardware is configured, as determined by a preceding call of Sound_Mode 0.

Related SWIs

None

Related vectors

None


Sound_SampleRate 0
(SWI &40146)

Reads the number of available sample rates

On entry

R0 = 0 (reason code)

On exit

R0 preserved
R1 = number of available sample rates, or nsr (see Sample rates)

Use

This call reads the number of available sample rates, or nsr.

You need to know this value to ensure that the sample rate index you must pass to most other Sound_SampleRate reason codes is in the required range 1 - nsr (see Sample rates).


Sound_SampleRate 1
(SWI &40146)

Reads the current sample rate index, and the corresponding sample rate

On entry

R0 = 1 (reason code)

On exit

R0 preserved
R1 = current sample rate index, in the range 1 - nsr (see Sample rates)
R2 = current sample rate, in units of 1/1024 Hz

Use

This call reads the current sample rate index, and the corresponding sample rate, measured in units of 1/1024 Hz. For example a sample rate of 20 kHz (20000 Hz) would be returned in R2 as 20000 × 1024, which is 20480000.


Sound_SampleRate 2
(SWI &40146)

Reads the sample rate corresponding to a sample rate index

On entry

R0 = 2 (reason code)
R1 = sample rate index to be read, in the range 1 - nsr (see Sample rates)

On exit

R0, R1 preserved
R2 = sample rate corresponding to the given sample rate index, in units of 1/1024 Hz

Use

This call reads the sample rate corresponding to a sample rate index, in units of 1/1024 Hz. For example a sample rate of 20 kHz (20000 Hz) would be returned in R2 as 20000 × 1024, which is 20480000.

Once you have called Sound_SampleRate 0 to find the number of available sample rates (nsr), you can then:

  • Enumerate the available sample rates by repeatedly making this call with R1 set to all valid indexes (ie 1 - nsr inclusive).
  • Find a particular sample rate (or the closest approximation, if acceptable) by using this call in a 'binary chop' algorithm, since sample rates increase monotonically with increasing sample rate index.

Sound_SampleRate 3
(SWI &40146)

Sets the current sample rate index

On entry

R0 = 3 (reason code)
R1 = new sample rate index, in the range 1 - nsr (see Sample rates)

On exit

R0 preserved
R1 = previous sample rate index
R2 = previous sample rate, in units of 1/1024 Hz

Use

This call sets the current sample rate index.

It returns the previous sample rate index, and the corresponding sample rate measured in units of 1/1024 Hz. For example a sample rate of 20 kHz (20000 Hz) would be returned in R2 as 20000 × 1024, which is 20480000.

* Commands


*Configure SoundSystem

Sets the configured value for the type of sound hardware to use

Syntax
*Configure SoundSystem 8bit | 16bit [oversampled] | n
Parameters
8bit standard 8 bit [MU]-law sound, as on older hardware
16bit standard 16 bit sound, as on newer hardware or Acorn 16 bit Audio Card
oversampled perform sample interpolation to keep sample rate over 24kHz
n value 0 - 7 to store in SoundSystem bits of CMOS RAM (at offset 132, bits 5 - 7: see CMOS RAM allocation)
Use

*Configure SoundSystem sets the configured value for the type of sound hardware to use, and whether to use oversampling for 16 bit sound.

For a description of oversampling, see Oversampling.

Example

*Configure SoundSystem 16bit oversampled

Related commands

None

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015