SoundCtrl Module Functional Specification ***************************************** -------------------------------------------------------------------------------- Distribution: Under NDA Document ref: 1309,202/FS Project: Ursula Revision: 0.04 Date: 06-Nov-1997 Author: XXXX Issue: 1d *** SUBJECT TO CHANGE WITHOUT NOTICE *** -------------------------------------------------------------------------------- Contents ======== 1.0 Overview. 2.0 Technical background. 3.0 User interface. 4.0 Programmer interface. 5.0 Data formats. 6.0 Glossary. -------------------------------------------------------------------------------- 1.0 Overview ============ SoundCtrl is a module which allows the programmer to control mixing and sampling in the Phoebe sound system. -------------------------------------------------------------------------------- 2.0 Technical background ======================== It is assumed in this document that Phoebe will be delivering new sound system capabilities via the Analog Devices' AD1816A SoundPort Controller. This device provides SoundBlaster Pro compatibility and a variety of other features including audio channels controlled via its own 'Sound System' interface a la Windows Sound System interface (one of the older Microsoft 'standards'). The features assumed for Phoebe are as follows:- * SoundBlaster Pro / Adlib compatible register set. * OPL-3 FM synthesiser. * MPU-401 MIDI interface (used by MIDI module). * A line input channel (analogue stereo). * A CD input channel (analogue stereo). * A Microphone in channel (analogue mono). * Two I2S serial buses (digital stereo): bus 0 dedicated to VIDCs audio output; bus 1 dedicated to the wavetable synthesiser. * A stereo DAC with variable sampling for playback. * A stereo mixer with mute or variable gain on each input channel (above). * A stereo ADC with variable sampling and gain from a choice of sources. * A Game Port (used by Joystick module). Because of the limited hardware resources on the chip, the SoundBlaster DAC and ADC cannot be used at the same time as the Playback and Capture channels below. If a programmer wishes to use these features of the SoundBlaster by directly addressing the hardware for, say, a game, then these SoundBlaster resources must first be claimed using the SoundCtrl_Claim SWI. In this document the FM sythesiser is an internal OPL3 compatible device. Unqualified references to synthesisers (or synth) should be taken to refer to an external wavetable generator. -------------------------------------------------------------------------------- 3.0 User interface ================== This software component will have no user interface. -------------------------------------------------------------------------------- 4.0 Programmer interface ======================== 4.1 SWIs -------- All registers are preserved unless otherwise stated. Error numbers are given as an offset from the error base (0x813100). Any reserved bit, byte or word must be filled with zeroes unless stated otherwise. 4.1.1 SoundCtrl_Claim 0x50000 ~~~~~~~~~~~~~~~~~~~~~ On entry: R0 = flags, currently reserved R1 = resource number to claim: 0 - Soundblaster (DAC, ADC, FMSynth, timer and mixer: SoundCtrl virtually disabled) 1 - Adlib/FMSynth 2 - MPU 401 MIDI 3 - game port 4 - playback channel 5 - capture channel 6 - timer 7 - the mixer R2 = access key or 0 to check if already claimed On exit: R0 = 0 - claim unsuccesful, already claimed = 1 - claim successful, not claimed for exclusive use This call registers the holder of the access key as having exclusive right to the resource in question. The access key will be needed for any action which changes the state of that resource. An attempt to claim a resource with the current key will be treayed as a successful claim. As soon as any resource is no longer in use it must be freed using SoundCtrl_Release. Once the playback or capture channel has been claimed, the SoundBlaster DAC & ADC can no longer be claimed. Equally if the SoundBlaster DAC & ADC is claimed, neither the playback nor the capture channel can be claimed. The mixer must be claimed if either the SWI interface to the mixer (SoundCtrl_SetVolume with all but ADC channels) or the SoundBlaster mixer is required. NB: In typical operation the MIDI module will claim the MIDI device and the Joystick module will claim the Game Port. This SWI can return the following error: +3 - Sound Control resource not recognised 4.1.2 SoundCtrl_Release 0x50003 ~~~~~~~~~~~~~~~~~~~~~~~ On entry: R0 = flags: bit 0: set => force release of channel clear => release only if access key is correct other bits reserved R1 = resource number to release: 0 - Soundblaster (DAC, ADC, FMSynth, timer and mixer: SoundCtrl virtually disabled) 1 - Adlib/FMSynth 2 - MPU 401 MIDI 3 - game port 4 - playback channel 5 - capture channel 6 - timer 7 - the mixer R2 = access key This call deregisters the access key and internally marks the resource unused. This SWI can return the following errors: +3 - Sound Control resource not recognised +5 - Access key is not correct 4.1.3 SoundCtrl_SetVolume 0x50002 ~~~~~~~~~~~~~~~~~~~~~~~~~ On entry: R0 = flags: bit 0: set for left muted, clear otherwise bit 1: set for right muted, clear otherwise other bits reserved R1 = channel R2 = access key R3 = volume left R4 = volume right On exit: R0 = flags: bit 0: set for left muted, clear otherwise bit 1: set for right muted, clear otherwise other bits reserved R3 = left volume chosen R4 = right volume chosen This is a family of calls with similar, but not identical, functions on different channels. Calls can mute the relevant channels or set the required gain and attenuation subject to the capacities of the underlying hardware. [ For reference, the AD1816A supports the following Master (0) volume: 0.0dB to -46.5dB in 1.5dB decrements Line (1) volume: 12.0dB to -34.5dB in 1.5dB decrements CD (2) volume: 12.0dB to -34.5dB in 1.5dB decrements Mic (5) volume: 0.0dB to -45.0dB in 3.0dB decrements (Mono) Playback (8) volume: 0.0dB to -94.5dB in 1.5dB decrements FM (9) volume: 0.0dB to -94.5dB in 1.5dB decrements I2S 0 (10) volume: 0.0dB to -94.5dB in 1.5dB decrements I2S 1 (11) volume: 0.0dB to -94.5dB in 1.5dB decrements Capture* (12) volume: 0.0dB to +22.5dB in 1.5dB increments However, there exists the possiblity that future hardware will support a wider range of values. Hence the flexibility in the following. NB: For those channels which are currently mono only the left channel currently has an effect. However, this must not be relied upon in future releases. * Capture/ADC in cannot be muted.] Gain (or attenuation) is specified as a 2's complement, fixed point number, repesenting the number of decibels, in the following format:- 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 /---------------------------------------------------------------\ |±| | | | | | | | | | | | | | | · | | | | | | | | | | | | | | | | \---------------------------------------------------------------/ ^ ^ Sign bit | This gives a (overly generous) range of ± 32767dB with a granularity of 1.52×10^-5dB. A rogue value with just the top bit set (-32768 / 0x80000000) indicates that automatic gain control should be used. This must only be selected for hardware which supports the feature and will be faulted otherwise. All channels apart from the ADC in must only be used if the mixer has been claimed using SoundCtrl_Claim. The ADC in must only be used if the playback and capture channels have been claimed. This SWI can return the following error: +2 - Sound channel is unknown or not suitable for this purpose +5 - Access key is not correct 4.1.4 SoundCtrl_GetVolume 0x50003 ~~~~~~~~~~~~~~~~~~~~~~~~~ On entry: R0 = flags, currently reserved R1 = channel On exit: R0 = flags: bit 0: set for left muted, clear otherwise bit 1: set for right muted, clear otherwise other bits reserved R3 = volume left R4 = volume right This returns volume information in the format discussed in 5.1.2 SoundCtrl_SetVolume. This SWI can return the following error: +2 - Sound channel is unknown or not suitable for this purpose channel 4.1.5 SoundCtrl_ChannelInfo 0x50004 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ On entry: R0 = flags, currently reserved R1 = channel number (zero to start enumeration) On exit: R0 = flags: bit 0: set => volume set in SoundCtrl_SetVolume affects ADC input, clear => volume set for this channel does not affect ADC bit 1: set => can be muted, clear => can not be muted bit 2: set => has automatic gain control, clear => does not have automatic gain control bit 3: set => has selectable sources for use as input (using SoundCtrl_SetSource) clear => does not have selectable sources bit 4: set => can be used as input to ADC selector (see SoundCtrl_SetADCSource), clear => cannot be used as input to ADC bit 5: set => can be used as input to mixer clear => cannot be used as input to mixer bit 6: set => has programable sample rates clear => does not have programmable sample rates bit 30: set => has right component, clear => has no right component bit 31: set => has left component, clear => has no left component other bits reserved R1 = next available channel number R2 = channel number (NB: may differ from entry value of R1) R3 = resource number to claim to use this device (or -1 if none) R4 = minimum volume (in format described in 5.1. SoundCtrl_SetVolume) R5 = maximum volume (in format described in 5.1. SoundCtrl_SetVolume) R6 = volume increment (in format described in 5.1. SoundCtrl_SetVolume) This SWI returns information about a channel. Channels with a right component and no left component or vice versa are mono channels which can only be fed into the ADC on the right or left respectively. Channels with both a left and right channel are stereo channels. Currently a value of 00 for bits 0 and 1 is reserved. If R4 = 0x80000000 then there exists no volume control, R5, R6 are reserved. This call can be used in two ways:- To obtain information on one channel only, the channel number about which information is desired is given in R1 and the R1 value on exit is ignored. For information on more than one channel multiple calls must be made. The first call should be made with a value of zero in R1. Subsequent calls should use the value returned by the last call made until the value returned in R1 is 0 This SWI can return the following errors: +2 - Sound channel is unknown or not suitable for this purpose 4.1.6 SoundCtrl_SetSource 0x50005 ~~~~~~~~~~~~~~~~~~~~~~~~~ On entry: R0 = flags, currently reserved R1 = input channel number, currently capture (12) only R2 = access key R3 = left source R4 = right source This selects channels on board the sound chip to be the source for the relevant channel. Left and right may be independently selected. A call must be made to SoundCtrl_EnumerateChannels to check availability and suitability of sources and input channel before using this call. The various sources are, currently: 0 - output from mixer 1 - line in 2 - CD 5 - microphone 7 - mono mixer The relevant channel must be claimed using SoundCtrl_Claim before making this call. NB: This SWI returns the following error: +2 - Sound channel is unknown or not suitable for this purpose +5 - Access key is not correct 4.1.7 SoundCtrl_GetSource 0x50006 ~~~~~~~~~~~~~~~~~~~~~~~~~ On entry: R0 = flags, currently reserved R1 = input channel number On exit: R0 = flags, currently reserved R3 = left source (see _SetSource) R4 = right source (see _SetSource) This returns the current channel(s) for the relevant channel's right and left source. The numeric values used are as for SoundCtrl_SetADCSource. A call must be made to SoundCtrl_EnumerateChannels to check availability and suitability of input channel before using this call. This SWI never returns errors. 4.1.8 SoundCtrl_SetCodec 0x50007 ~~~~~~~~~~~~~~~~~~~~~~~~ On entry: R0 = flags: bit 0: set => stereo, clear => mono other bits reserved R1 = 8 - playback 9 - FM Synth 10 - I˛S 0 11 - I˛S 1 12 - capture R2 = access key R3 = encoding type, 0 : linear unsigned 8-bit 1 : u-law 8-bit 2 : linear little-endian 16-bit 3 : A-law 8-bit 4,5 : reserved 6 : linear big-endian 16-bit other values reserved R4 = sample rate On exit: R4 = sample rate chosen This sets the choice of encoding/decoding scheme, and the sample rate, for either the playback or the capture channel. The sample rate will be the highest available rate below or equal to that requested. If the sample rate requested is below the minimum available, the minimum available rate will be chosen. [On Phoebe sample rates of 4kHz to 55.2kHz may be chosen in 1Hz increments.] This call must only be made if the relevant resource has been successfully claimed. This SWI can return the following errors: +2 - Sound channel is unknown or not suitable for this purpose +4 - Encoding is not recognised +5 - Access key is not correct 4.1.9 SoundCtrl_GetCodec 0x50008 ~~~~~~~~~~~~~~~~~~~~~~~~ On entry: R0 = flags, currently reserved R1 = 8 - playback 12 - capture On exit: R0 = flags: bit 0: set => stereo, clear => mono R3 = encoding type, 0 : linear unsigned 8-bit 1 : u-law 8-bit 2 : linear little-endian 16-bit 3 : A-law 8-bit 6 : linear big-endian 16-bit -1 : this channel does not have codec capabilities R4 = sample rate This returns the current settings of the sample rate and en-/decoding scheme for the capture and playback channels. This SWI can return the following error: +2 - Sound channel is unknown or not suitable for this purpose 4.1.10 SoundCtrl_SampleRateInfo 0x50009 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ On entry: R0 = flags, currently reserved R1 = channel R3 = desired sample rate On exit: R3 = nearest sample rate lower than or the same as requested sample rate, or lowest possible sample rate if the requested rate is lower than any available (eg. 0) R4 = nearest sample rate greater than requested sample rate or greatest possible sample rate if the requested rate is higher then any available or -1 was specified in R3 on entry. This call can be used in several ways: Firstly it can be used simply to determine the sample rate which would be used by a call to SoundCtrl_SetCodec with the same requested rate. The value returned in R3 would be the rate used. This could be used repeatedly to determine, for a list of desired sample rates, which sample rates could actually be used. Secondly it can be used to return the highest and lowest possible rates by calling it with 0 (to find the lowest) followed by -1 (to find the highest). Thirdly it can be called to enumerate all rates. This is done with 0 in R3 initially and thereafter by copying R4 into R3 to find the full range of sample rates available. Th highest rate available will be returned in both R3 and R4. Note that for hardware supporting small granularity this becomes a needlessly time-wasting task and some common sense is needed by the programmer to avoid calling it for small increments in sample rate. If called with a requested sample rate lower than any available R3 will return the lowest available and R4 the next lowest. For hardware supporting only one sample rate these will be the same value. However, if called with a sample rate greater than or equal to the highest possible rate, R3 and R4 will return identical values: the highest possible sample rate. The sample rate is given in the following format: 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 /---------------------------------------------------------------\ | | | | | | | | | | | | | | | | | | | | | · | | | | | | | | | | | \---------------------------------------------------------------/ ^ | This gives a range of 0 to 4.19MHz with a granularity of 977 uHz (1/1024 Hz). 4.1.11 SoundCtrl_Transfer 0x5000a ~~~~~~~~~~~~~~~~~~~~~~~~~ On entry: R0 = flags: bit 0: reserved, set to zero bit 1: set => scatter list is circular buffer, clear => not so bit 2: set => call-back handler entry point in R7 other bits reserved and must be zero R1 = 8 - playback 12 - capture other values reserved R2 = access key R3 = pointer to word-aligned scatter list R4 = number of bytes to transfer, or 0 for infinite length transfer R5 = size of circular buffer R6 = number of bytes to between calls to call-back handler R7 = pointer to list of assembler 'call-back' handler pointers: + 0 : start + 4 : process buffer + 8 : finish R8 = entry point's R12 value On exit: This call initiates a DMA transfer using either the playback or capture channel. Only one transfer can occur on any one channel at a time. The scatter list consists of pairs of buffer logical address, buffer length. These are word-aligned 32-bit values, the length must be a multiple of 4. |Only one transfer is permitted on any channel at any time (SoundCtrl DMA |transfers are regarded as real-time, not queuable, events). This call must only be made if the relevant resource has been successfully claimed. This SWI can return the following error: +2 - Sound channel is unknown or not suitable for this purpose +5 - Access key is not correct |Start handler: On entry: R12 = value passed in R8 above Process buffer Handler: On entry: R12 = value passed in R8 above On exit: R0 = 0 => continue transfer n => abort after n bytes transfered (must be mutiple of 4) Finish handler: On entry: R0 = 0 if V is clear or a pointer to an error block if V is set R12 = value passed in R8 above Interrupts may be disabled on entry to the call-back handlers, and, if so, must be maintained in this state at all times. The handler may be entered in IRQ mode. If this is the case, then the handlers should return in IRQ mode and must preserve R14_svc when calling SWIs (see PRM 3.0 1-125). The handlers must complete as quickly as is possible and should avoid potentially slow calls to the OS. All registers must be preserved unless stated otherwise. 4.1.12 SoundCtrl_SuspendTransfer 0x5000b ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ On entry: R0 = flags, reserved R1 = channel number R2 = access key This call will cause the current transfer to temporarily halt. SoundCtrl_ResumeTransfer can be called to cause the transfer to continue. 4.1.13 SoundCtrl_ResumeTransfer 0x5000c ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ On entry: R0 = flags, reserved R1 = channel number R2 = access key This call causes the transfer to continue if it was halted using SoundCtrl_SuspendTransfer. Otherwise it does nothing. 4.1.14 SoundCtrl_TerminateTransfer 0x000d ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ On entry: R0 = flags, reserved R1 = channel number R2 = access key This call prematurely ends the transfer. 4.1.15 SoundCtrl_GetHWAddress 0x5000e ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ On entry: R0 = flags, currently reserved On exit: R0 = Soundblaster register base address or 0 R1 = Adlib register base address or 0 R2 = MIDI register base address or 0 R3 = Game Port register base address or 0 This SWI returns the base addresses of the register sets for various logical devices of the sound chip or zero if that device is not present. It is for use by those programmers who wish to directly address the hardware. The hardware in question must first be claimed using SoundCtrl_Claim. This SWI never returns any errors. 4.2 Possible Errors ------------------- The module can return the following errors (offset from 0x813100): +1 - Sound Control function unknown or not supported +2 - Sound channel is unknown or not suitable for this purpose +3 - Sound Control resource not recognised +4 - Encoding is not recognised +5 - Access key is not correct -------------------------------------------------------------------------------- 5.0 Data formats ================ The data formats used are controlled by the SoundCtrl_SetCodec and SoundCtrl_GetCodec SWIs discussed above. The u-law and A-law discussed above differ from RISC OS' u-law and A-law in bit layout. -------------------------------------------------------------------------------- 6.0 Glossary ============= ADC: analogue to digital convertor, a sampler. Capture: the process of sampling audio using the ADC and writing the results to memory. Channel: a path along which sound can travel. May be analogue or digital. DAC: digital to analogue convertor. Double buffer: a set of two buffers used together in such a way that whilst one buffer client fills one of the two buffers another is emptying the other. This avoids contention between the filler and emptier and prevents one of them overunning the other. FM Synth(esiser): a logical device capable of synthesising musical notes and sound effects. Playback: the process of streaming data from memory through the DAC. Wavetable synth(esiser): a very versatile device capable of producing a very wide range of different sound effects.