AcornSearch - Acorn and RISC OS information searching
RISC OS Search
containing
"Nutty quip goes here!"
Home  |  About  |  Filebase Archive  |  StrongHelp Manuals  |  Newsgroups  |  Module Database
=>     R0 =     handler address
     R1 =     parameter to pass
     R2 =     flags
     R3 =     name of handler
     R4 =     type
<=     R0 =     handler number

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

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

Each handler is passed a buffer to fill with the registers set as follows:

=>     R0 =     parameter
     R1 =     base address of buffer to fill
     R2 =     end of buffer
     R3 =     flags
     R4 =     sample frequency
     R5 =     sample period
     R6 =     fractional step as specified by SharedSound_SampleRate
     R7 =     LR volume
     R8 =     Pointer to helpful fill code (1.00+)
     R4, R5 and R6 are updated at the start of a buffer fill to represent the current sample frequency etc.
<=     R3 contains flags as above, modified according to the action of the handler

The important requirement on exit is that bit 0 of R3 should be set if any data has been written into the buffer. In fact, SharedSound cannot currently cope with no data being filled, so zeros should always be written.
SharedSound Handler flags
Bits     /Meaning/

0     Mix. If set then data must be mixed, otherwise overwrite.
1     Quality. If set then use highest quality e.g. oversampling. [Not implemented]
3-7     Overrun count [Not implemented]
     0     No overrun
     1˜30     times buffer has been overrun
     31     Buffer overrun > 30
29     Stereo. Reverse stereo if set. [Not implemented]
30     Set if to use volume in R7, otherwise use max volume
31     Set if volume in R7 is zero, ie. muted.

Only bit 0 of the above flags is implemented by SharedSound. The other flags are currently used by the Sound16 drivers.
Fill code
On entry to the fill handler, R8 points to the following table:

Offset     Value

0     Flags word, currently 0
4     Pointer to silence fill routine
8     Pointer to data fill routine

This table may be extended in future to include more fill variants; the presence/absence of these routines will be indicated by bits in the flags word.

Using these routines, the overall sound fill code in a client can therefore look something like this (assuming the client is filling from a cyclic buffer).
Silence fill code
=>     R1 =     Base address of buffer to be filled
     R2 =     End of the buffer to be filled
     R3 =     Flags (as on entry to the fill handler)
     R4-R5     Unused
     R6 =     Fractional step value
     R7 =     LR volume
     R9 =     Fractional accumulator
<=     R0 =     New flags (to be returned from fill handler in R3)
     R1 =     Next byte to be filled
     R4 =     Next byte to fill from
     R9 =     New Fractional accumulator
     R2-R3,R5-R7,R8,R12 preserved
     All other registers corrupted.
Data fill code
=>     R1 =     Base address of buffer to be filled
     R2 =     End of the buffer to be filled
     R3 =     Flags (as on entry to the fill handler)
     R4 =     Base of buffer to fill from
     R5 =     End of buffer to fill from
     R6 =     Fractional step value
     R7 =     LR volume
     R9 =     Fractional accumulator
<=     R0 =     New flags (to be returned from fill handler in R3)
     R1 =     Next byte to be filled
     R4 =     Next byte to fill from
     R9 =     New Fractional accumulator
     R2-R3,R5-R7,R8,R12 preserved
     All other registers corrupted.
Example fill code
fill    STMFD   r13!,{r0-r2,r4-r12,r14}

MOV     r12,r0
; We are filling from play_ptr to where?
LDR     r4,play_ptr
LDR     r5,fill_ptr
LDR     r9,buffer_start
ADD     r4,r4,r9
ADD     r5,r5,r9
LDR     r9,accumulator
; Are we wrapped, or unwrapped?
CMP     r4,r5
BEQ     out_of_data
BLO     unwrapped
; |*****-------------------------********|
;       ^fill ptr                ^play ptr
LDR     r5,buffer_end   ; Fill from fill ptr to buffer_end
; Call the fill code
MOV     R14,PC
LDR     PC,[R8,#8]
; Did we run out of data?
CMP     R4,R5           ;
LDRHS   R4,buffer_start ; If r4 >= r5 then we used all the
; data in the buffer.
CMP     R1,R2           ; Did we finish the fill?
BHS     finish          ; If r1 >= r2 then we finished.
LDR     R5,fill_ptr     ; No, so we ran out of data. Jump
CMP     R5,#0           ; Check if there any data there -
BEQ     out_of_data     ; If not, play silence.
ADD     R5,R5,R4
unwrapped
; |-----*************************--------|
;       ^play ptr                ^fill ptr
; Call the fill code
MOV     R14,PC
LDR     PC,[R8,#8]
; Either we finished the fill, or we ran out of data.
CMP     R1,R2           ; Did we finish?
BEQ     finish
out_of_data
; Fill with silence
MOV     R14,PC
LDR     PC,[R8,#4]
finish
LDR     r3,buffer_start
STR     R9,accumulator
SUB     r4,r4,r3
STR     R4,play_ptr
MOV     r3,r0

LDMFD   r13!,{r0-r2,r4-r12,PC}

[sh-index] Back to list of manuals