<html>
<h2>ProSound module</h2>
The ProSound module provides a number of SWIs for sampleformat conversion and for handling of ProSound tracks.<br>


<h4>SWI ProSound_InitTrack (SWI &83F00)</h4>
This SWI creates a new track.

<pre>
On entry
        R0  =>  Block to use as track handle (1024 bytes)
        R1  =>  Filename of VM file
        R2  =   Number of samples in file (1024 - 200000000)
        R3  =   Max number of samples in the file ( >= R2)
        R4  =   Frequency*10 (in Hz) (5000 - 60000)
        R5  =   Flags
                Bit 0     clear  => allow track duration to change 
                          set    => don't allow track duration to change
                Bit 2     clear  => create the file
                          set    => the file already exists and contains data
                Bit 3     clear  => use a dynamic area
                          set    => use RMA
                Bit 4-8   id of compression type
                          (0 is 16bit lin sign)
                Bit 9-31  must be 0
        R6  =   Number of pages in the cache
        R7  =   Byte-offset of first sample in file

On exit
        All registers preserved
</pre>


<h4>SWI ProSound_ReadFromDisc (SWI &83F01)</h4>
This SWI reads a number of samples from disc to a buffer.

<pre>
On entry
        R0  =>  Track
        R1  =>  Buffer
        R2  =   Number of samples to read
        R3  =   Index of first sample to read

On exit
        R2  =   Number of samples read
        All other registers preserved
</pre>


<h4>SWI ProSound_WriteToDisc (SWI &83F02)</h4>
This SWI writes a number of samples from a buffer to disc. It calls <tt>SWI ProSound_WriteCompressed</tt> and <tt>SWI ProSound_InvalidateCache</tt>.

<pre>
On entry
        R0  =>  Track
        R1  =>  Buffer
        R2  =   Number of samples to write
        R3  =   Index of first sample to write

On exit
        R2  =   Number of samples written
        All other registers preserved
</pre>


<h4>SWI ProSound_AddSamples (SWI &83F06)</h4>
This SWI adds the contents of two buffers.

<pre>
On entry
        R0  =>  Input buffer 1
        R1  =>  Input buffer 2
        R2  =>  Output buffer (can be equal to R0 or R1)
        R4  =   Number of samples in either buffer

On exit
        All registers preserved
</pre>


<h4>SWI ProSound_InsertSamples (SWI &83F07)</h4>
This SWI inserts a number of samples at any position on a track. It calls <tt>SWI ProSound_InvalidateCache</tt> and <tt>SWI ProSound_WriteCompressed</tt>.

<pre>
On entry
        R0  =>  Track
        R1  =   Sample index of sample to insert AFTER
        R2  =   Number of samples to insert (ISC)

On exit
        R2  =   Number of samples inserted
        All other registers preserved
</pre>

The duration of the track is NOT increased. This should be done BEFORE this SWI is called if you want to preserve the last (ISC) samples on the track.<br>


<h4>SWI ProSound_RemoveSamples (SWI &83F08)</h4>
This SWI removes a number of samples from the track. It calls <tt>SWI ProSound_InvalidateCache</tt> and <tt>SWI ProSound_WriteCompressed</tt>.

<pre>
On entry
        R0  =>  Track
        R1  =   Sample index of first sample to remove
        R2  =   Number of samples to remove

On exit
        All registers preserved
</pre>

The duration of the track is NOT altered.<br>


<h4>SWI ProSound_GetPage (SWI &83F09)</h4>
This SWI returns a pointer to the RAM page holding the requested disc page. The disc page is paged in if necessary, through <tt>SWI ProSound_PageIn</tt>.

<pre>
On entry
        R0  =>  Track
        R1  =   Disc page number

On exit
        R0  =>  RAM page start
        R1  =   RAM page number
        All other registers preserved
</pre>


<h4>SWI ProSound_FindPage (SWI &83F0A)</h4>
This SWI returns the RAM page which holds a given disc page or -1 if the
disc page isn't cached.

<pre>
On entry
        R0  =>  Track
        R1  =   Disc page number

 On exit
        R0  =>  RAM page start or -1 (disc page is not in RAM)
        R1  =   RAM page number or -1 (disc page is not in RAM)
        All other registers preserved
</pre>

<b>THIS CALL IS FOR INTERNAL USE ONLY</b>


<h4>SWI ProSound_PageIn (SWI &83F0B)</h4>
This SWI reads a disc page to into a RAM page. If the RAM page is in use, it is paged out before the new page is read.

<pre>
On entry
        R0  =>  Track
        R1  =   Disc page number
        R2  =   RAM page number

On exit
        All registers preserved
</pre>

<b>THIS CALL IS FOR INTERNAL USE ONLY</b>


<h4>SWI ProSound_TrackCompression (SWI &83F0C)</h4>
This SWI manages compression/decompression of tracks.

<pre>
On entry
        R0  =   Reason code
                0 : Install compression type
                1 : Remove compression type
                2 : Read compression types list
                3 : Read compression type details
        R1-R8   Depends on R0

On exit
        Depends on the reason code
</pre>

<h6>Install compression type</h6>
<pre>
On entry
        R0  =   0
        R1  =>  List of entry points
                0       ReadSamples_Code
                4       WriteSamples_Code
                8       CreateTrack_Code
                12      RemoveTrack_Code
                16      InsertSamples_Code
                20      RemoveSamples_Code
                24      ExtendFile_Code
                28      OpenFile_Code
                32      0
                36      0
                40      0
                44      0
                48      0
                52      0
                56      Decompress_Code
                60      Compress_Code
        R2  =>  Compression type name (max 23 chars, 0-terminated)
        R3  =   Compression info flags
        R4  =   Compression type id (allocated by Oregan)
                0       16 bit linear signed
                1       8 bit log
        R5  =   Features flags
                Bit 0 set => always uses temp tracks (eg. in RAM)
On exit
        -
</pre>

<h6>Remove compression type</h6>
<pre>
On entry
        R0  =   1
        R1  =   Compression type id
</pre>

<h6>Read compression types list</h6>
<pre>
On entry
        R0  =   2
        R1  =>  Buffer for namelist (64 words, each entry uses 2 words)
                word 0  =>  name
                word 1      bits 0-4  compression type id
On exit
        R2  =   Number of available compression types (max. 32)
</pre>

<h6>Read compression type details</h6>
<pre>
On entry
        R0  =   3
        R1  =   Compression type id
On exit
        R0  =>  Entry point list
        R1  =>  Compression type name
        R2  =   Compression info flags
        R3  =   Features flags
</pre>


<h4>SWI ProSound_PageAddress (SWI &83F0D)</h4>
This SWI returns the start address of a RAM page.

<pre>
On entry
        R0  =>  Track
        R1  =   RAM page number

On exit
        R0  =>  RAM page start
        All other registers preserved
</pre>

<b>THIS CALL IS FOR INTERNAL USE ONLY</b>


<h4>SWI ProSound_InvalidateCache (SWI &83F0E)</h4>
This SWI frees a number of RAM pages.

<pre>
On entry
        R0  =>  Track
        R1  =   First sample to invalidate
        R2  =   Last sample to invalidate

On exit
        All registers preserved
</pre>


<h4>SWI ProSound_ApplyEnvelope (SWI &83F10)</h4>
This SWI applies an envelope to a buffer.<br>
If R0 points to a track, the envelope flag for that track must be set, otherwise the envelope will not be applied.

<pre>
On entry
        R0  =>  Track or envelope
        R1  =>  Buffer
        R2  =   Number of samples in buffer
        R3  =   Index (on track) of first sample in buffer
        R4  =   Flags
                Bit 0 set => volume is in R5
                Bit 1 set => R0 points to an envelope
        R5  =   Volume (0-32768, 4096 is 100%) if bit 0 of R4 is set
</pre>
<b>This SWI doesn't preserve the floating point registers.</b>


<h4>SWI ProSound_EnvelopeOp (SWI &83F11)</h4>
This SWI manipulates the envelope in various ways.

<pre>
On entry
        R0  =>  Track
        R1  =   Reason code
                0  =>   Reset envelope (to 2 points)

                1  =>   Read envelope
                        R2  =>  Envelope buffer (8196 bytes)
                        The first word is the number of points (NP), then
                        follows NP double words; first word is position of
                        the point in the track, the second word is the
                        amplitude (0-511, 0=-60dB, 256=0dB, 511=60dB)

                2  =>   Write envelope
                        R2  =>  Envelope buffer (8196 bytes)
                        The first point MUST be positioned at 0, and the
                        last point MUST be positioned at the last sample
                        on the track
                        The first word is the number of points (NP), then
                        follows NP double words; first word is position of
                        the point in the track, the second word is the
                        amplitude (0-511, 0=-60dB, 256=0dB, 511=60dB)

                3  =>   Read number of points
                        On exit
                        R0  =   Number of points in the envelope

                4  =>   Insert samples
                        R2  =   Sample index to insert after
                        R3  =   Number of samples to insert

                5  =>   Remove samples
                        R2  =   Sample index of first sample to remove
                        R3  =   Number of samples to remove

                6  =>   Read envelope value
                        R2  =   Sample index of sample to read
                        On exit
                        R0  =   Amplitude (0-32767, 256 = 100%)
                        This call simply calls SWI ProSound_ReadEnvelope

                7  =>   Reset fast envelope reader
</pre>
<b>This SWI doesn't preserve the floating point registers.</b>


<h4>SWI ProSound_WriteCompressed (SWI &83F12)</h4>
This SWI compresses a RAM page and writes it to the compressed sample buffer.

<pre>
On entry
        R0  =>  Track
        R1  =   Disc page number
        R2  =>  1024 bytes buffer start or -1

On exit
        If R2 = -1 on entry then R0 holds the display buffer value for the
        disc page.
        All other registers preserved
</pre>

This SWI should be called whenever there is a chance that a cached discpage has altered.


<h4>SWI ProSound_ReadEnvelope (SWI &83F13)</h4>
This call reads a value from an envelope.

<pre>
On entry
        R0  =>  Envelope
        R1  =   Sample index of sample

On exit
        R0  =   Amplitude (0-32767, 256 = 100%)
        R1-R5 are destroyed.
</pre>

The routine is optimised to be called with R1 increasing for each call.<br>
If R1 < previous_R1 the routine will be VERY slow.


<h4>SWI ProSound_ReadSampleInfo (SWI &83F14)</h4>
This SWI returns the maximum sample value and the DC-offset of a selection.

<pre>
On entry
        R0  =>  Track
        R2  =   First sample
        R3  =   Last sample or -1 (last sample)

On exit
        R0  =   Maximum sample value (from 0 to 32767)
        R1  =   (Sum of all samples)/32768
        All other registers preserved
</pre>


<h4>SWI ProSound_CustomEffect (SWI &83F15)</h4>
This SWI applies a custom effect to a sample.
It calls <tt>SWI ProSound_WriteCompressed</tt> and <tt>SWI ProSound_InvalidateCache</tt>.

<pre>
On entry
        R0  =>  Track
        R1  =>  Effect block
                FXB+0   Value to pass in R2
                FXB+4   Value to pass in R3
                FXB+8   Value to pass in R4
                FXB+12  Value to pass in R5
                FXB+16  Value to pass in R6
                FXB+20  Value to pass in R7
                FXB+24  Address of routine to call
        R2  =   Sample index of first sample
        R3  =   Sample index of last sample
        R4  =   Flags
                Bit 0-1 Read/write type
                        0       Read and write
                        1       Effect is read only
                        2       Effect is write only
                        3       Read and write, write with write action
                Bit 2-3 Buffering
                        0       The SWI should claim a buffer from the RMA
                        1       R5 points to buffer
                                R6 is the size of the buffer (in samples)
                        2       The SWI should claim a buffer from the RMA
                                R6 is the size of the buffer (in samples)
                        3       -
                Bit 4-5 Write action (if read/write type = 3)
                        0       Force
                        1       Add
                        2       Average
                        3       Reserved (currently acts as force)
        R5  =>  Buffer (if bit 2-3 of R4 is 1)
        R6  =   Buffer size in samples (if bit 2-3 of R4 is 1 or 2)

 On exit
        All registers preserved
</pre>

The effect routine will be called with
<pre>
        R0  =   Sample value (32 bit value from -32768 to 32767)
        R1  =   Sample index on track
        R2-R7   As specified in FXB+4 to FXB+24 (reloaded before each call)
        R8  =>  Track
        R10 =   Return address (can't use R14)
        R13 =>  small FD stack (SVC)
</pre>
On exit, R0 should hold the new sample value as a 32 bits value from -32768 to 32767. Clipping will be performed automatically.<br>
R1 - R12 may be corrupted.<br>
The effect code is called in supervisor mode.

On a standard Risc PC 600, the effect routine will be called ~200000 times each second if the routine doesn't do anything.



<h4>SWI ProSound_Build (SWI &83F16)</h4>
This SWI builds a sample from the various tracks.

<pre>
On entry
        R0  =>  Track list
                0       Pointer to track 0 or 0
                4       Pointer to track 1 or 0
                8       Pointer to track 2 or 0
                12      Pointer to track 3 or 0
                16      Pointer to track 4 or 0
                20      Pointer to track 5 or 0
                24      Pointer to track 6 or 0
                28      Pointer to track 7 or 0
        R3  =>  VU meter buffer (if bit 3 of R7 is set)
        R4  =>  Buffer list
                +0  =>  Work buffer (2*N bytes)
                +4  =>  Left channel or 0
                +8  =>  Right channel or 0
        R5  =>  Number of samples to build per channel (N) (>=1)
        R6  =   Index of first sample
        R7  =   Flags
                Bit 0 set   =>  apply envelope
                Bit 1 set   =>  force write to unused channel buffer
                Bit 2 clear =>  left and right channels are separate
                Bit 2 set   =>  left and right channels are interleaved
                Bit 3 set   =>  R3 points to a VU meter buffer
                All other bits are reserved and must be 0.

 On exit
        All registers preserved
</pre>

The SWI is not reentrant.<br>
All buffers must be quad-wordaligned.<br>

<h6>If the channels are interleaved:</h6>
The right channel buffer is ignored, and the left channel buffer pointer MUST be <> 0 and should point to a buffer large enough to hold the samples for both channels, ie. 4*N bytes. The routine uses ~35 clockcycles per sample for both channels.

<h6>If the channels are separate:</h6>
There will only be written to left (or right) channel buffer if any of the input tracks are applied to the left (or right) channel and if the volume of these tracks are >0 and if the forcewrite flag is clear. So if you know for sure that none of the tracks give any contribution to eg. the left channel, you don't need to supply a buffer for the left channel. The routine uses ~20 clockcycles per sample per channel.<br>

Applying the envelope uses another 3-5 clockcycles per sample per channel.



<h4>SWI ProSound_OpenClose (SWI &83F17)</h4>
This SWI open or closes a file.

<pre>
On entry
        R0  =>  Track
        R1  =   0 (open) or 1 (close)

On exit
        All registers preserved
</pre>


<h4>SWI ProSound_SetDuration (SWI &83F18)</h4>
This SWI sets the duration of a track.

<pre>
On entry
        R0  =>  Track
        R1  =   New duration (in samples)

On exit
        R1  =   Actual new duration (in samples)
        All other registers preserved
</pre>


<h4>SWI ProSound_ConvertFrom (SWI &83F19)</h4>
This SWI converts from various formats to 16bit.

<pre>
On entry
        R0  =   Input format
        R1  =>  Input buffer
        R2  =>  Output buffer
        R4  =   Number of samples in input buffer
        R5-R8   Parameters

On exit
        All registers preserved
</pre>

<h6>Input formats:</h6>
<pre>
        0       16 bit linear signed
        1       16 bit linear unsigned
        2       16 bit linear signed, big-endian
        3       16 bit linear unsigned, big-endian
        4       8 bit linear signed
        5       8 bit linear unsigned
        6       8 bit logarithmic, VIDC1a
        7       8 bit logarithmic, u-law
        8       8 bit logarithmic, a-law (dodgy)
        9       4 bit ADPCM, Intel/DVI mono
                R5  =>  12 bytes buffer for holding status
                        Must be initialised to:
                        Word 0  0
                        Word 1  7
                        Word 2  0
       10       4 bit ADPCM, Intel/DVI stereo
                R5  =>  24 bytes buffer for holding status
                        Must be initialised to:
                        Word 0  0
                        Word 1  7
                        Word 2  0
                        Word 3  0
                        Word 4  7
                        Word 5  0
       11       4 bit ADPCM, Intel/DVI, Acorn style mono (dodgy)
                see format 9
       12       4 bit ADPCM, Intel/DVI, Acorn style stereo (dodgy)
                see format 10
       13       12 bit linear signed
       14       12 bit linear unsigned
       15       24 bit linear signed
       16       24 bit linear unsigned
       17       32 bit linear signed
       18       32 bit linear unsigned
       19       24 bit linear signed, big-endian
       20       24 bit linear unsigned, big-endian
       21       32 bit linear signed, big-endian
       22       32 bit linear unsigned, big-endian
</pre>


<h4>SWI ProSound_ConvertTo (SWI &83F1A)</h4>
This SWI converts from 16bit to various formats.

<pre>
On entry
        R0  =   Output format
        R1  =>  Input buffer
        R2  =>  Output buffer
        R4  =   Number of samples in input buffer
        R5-R8   Parameters

On exit
        All registers preserved
</pre>

<h6>Output formats:</h6>
<pre>
        0       16 bit linear signed
        1       16 bit linear unsigned
        2       16 bit linear signed, big-endian
        3       16 bit linear unsigned, big-endian
        4       8 bit linear signed
        5       8 bit linear unsigned
        6       8 bit logarithmic, VIDC1a
        7       8 bit logarithmic, u-law
        8       8 bit logarithmic, a-law (dodgy)
        9       4 bit ADPCM, Intel/DVI mono
                R5  =>  12 bytes buffer for holding status
                        Must be initialised to:
                        Word 0  0
                        Word 1  7
                        Word 2  0
       10       4 bit ADPCM, Intel/DVI stereo
                R5  =>  24 bytes buffer for holding status
                        Must be initialised to:
                        Word 0  0
                        Word 1  7
                        Word 2  0
                        Word 3  0
                        Word 4  7
                        Word 5  0
       11       4 bit ADPCM, Intel/DVI, Acorn style mono (dodgy)
                see format 9
       12       4 bit ADPCM, Intel/DVI, Acorn style stereo (unsupported)
       13       12 bit linear signed
       14       12 bit linear unsigned
       15       24 bit linear signed
       16       24 bit linear unsigned
       17       32 bit linear signed
       18       32 bit linear unsigned
       19       24 bit linear signed, big-endian
       20       24 bit linear unsigned, big-endian
       21       32 bit linear signed, big-endian
       22       32 bit linear unsigned, big-endian
</pre>


<h4>SWI ProSound_Interleave (SWI &83F1B)</h4>
This SWI converts from interleaved to non-interleaved format (or back).

<pre>
On entry
        R0  =   Flags
        R1  =>  Buffer1
        R2  =>  Buffer2
        R3  =>  Buffer3 or 0 (only allowed when un-interleaving)
        R4  =   Number of samples in input buffer(s) in total
                (not per channel)

On exit
        All registers preserved
</pre>

<h6>Flags:</h6>
<pre>
Bit 0 - 7       Format
                0       Mono
                1       Stereo LRLRLR...
                2       Stereo RLRLRL...
                3       Stereo AudioWorks style LLLLLLLLRRRRRRRRLLLL...
                4       Stereo AudioWorks style RRRRRRRRLLLLLLLLRRRR...
                253     Special case
                        swaps left and right in a interleaved buffer; the
                        buffer must be interleaved in either format 1 or 2
                254     Special case
                        uninterleave cnverts from format 1/2 to format 0
                        interleave converts from format 0 to format 1/2
                        buffer 1 is input, buffer 2 is output
                255     Special case
                        interleave converts from format 1 to format 3
                        un-interleave converts from format 3 to format 1
                        buffer 1 is input, buffer 2 is output
 Bit 8  clear  => un-interleave, buffer 1 is input
        set    => interleave, buffers 1 and 2 are input
 Bit 9  set    => swap left/right when un-interleaving (only formats 0-4)
</pre>

If format is either 1 or 2, the SWI assumes that there is an even number of samples in the input buffer.<br>

If format is either 3 or 4 or 255, the SWI assumes that there is a multiple of 8 samples in the input buffer.<br>

If format is 0 and bit 8 is set, the samples from the two input buffers (1 and 2) are added and saved in buffer 3.<br>

If format is 0 and bit 8 is clear, the contents of the input buffer (1) is copied to both buffer 2 and 3.<br>

If format is 253, buffer 1 is input and buffer 2 is output.<br>

If format is 254 and bit 8 is set, the samples from buffer 1 are copied as samples pair to buffer 2 (eg. ABCDE becomes AABBCCDDEE).<br>

If format is 255 and bit 8 is clear, the sample pairs in buffer 1 are averages and written to buffer 2.<br>

All buffers must be word-aligned.



<h4>SWI ProSound_Resample (SWI &83F1C)</h4>
This SWI resamples a block of samples.

<pre>
On entry
        R0  =   Resample rate * 4096
                (infreq/outfreq or inbuffersize/outbuffersize)
        R1  =>  Input buffer
        R2  =>  Output buffer (max 2^19 samples)
        R3  =   Flags
                Bit 0 set => interpolate new samples
                Bit 1 set => always resample from start to end (*)
                Bit 2-3   interpolation method (ignored if bit 0 is clear)
        R4  =   Number of samples in output buffer

On exit
        All registers preserved
</pre>

When resampling ProSound will start at the start of the buffers and end at the end of the buffers if the resample rate is > 1. If the resample rate is < 1 and bit 1 (*) in the flags is clear, the resampling will occur in the opposite direction, thus always allowing the same buffer to hold the input as well as the output data.<br>

 Currently all 4 interpolation methods are the same (linear interpolation), but in future versions of the module different methods may be available; a higher number will select a better (and probably also slower) method.


<h4>SWI ProSound_KillTrack (SWI &83F1D)</h4>
This SWI removes a track from disc and memory.<br>
It closes the file (if open), removes the file (if bit 0 of the flags is clear) and removes the dynamic area.

<pre>
On entry
        R0  =>  Track
        R1  =   Flags
                Bit 0 set =>    don't delete the file

On exit
        All registers preserved
</pre>


<h4>SWI ProSound_OverwriteDisc (SWI &83F1E)</h4>
This SWI writes a number of samples from a buffer to disc, using an 'overwrite' action.
It calls <tt>SWI ProSound_WriteCompressed</tt> and <tt>SWI ProSound_InvalidateCache</tt>.

<pre>
On entry
        R0  =>  Track
        R1  =>  Buffer (2*NS bytes)
        R2  =   Number of samples to write (NS)
        R3  =   Index of first sample to write
        R4  =   Overwrite action
                0       Overwrite
                1       Add
                2       Average
                3       Insert (not available)
                4       Mix (R6 = amplitude of signal in input buffer)
        R5  =>  Work buffer (2*NS bytes) (if R4=1 or R4=2)
        R6  =   Amplitude (if R4 = 4), 0 is silence, 256 is full


On exit
        R2  =   Number of samples written
        All other registers preserved
</pre>

<h6>Notes</h6>
R4 = 4 and R6 = 0    =>  nothing happens<br>
R4 = 4 and R6 = 128  =>  similar to R4 = 2<br>
R4 = 4 and R6 = 256  =>  similar to R4 = 0<br>
