www.riscos.com Technical Support: |
|
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 -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.
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.
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.
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 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:
Other reason codes for Sound_SampleRate allow you to read and set the sample index, and hence the sample rate:
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:
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.
The new SoundDMA module also supports 8 bit -LAW SOUND. THE SOUND IS GENERATED IN THE SAME WAY AS BEFORE: THE 8 BIT CHANNEL HANDLER GENERATES -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 -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.
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:
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.
When the computer is configured for 16 bit sound, this call affects both 16 bit sound and the emulated 8 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.
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.
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 -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:
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 -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 |
R0 - R10 may be corrupted
R11, R12, R13 must be preserved
Interrupts may be enabled during execution of the handler
Handler may be called in either IRQ mode or SVC mode
Processor mode must be preserved on exit
SWI calls
Examines and controls the 16 bit sound system's configuration
R0 = reason code
Other registers depend on reason code
Registers depend on reason code
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
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 |
None
None
R0 = 0 (reason code)
R0 = sound system capabilities:
0 THE SOUND SYSTEM ONLY SUPPORTS 8 BIT -law sound; R1 is 0, and R2 preserved |
1 THE SOUND SYSTEM SUPPORTS 16 BIT SOUND_ AND ALSO 8 BIT -law sound by emulation; other registers as below |
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 |
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.
R0 = 1 (reason code)
R1 = new state of automatic linear 2× oversampling: 0 DISABLED_ 1 enabled
R0 preserved
R1 = previous state of automatic linear 2× oversampling: 0 DISABLED_ 1 enabled
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.
Examines and controls the 16 bit linear stereo sound handler
R0 = reason code
Other registers depend on reason code
R0 preserved
Other registers depend on reason code
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
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.
None
None
R0 = 0 (reason code)
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
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.
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
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
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.
R0 = reason code
Other registers depend on reason code
R0 preserved
Other registers depend on reason code
Interrupt status is undefined
Fast interrupts are enabled
Processor is in SVC mode
Not defined
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.
None
None
Reads the number of available sample rates
R0 = 0 (reason code)
R0 preserved
R1 = number of available sample rates, or nsr (see Sample rates)
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).
Reads the current sample rate index, and the corresponding sample rate
R0 = 1 (reason code)
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
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.
Reads the sample rate corresponding to a sample rate index
R0 = 2 (reason code)
R1 = sample rate index to be read, in the range 1 - nsr (see Sample rates)
R0, R1 preserved
R2 = sample rate corresponding to the given sample rate index, in units of 1/1024 Hz
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:
Sets the current sample rate index
R0 = 3 (reason code)
R1 = new sample rate index, in the range 1 - nsr (see Sample rates)
R0 preserved
R1 = previous sample rate index
R2 = previous sample rate, in units of 1/1024 Hz
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.
Sets the configured value for the type of sound hardware to use
8bit | standard 8 bit -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) |
*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.
*Configure SoundSystem 16bit oversampled