You can get the latest version of this file and the freeware player modules
on the web at http://www.fun.cediti.be/~bju/myprogs.html (until end 1999).

There are also some contact addresses at the end of this file.



                         Digital Symphony revisions


1) 12 Mar 1993 (DS 1.20, DSymPlay 1.01)
   ------------------------------------
   Filetypes SySample and Symphony are now able to store 8-bit linear sample
   data.

2) 30 Mar 1994 (DS 1.30, DSymPlay 1.30)
   ------------------------------------
   Filetypes SySample and Symphony are now able to store 16-bit linear sample
   data.
   New compression scheme introduced.
   We now play tunes at nearly exactly the speed an Am*ga does.

3) 01 Sep 1994 (DS 1.31, DSymPlay 1.30)
   ------------------------------------

4) 16 Jan 1995 (DS 1.31, DSymPlay 1.40)
   ------------------------------------
5) 23 Oct 1996 (DS 1.31, DSymPlay 1.41)
   ------------------------------------

6) 20 Feb 1997 (DS 1.40, DSymPlay 1.42)
   ------------------------------------
   StrongARM compatible

6) 20 Jun 1997 (DS 1.40, DSymPlay 1.46)
   ------------------------------------
   External instrument loading capabilities.
   Loading songs in internal format.
   SWI DSym_TuneInfo spec changed.


                              Latest versions


DSym_Play module: 1.42
Digital Symphony: 1.40
Symphony file: 1 (from DS 1.30 on)
SySample file: 1 (from DS 1.30 on)
Patterns file: 0


              Major changes in DSymPlay from version 1.10 on


- Dynamic choice of the fastest routine given the processor (ARM 2 or >2).
- The load routine didn't release the unpacking buffer (32K) after
  loading a packed song. Works now.
- Changed the specs of the CutNote SWI, sorry!
- StrongARM compatible


This file contains two main parts:

   I. Effects commands and music files formats.
  II. SWI's and commands of the Digital Symphony players.


   PART I : Effect commands and music file formats of some music programs


1.1. Amiga ProTracker V1.1B Effect Commands
     --------------------------------------
     (x-y,z) indicates z is done if value not in the range x to y inclusive.
     <command number in hex> <effect value in hex>

     0 xy Normal play or Arpeggio.
          x: first halfnote to add to pitch
          y: second halftone to add to pitch

     1 xx Slide Up.
          xx: pitch increase step

     2 xx Slide Down.
          xx: pitch decrease step

     3 xx Tone Portamento. 
          xx: pitch slide speed (0 for previous speed)

     4 xy Vibrato.
          x: pitch change speed (0 for previous speed)
          y: pitch change depth (0 for previous depth)

     5 xy Tone Portamento + Volume Slide.
          x: volume increase step (priority)
          y: volume decrease step

     6 xy Vibrato + Volume Slide.
          x: volume increase step (priority)
          y: volume decrease step

     7 xy Tremolo.
          x: volume change speed (0 for previous speed)
          y: volume change depth (0 for previous depth)

     8 xx Not used.

     9 xx Set Sample Offset.
          xx: offset in sample DIV 256 (loop restarted if illegal)
              0 for previous offset

     A xy Volume Slide.
          x: volume increase step (priority)
          y: volume decrease step

     B xx Position Jump.
          xx: song position (0-127, masked, 0 if illegal)

     C xx Set Volume.
          xx: volume (0-64,rounded). Linear.

     D xy Pattern Break.
          10*x+y: position to jump to in next pattern (0-63, 0)

     E 0x Set Filter.
          x: filter on (0) or filter off (1) (or power LED on/off)

     E 1x Fine Slide Up.
          x: value to add to pitch

     E 2x Fine Slide Down.
          x: value to subtract from pitch

     E 3x Glissando Control.
          x: on (1) or off (0) (use with Tone Portamento)
          When off, the slide is smooth else from halfnote to halfnote

     E 4x Set Vibrato Waveform.
          x: sine (0), ramp down (1), square (2)
             bit 2 is off if wave form has to be restarted each note

     E 5x Set Fine Tune.
          x: new fine tune value

     E 6x Jump to Loop.
          x: jump to loop, play x times
             if 0, the loop start is set to the current pattern position

     E 7x Set Tremolo Waveform.
          x: sine (0), ramp down (1), square (2)
             bit 2 is off if wave form has to be restarted each note

     E 8x Not used.

     E 9x Retrig Note.
          x: retrig note each (more or less) x vblanks

     E Ax Fine Volume Slide Up.
          x: value to add to volume

     E Bx Fine Volume Slide Down.
          x: value to subtract from volume

     E Cx Note Cut.
          x: cut note after x vblanks (volume is only set to 0)

     E Dx Note Delay.
          x: number of vblanks for note delay

     E Ex Pattern Delay.
          x: delay pattern x notes

     E Fx Invert Loop.
          x: speed
             if 0, it's turned off
          Care must be taken using it: it inverts the sign of sample data
          inside sample loop, one byte each vblank

     F xx Set Speed.
          In CIA mode (recommended and most usual):
              xx: speed (1-31,ignored) or tempo (32-255)
                  Tempo unit: 1/24th vblanks per minute (defaults to 125)
          In VBlank mode:
              xx: speed (1-255,ignored)

1.2. Archimedes Tracker V1.0+++ Effect Commands
     ------------------------------------------                    
     (x-y,z) indicates z is done if value not in the range x to y.
     <command character> <command number in hex> <effect value in hex>

     0 00 xy Normal play or Arpeggio.
             x: first halfnote to add
             y: second halftone to subtract

     1 01 xx Slide Up.
             xx: pitch increase step (4 bits?)

     2 02 xx Slide Down.
             xx: pitch decrease step (4 bits?)
                                         
     B 0B xx Break Pattern.

     E 0E xy Set Stereo.
             y: stereo position (1-7,ignored). 1=left 4=center 7=right
             
     G 10 xx Volume Slide Up.
             xx: speed (4 bits?)

     H 11 xx Volume Slide Down.
             xx: speed (4 bits?)

     J 13 xx Position Jump.
             xx: song position (0-127,masked)

     L 15 xy Line Jump. (not in manual)
             Jump to line 10*x+y in same pattern. (10*x+y>63 ignored)

     S 1C xy Set Speed.
             y: speed (1-15,ignored)

     V 1F xx Set Volume.
             xx: volume (0-255). Logarithmic.

1.3. Archimedes Symphony V1.00 Effect Commands
     -----------------------------------------
     (x-y,z) indicates z is done if value not in the range x to y.
     <command number in hex> <effect value in hex>

     00 xyz Normal play or Arpeggio + Volume Slide Up.
            x: volume increase step
            y: first halfnote to add
            z: second halftone to add

     01 xyy Slide Up + Volume Slide Up.
            x: volume increase step
            yy: pitch increase step

     02 xyy Slide Down + Volume Slide Up.
            x: volume increase step
            yy: pitch decrease step

     03 xyy Tone Portamento. 
            yy: pitch slide speed (0 for previous speed)

     04 xyz Vibrato.
            y: pitch change speed (0 for previous speed)
            z: pitch change depth (0 for previous depth)

     05 xyz Tone Portamento + Volume Slide.
            y: volume increase step (priority)
            z: volume decrease step

     06 xyz Vibrato + Volume Slide.
            y: volume increase step (priority)
            z: volume decrease step

     07 xyz Tremolo.
            y: volume change speed (0 for previous speed)
            z: volume change depth (0 for previous depth)

     09 xxx Set Sample Offset.
            xxx: offset in sample DIV 128 (loop restarted if illegal)
                 0 for previous offset

     0A xyz Volume Slide + Fine Slide Up.
            x: value to add to pitch
            y: volume increase step (priority)
            z: volume decrease step

     0B xxx Position Jump.
            xxx: song position (0 if illegal)

     0C xyy Set Volume.
            yy: volume (0-64,rounded). Linear.

     0D xyy Pattern Break.
            yy: break position in next pattern (0-63, 0)

     0E xxx Not used.

     0F xxx Set Speed.
            xxx: speed (1-4095,ignored). Default is 6

     10 xxy Filter Control. (Not implemented)
            y: filter on (0) or filter off (1)

     11 xyy Fine Slide Up + Fine Volume Slide Up.
            x: value to add to volume
            yy: value to add to pitch

     12 xyy Fine Slide Down + Fine Volume Slide Up.
            x: value to add to volume
            yy: value to subtract from pitch

     13 xxy Glissando Control.
            y: on (1) or off (0) (use with Tone Portamento)
            When off, the slide is smooth else from halfnote to halfnote

     14 xxy Set Vibrato Waveform.
            y: sine (0), ramp down (1), square (2)
               bit 2 is off if wave form has to be restarted each note

     15 xxy Set Fine Tune.
            y: new fine tune value

     16 xxx Jump to Loop.
            xxx: jump to loop, play xxx times
                 if 0, the loop start is set to the current pattern position

     17 xxy Set Tremolo Waveform.
            y: sine (0), ramp down (1), square (2)
               bit 2 is off if wave form has to be restarted each note

     19 xxx Retrig Note.
            xxx: retrig note each (more or less) xxx vblanks

     1A xyy Fine Slide Up + Fine Volume Slide Down.
            x: value to subtract from volume
            yy: value to add to pitch

     1B xyy Fine Slide Down + Fine Volume Slide Down.
            x: value to subtract from volume
            yy: value to subtract from pitch

     1C xxx Note Cut.
            xxx: cut note after xxx vblanks (volume is only set to 0)

     1D xxx Note Delay.
            xxx: number of vblanks for note delay

     1E xxx Pattern Delay.
            xxx: delay pattern xxx notes

     1F xxy Invert Loop.
            y: speed
               if 0, it's turned off
               Care must be taken using it: it inverts the sign of sample
               data inside sample loop, one byte each vblank

     20 xyz Normal play or Arpeggio + Volume Slide Down.
            x: volume decrease step
            y: first halfnote to add
            z: second halftone to add

     21 xyy Slide Up + Volume Slide Down.
            x: volume decrease step
            yy: pitch increase step

     22 xyy Slide Down + Volume Slide Down.
            x: volume decrease step
            yy: pitch decrease step

     2A xyz Volume Slide + Fine Slide Down.
            x: value to subtract from pitch
            y: volume increase step (priority)
            z: volume decrease step

     2B xyy Line Jump.
            yy: Line to jump to in same pattern. (0-63, 0)

     2F xxx Set Tempo.
            xxx: new tempo value (1-4095,ignored).
                 Unit: 1/20th vblanks per second (defaults to 1000)

     30 xxy Set Stereo.
            if y and 7 =0 then xx = stereo position (0-127 is 0 to 127,
                                    129-255 is -1 to -127, 128 ignored)
            if y and 7 >0 then y = stereo position (1-7,ignored).
                               1=left 4=center 7=right

     31 xxx Song Upcall.
            The CPU performs a linked branch to the song upcall vector.
            The routine linked to that vector can corrupt all registers
            and must preserve SVC mode on return using MOVS PC,R14
            On entry registers contain the following:
            R0= xxx parameter
            R4= full note address + 4
            R5= voice number (0 to 7)

     32 xxx Unset Sample Repeat.
            The sample continues to be played until it ends, but without loops

2.1. Amiga ProTracker V1.1B Song/Module Format (Filetype &001)
     ---------------------------------------------------------
     Rem: files handled by Amiga ProTracker, NoiseTracker, SoundTracker,
          IntuiTracker, ...

     Offset  Bytes  Description
     ------  -----  -----------
        0     20    Songname. Trailing null bytes at the end.

     Information for sample 1-31:

     Offset  Bytes  Description
     ------  -----  -----------
       20     22    Samplename. Pad with null bytes.
       42      2    Length DIV 2. 
       44      1    Lower four bits: finetune value (signed 4 bits)
                    Upper four bits: not used (should be 0).
       45      1    Volume for sample 1. Range is &00-&40 (0-64).
       46      2    Repeat offset DIV 2.
       48      2    Repeat length DIV 2.

     Information for the next 30 samples starts here. It's just like the
     info for sample 1.

     Offset  Bytes  Description
     ------  -----  -----------
       50     30    Sample 2...
       80     30    Sample 3...
        .
        .
        .
      890     30    Sample 30...
      920     30    Sample 31...

     Offset  Bytes  Description
     ------  -----  -----------
      950      1    Songlength (1-128).
      951      1    Well... this little byte here is set to 127, so that old
                    trackers will search through all patterns when loading.
                    NoiseTracker uses this byte for restart, but we don't.
      952    128    Song positions 0-127. Each hold a number from 0-63 that
                    tells the tracker what pattern to play at that position.
     1080      4    The four letters "M.K." - This is something
                    Mahoney & Kaktus inserted when they increased the number
                    of samples from 15 to 31. If it's not there, the
                    module/song uses 15 samples or the text has been removed
                    to make the module harder to rip. Startrekker puts
                    "FLT4" or "FLT8" there instead. "M&K!" may be present,
                    too.

     Offset  Bytes  Description
     ------  -----  -----------
     1084    1024   Data for pattern 00.
        .
        .
        .
     xxxx  Number of patterns stored is equal to the highest pattern number
           in the song position table (at offset 952-1079).

     Each note is stored as 4 bytes, and all four notes at each position in
     the pattern are stored after each other.

     Position          Notes data
     -------- ------------------------------ 
        00    chan 1  chan 2  chan 3  chan 4
        01    chan 1  chan 2  chan 3  chan 4
        02    chan 1  chan 2  chan 3  chan 4
       etc.

     Info for each note:
     -------------------      
     bits 24-31: effect value (0-255).
          20-23: lower 4 bits of sample number (0-15).
          16-19: effect command number (0-15).
           8-15: lower 8 bits of note period (0-255).
           4- 7: upper 4 bits of sample number (0-1).
           0- 3: higher 4 bits of note period (0-3).

     Period table for Tuning 0, normal:
     ----------------------------------
       C-1 to B-1 : 856,808,762,720,678,640,604,570,538,508,480,453
       C-2 to B-2 : 428,404,381,360,339,320,302,285,269,254,240,226
       C-3 to B-3 : 214,202,190,180,170,160,151,143,135,127,120,113

     To determine what note to show, scan through the table until you find
     the same period as the one in the note. Use the index to look up in
     a notenames table.

     This is the data stored in a normal song. A packed song starts with the
     four letters "PACK".

     In a module, all the samples are stored right after the pattern data.
     To determine where a sample starts and stops, you use the sample info
     structures in the beginning of the file (from offset 20). Their format
     is linear signed.

     ProTracker CIA (Complex Interface Adapter) Timer Tempo Calculations
                                      AMIGA
     -------------------------------------------------------------------
     Fcolor                        = 4.43361825 MHz (PAL color carrier freq)
     CPU Clock   = Fcolor * 1.6    = 7.0937892  MHz
     CIA Clock   = CPU Clock / 10  = 709.37892  kHz
     50 Hz Timer = CIA Clock / 50  = 14187.5784
     Tempo num.  = 50 Hz Timer*125 = 1773447

     For NTSC: CPU Clock = 7.1590905 MHz --> Tempo num. = 1789773

      To calculate tempo we use the formula: TimerValue = 1773447 / Tempo
      The timer is only a word, so the available tempo range is 28-255 (++).
      Tempo 125 will give a normal 50 Hz timer (VBlank).

      A normal ProTracker VBlank song tempo can be calculated as follows:
      We want to know the tempo in BPM (Beats Per Minute), or rather quarter-
      notes per minute. Four notes makes up a quarternote.
      First find interrupts per minute: 60 seconds * 50 per second = 3000
      Divide by interrupts per quarter note = 4 notes * speed
      This gives: Tempo = 3000/(4*speed)
      Simplified: Tempo = 750/speed
      For a normal song in speed 6 this formula gives: 750/6 = 125 BPM
      
      Note: The mentioned 50 Hz quantities are rather inaccurate since the
            vblank frequency is exactly 49.9 Hz!

2.2. Archimedes Tracker V1.0+++ File Formats
     ---------------------------------------
     
     Sample chunk format
     -------------------
     This is the component of a Tracker sample file (Filetype &CB5).
     
       Field length Contents
       ------------ --------
          4 bytes   The string "SAMP"
          4 bytes   Chunk length (i.e. total size -8)
          4 bytes   The string "SNAM"
          4 bytes   Sample name length (20)
         20 bytes   Sample name padded with zero's
          4 bytes   The string "SVOL"
          4 bytes   Value 4
          4 bytes   Sample volume (0-255). Logarithmic
          4 bytes   The string "SLEN"
          4 bytes   Value 4
          4 bytes   Sample length (multiple of 4 otherwise Tracker crashes!)
          4 bytes   The string "ROFS"
          4 bytes   Value 4
          4 bytes   Repeat offset
          4 bytes   The string "RLEN"
          4 bytes   Value 4
          4 bytes   Repeat length
          4 bytes   The string "SDAT"
          4 bytes   Sample length (multiple of 4): xx
         xx bytes   Sample data in logarithmic format

       Note: the manual states that not all sub-chunks may be present. But
             until now they've always been there.

     Pattern chunk format
     --------------------
     This is the component of a Tracker pattern file (Filetype &FF1).
     
       Field length Contents
       ------------ --------
          4 bytes   The string "PATT"
          4 bytes   Chunk length (i.e. number of voices * 256 - the manual
                    says it's always 2048, that's false! ): xx
         xx bytes   Notes

         Each note is stored as 4 bytes, and all x notes at each position in
         the pattern are stored after each other.
     
         Position         Notes data
         -------- ---------------------------
            00    chan 1  chan 2  ...  chan x
            01    chan 1  chan 2  ...  chan x
            02    chan 1  chan 2  ...  chan x
           etc.

         Info for each note:
         -------------------      
         bits 24-31: note number (0-36).
              16-23: sample number (0-36).
               8-15: effect command number.
               0- 7: effect value (0-255).
     
         Note numbers table:
         -------------------
           C-1 to B-1 : 01 to 12
           C-2 to B-2 : 13 to 24
           C-3 to B-3 : 25 to 36

     Module format
     -------------
     This is the format of a Tracker module file (Filetype &CB6).
     
       Field length Contents
       ------------ --------
          4 bytes   The string "MUSX"
          4 bytes   Chunk length (i.e. total size -8)
          4 bytes   The string "TINF"
          4 bytes   Value 4
          4 bytes   Date of version in BCD format: YYYYMMDD (bytes 1 to 4)
          4 bytes   The string "MVOX"
          4 bytes   Value 4
          4 bytes   Number of voices (1-8)
          4 bytes   The string "STER"
          4 bytes   Value 8
          8 bytes   Default stereo positions for 8 channels. See the command.
          4 bytes   The string "MNAM"
          4 bytes   Tune name length (32)
         32 bytes   Tune name padded with zero's
          4 bytes   the string "ANAM"
          4 bytes   Author name length (32)
         32 bytes   Author name padded with zero's
          4 bytes   the string "MLEN"
          4 bytes   Value 4
          4 bytes   Tune length (1-128)
          4 bytes   the string "PNUM"
          4 bytes   Value 4
          4 bytes   Number of defined patterns (1-64)
          4 bytes   the string "PLEN"
          4 bytes   Value 64
         64 bytes   Length of each pattern (0-64)
          4 bytes   the string "SEQU"
          4 bytes   Value 128
        128 bytes   pattern number to be played at each position (0-63)

       This is followed by a pattern chunk for each defined pattern.
       After that, there is a sample chunk for each of the 36 samples.

       Note that such a file can contain more than one module (MUSX chunk)
       but practically it's very rare and not easy to handle...

       Such a format for a music module is a bit silly since nearly all
       chunks have a constant length.
   
2.3. Archimedes Symphony Module/Song Format
     --------------------------------------
     Such tunes are composed of a list of positions which refer to the
     pattern that has to be played through a given channel at that song
     position. It's possible to play nothing instead of a pattern.

     The ranges are as follows:
     --------------------------
     Voices: 1 to 8
     Tune length: 0 to 4096 (&1000)
     Pattern number: 0 to 4095 (&FFF)
     
     A pattern is composed of 64 notes.

     Each note is stored as 4 bytes (A 32 bit-word), and of course all notes
     are stored after each other.

     Position Notes data
     -------- ----------
        00      chan i
        01      chan i
        02      chan i
       etc.
     
     Info for each note:
     -------------------
     bits 20-31: effect value (0-4095).
          14-19: effect command number (0-63).
          13-13: not used for now (should be 0).
           6-12: sample number (0-63).
           0- 5: note number (0-36).

     Note numbers table:
     -------------------
       C-1 to B-1 : 01 to 12
       C-2 to B-2 : 13 to 24
       C-3 to B-3 : 25 to 36

     Note: the use of [x,y] in the following specs refers to the revision
           number x and file version y in which the feature first appeared
           (see top of this file)
     Note2: Any program that would like to read Symphony files should test
            the version number and give an error if greater or equal to 10.
            The difference between version 0 and 1 is that a version 1 file
            MAYBE uses the new packing methods as standard. So read the file
            and check if you know the packing methods used.
     Note3: You may notice that the space taken by a soundtrack can be
            computed without reading the whole file.

     Sample file format (Filetype &10A: SySample)
     --------------------------------------------
       Field length Contents
       ------------ --------
          8 bytes   The string "BASSSAMP". Byte value= ASCII code - 64
          1 byte    Version number (currently 1)
          1 byte    Name length: xx
         xx bytes   Name
          3 bytes   Length DIV 2 (length= number of samples, not bytes)
          3 bytes   Repeat offset DIV 2
          3 bytes   Repeat length DIV 2
          1 byte    Packing method
         sy bytes   Data:
                    Packing=0 : 8-bit logarithmic (sy=length)
                    Packing=1 : 13-bit LZW applied to linear sample data
                                differences (sy multiple of 4)
                    Packing=2 : 8-bit linear signed (sy=length)       [1,0]
                    Packing=3 : 16-bit linear signed (sy=length*2)    [2,1]
                                (little endian)
                    Packing=4 : SigmaDelta compression applied to     [2,1]
                                linear sample differences
                    Packing=5 : SigmaDelta compression applied to     [2,1]
                                logarithmic sample differences
        0-3 bytes   Zero's to fill last file word

     Pattern file format (Filetype &FFD: Data)
     -----------------------------------------
       Field length Contents
       ------------ --------
          8 bytes   The string "BASSPTRN". Byte value= ASCII code - 64
          1 byte    Version number (currently 0)
          1 byte    Contents: 0 for a sequence, 1 for some patterns
        0-1 byte    Number of sequence lines (only if Contents=0): z
          2 bytes   Length: number of sequence positions
                    or number of patterns: xx
         yy bytes   Data:
                    Contents=0 : For each line
                                     For xx positions
                                         Pattern number (2 bytes each)
                                 (yy=2*xx*z)
                    Contents=1 : patterns data (yy=256*xx)

     Module/Song file format (Filetype &10B: Symphony)
     -------------------------------------------------
       Field length Contents
       ------------ --------
          8 bytes   The string "BASSTRAK". Byte value= ASCII code - 64
          1 byte    Version number (currently 1)
          1 byte    Number of voices (1 to 8): z
          2 bytes   Track length in positions: y (0 to &1000)
          2 bytes   Number of defined patterns: p (0 to &1000)
          3 bytes   Information text length: il

          For the 63 samples, we have:

       (  1 byte    Sample name length: sn
       (            (bit 7 set if all its data is blanked: lengths, vol, ft)
       (            (bit 6 reserved => mask out to read / write 0)
       (  3 bytes   Sample length DIV 2 (length= number of samples, not bytes)

          1 byte    Track name length: x
          x bytes   Track name
          8 bytes   Effects allowed table. 1 bit per effect (0=no, 1=allowed)
      If y>0 then
        ( 1 byte    Packing system for sequence (0= not packed, 1= packed)
        ( s bytes   Sequence data:
        (           Packing=0 : For each position
        (                           For each voice
        (                               Pattern number (2 bytes)
        (                       (s= 2*y*z)
        (           Packing=1 : 13-bit LZW applied to overall sequence data
        (                       (s multiple of 4)

      If p>0 then
        ( For each pk-pattern chunk (all 2000 patterns but the last):
        (       1 byte  Packing system for chunk (0= not packed, 1= packed)
        (       b bytes Pattern data:
        (               Packing=0 : For each pattern
        (                             For each pattern position (0 to 63)
        (                               Full note value (1 word)
        (                           (b= 4*64*pk)
        (               Packing=1 : 13-bit LZW applied to chunk data
        (                           (b multiple of 4)

          For the 63 samples, we have:

       ( sn bytes   Sample name
       (  3 bytes   Sample repeat offset DIV 2
       (  3 bytes   Sample repeat length DIV 2
       (  1 byte    Sample volume (0 to 64)
       (  1 byte    Sample fine tune (-8 to 7)
       (  1 byte    Packing system for sample (see sample file format)
       (
       ( If sample length>0 then
       (   ( sy bytes Data: see sample file format above

      If il>0 then
        ( 1 byte    Packing system for information text
        (           (0= not packed, 1= packed)
        ( i bytes   Information text:
        (           Packing=0 : Text (i=il)
        (           Packing=1 : 13-bit LZW applied to information text
        (                       (i multiple of 4)

        0-3 bytes   Zero's to fill last file word


    Notes about compression algorithms:

    - Sample differences are computed like this:
      Init: x=0; p=sample start
      Loop: difference= value(p)-x; x= value(p); inc(p)
    - The 13-bit LZW compression scheme uses 256/257 as restart/end code.
      Applied on signed linear sample deltas.
    - The SigmaDelta compression is rather too complex to explain here!
      Applied on unsigned linear or unsigned logarithmic sample deltas.

    Maybe next time we'll provide some algorithms...
    


        PART II : Digital Symphony SWI's and commands information


The following explains the functionalities used in the 1 music-player module
(the one generated by the Digital Symphony application) and in the
multi music player module (files DSymPlay and DSymPlayA3). The file DSymPlayA3
only differs from the file DSymPlay in that only the routines used whenever
a cached processor (e.g. ARM3) is detected are present in it, so you gain
some Kbytes space (~16K) but have slower routines when used with non-cached
processors (e.g. ARM2, ARM250).

THESE MODULES ARE FREEWARE. If you use it in a NON COMMERCIAL program (we
strongly encourage it) then all we ask is:
  - In all cases, give some credits to BASS for the playroutine.
  - If the play module stays as a stand-alone module in your app directory,
    then include this text file unaltered too.
If you wish to use them in some commercial software then contact
Oregan Developments for an agreement. See the end of this file for addresses.

Now more technical details.

In order to keep the code size low and the CLI command name space clean, this
player only offers SWI's. But hopefully a CLI command gives access directly
to these SWI's for the CLI user.

Nearly all SWI's should never be used while interrupting the player routine
(i.e. they're not reentrant). See the SWI that allows to know if the player
routine has been interrupted or not.

You can call a SWI via this * command:

  *DSym <SWI name> [<R0 value> [<R1 value> [<...>]]]

  Of course you can't get results back this way.
  The unspecified values are set to 0 before calling the corresponding SWI.

  A value may be:
    - Any string readable by the OS_ReadUnsigned SWI (see the PRM's).
    - The latter string preceeded by the minus sign for a negative number.
  You can specify a pointer to a string (i.e. when a file name is required)
  only for R0 value: just put the string between quotes.

Some examples:
  Set the overall volume to 64: *DSym Vol 64
  Load file $.MegaMix: *DSym Load "$.MegaMix"
  Set stereo of channel 2 to -127: *DSym Stereo 2 -&7F

Instead of installing the player module in RMA (that requires to ensure
there's enough memory free in RMA, very annoying in demos), you could
directly patch the module into your code. There are 2 ways to do this:

 - Link it to modules chain in RMA using OS_Module 10 (See the PRM's). The
   SWI's are always available. Don't forget to kill it before returning to
   desktop!

 - Don't link to other modules. The SWI's are not directly available.
   Let's assume ModStart to be the start address of the player module in
   your code. First you must call (ModStart+(ModStart!4)) like RISC OS
   would do when loading a module. Now you can use SWI's by calling a
   special routine with R11 containing the SWI number. For example, set the
   volume to 64 with:

               MOV R0,#64        ; SWI parameter
               MOV R11,#2        ; SWI number
               BL  ModStart+44   ; Note: need NOT be in SVC mode

   Finally don't forget to call (ModStart+(ModStart!8)) before your
   program exits.


The advantages of using a generated 1 music-player are as follows:
  - Only the useful routines are included. E.g. the rather big loader routine
    is not included.
  - The tune data is arranged to get more efficient results through
    compaction. In fact, samples are stored as linear deltas.
  - Several parameters can be set by default at module installation, such as
    looping, play or not when module installed...

Also an advantage in the multi music-player from version 1.40 on:
    At module's installation (or song loading for the multi-player), the
    samples data are scaled to the current configured volume of the machine.
    This gives more chances that the efficient sound buffer filling routines
    in the case of no scaling are used. It's of no help if the global volume
    is not at maximum or a sample is not played at full volume.
    WARNING here: when using the InstrData SWI, the newly installed sample
    is scaled too, so avoid calling twice with exactly the same parameters
    without refreshing the real sample data!

The SWI's allow you to play tunes in your own programs and making sound
effects. While the tune is playing you can make additional sound effects
(produce 'custom notes') in the same way the tune does. In fact, you could
play a tune by producing notes stored in your own tables.
If you'd like to play your notes while the tune is playing, you can do it
on the voices used by the tune, but with some tunes there can be some clashes
with samples and notes (this is ONLY a matter of nice sound and NOT a matter
of bugged routines). So it's preferable to play them on the free voices
(the ones with the highest numbers). For example, with a tune with 3 rows
in its sequence and 4 configured voices, you could safely play your notes on
the 4th voice.

Useful example:
---------------
Prototype for playing a song in a usual program:

    SYS"DSym_Load","<Prog$Dir>.Music" :REM Load song in RMA
    SYS"DSym_RestartSong"             :REM Start playing
    REPEAT
    REM Main loop
    UNTIL exit%
    FOR v%=64 TO 0 STEP -1            :REM Fade out
      SYS"DSym_Vol",v%
      WAIT
    NEXT
    *RMKill DSymphonyPlayer

To stop a tune: SYS"DSym_Pause"
To continue after a stop: SYS"DSym_TuneControl",1 or SYS"DSym_RestartSong" to
restart.

Some other possible effects:
  - Engine noises, changing volume and finetune (see effects 11 & 12).
  - Manipulate a lot of samples without loading new tunes, using the InstrData
    SWI.
  - ...

More technical details:
-----------------------
SWI Chunk name: DSym
SWI Chunk base number: &45880 (allocated from Acorn)

Should work on A5000's and some VIDC enhancers (i.e. no pitch bending)
without any additional code. See SWI to set hardware speed.

SWIs DSym_Load and DSym_LoadInstr do not work in the 1 music-player.

The player can only load Digital Symphony format files because it would eat
too much memory (makes me think of other players...). It was designed to
be as 'simple' as possible. It cannot read 16-bit samples.

The player does NOT use the VIDC pointer.

The player does NOT use WAIT's.

The player does use OS_ReadMonotonicTime only:
  - When calling DSym_Configure, DSym_Load or the module finalisation entry.
  - In the buffer filling routine when in 'auto speed' mode (in order to
    'guess' the current VIDC speed) (see SWI HardSpeed)
So let the interrupt for the corresponding timer enabled in those cases.

The FillAddress SWI allows you to know the address of the buffer filling
routine (you could get it with Sound_Configure but it's easier here).
If you feel pretty good you could then call it yourself instead of RISC OS
each time a sound interrupt occurs. You must call DSym_Configure at least
once before using the filling routine.

The specs for the filling routine:

   Entry: R12 points to buffer to fill (word-aligned, length=1664 bytes)
          Processor in IRQ mode
          IRQ disabled
   Exit:  R0-R12,R14 and flags corrupted
          Processor in IRQ mode
          IRQ disabled
          Buffer filled for the number of configured voices (208 bytes/voice)
   The routine enables IRQ's during its work.

You are expected to make no mistakes when passing parameters to SWI's. If
you do, it's possible that the machine locks up! (Remember: the player is
powerful but simple)

Note: There are two SWI's to set the stereo positions. A front-end
      application that sets the current stereo should set the DEFAULT stereo
      too.
Note2: In the following specs, no reference to a register on exit means
       it is preserved.
Note3: It is recommended that you set the sample quality (SampleRate SWI)
       to something other than the default 24. 24 is usually not convenient
       when CPU power is needed for other things than music. This is
       especially true if it has to run on an ARM2.
Note4: The terms 'custom note buffer' and '1-entry-per-voice buffer' used
       below refer to the buffer used to store notes triggered by some SWI's
       below before they are really played by the interrupt routine. Two
       notes played just one after each other probably means that only the
       lastest one will be taken into account. Some SWI's allow you to solve
       that problem by controlling the empty state of the buffer.

If not specified otherwise registers on SWIs exit are preserved.

And now the specs of the SWIs...


DSym_Load (SWI &45880)

             Load a Digital Symphony module

On entry     R0= -1 to free possibly claimed RMA buffers
          or R0=  0 to load from memory
          or R0=  pointer to file name to load

             R1= address to load from (if R0=0)

             R2= 0 to load into RMA
          or R2= start address of buffer to load module to.

             R3= size of destination buffer (if R2<>0)

             R4= 0 to claim decompression buffer in RMA
          or R4= start address of decompression buffer (32K space)

On exit      R0= length of track in memory
          or R0 points to standard error block and V is set

Use          This allows you either to free the space used by a tune or
             load a Digital Symphony track from a file or from memory.

Remarks      - A decompression buffer is needed only if the Symphony track
               contains packed data.
             - Buffers are word aligned.
             - In the case of packed data, the source and destination
               buffers memory can't overlap. In the case of entirely
               non-packed data, the two buffers can share a part of memory
               provided destination address <= source address. After the call
               the source data has been altered because the module needs to
               build an internal structure different to the source structure
               of the tune.
             - Although the code is quite optimized, loading from memory may
               take some time because all the data has to be moved in memory.
               So don't expect loading 50 songs per second with an ARM2!


DSym_RestartSong (SWI &45881)

             Restart the current song

On entry     -

On exit      A DSym_ResetParams is performed, the song position is reset to
             the beginning (0,0) and the song replayed.

Use          This is used to either start or restart playing a song.


DSym_Vol (SWI &45882)

             Set/read the current overall volume

On entry     R0= -1 to read overall volume
          or R0= new overall volume (0-64)

On exit      R0= previous overall volume (0-64)

Use          This is used to either set or read the overall volume. Real-time
             fades on the music may be done using this.

             The initial volume is 64.


DSym_Stereo (SWI &45883)

             Set/read stereo position

On entry     R0= voice number (0-7)
             R1= -128 to read stereo position
          or R1= new stereo position

On exit      R1= previous stereo position (-127 to 127) for voice number R0.

             Initial values are those of the Amiga.


DSym_CutNote (SWI &45884)

             Set/read sample status of a voice

On entry     R0= voice number (0-7)
             R1>=0 to read state
          or R1< 0 to stop note

On exit      R1= previous note state on voice number R0
                     < 0 -> stopped
                     >=0 -> playing, = sample start address
             If R1>=0 then
               R2= offset in sample in 1/(2^12) units


DSym_PlayInstrPacked (SWI &45885)

             Play an instrument (short version)

On entry     R0= voice number (0-7)
             R1= full note data (as found in a pattern)
             R5= minimum sustain time (in 1/50th sec)
             R6<>0 to wait for buffer empty else don't wait

On exit      The new note is put into a 1-entry-per-voice buffer to be played.
             Setting a sustain time means that the new note has precedence over
             the tune notes during this time period.


DSym_PlayInstr (SWI &45886)

             Play an instrument

On entry     R0= voice number (0-7)
             R1= note number (0-36)
             R2= sample number (0-63)
             R3= effect number (0-63)
             R4= effect value (0-&FFF)
             R5= minimum sustain time (in 1/50th sec)
             R6<>0 to wait for buffer empty else don't wait

On exit      The new note is put into a 1-entry-per-voice buffer to be played.
             Setting a sustain time means that the new note has precedence over
             the tune notes during this time period.


DSym_ResetParams (SWI &45887)


On entry     -

On exit      All parameters are reset (stereo, counters, effects,...)
             A FlushOutput is done.


DSym_FlushOutput (SWI &45888)


On entry     -

On exit      The current notes on all channels are cut.


DSym_FreezeOutput (SWI &45889)

             Set/read output status

On entry     R0= -1 to read output status
          or R0= new output status

On exit      R0= previous output status
                  = 0 -> off i.e. no sound output
                  <>0 -> on


DSym_UpCallVector (SWI &4588A)

             Set/read upcall vector address

On entry     R0= -1 to read upcall address
          or R0= -2 to set default upcall address
          or R0= new upcall address

On exit      R0= previous upcall address


DSym_MaskVoice (SWI &4588B)

             Set/read mask status of a voice

On entry     R0= voice number (0-7)
             R1= -1 to read voice status
          or R1= new voice status

On exit      R0= previous voice status
                  = 0 -> off (notes are still played but not heard)
                  <>0 -> on


DSym_SongPos (SWI &4588C)

             Set/read song positions

On entry     R0= -1 to read sequence position
          or R0= new sequence position
             R1= -1 to read pattern position
          or R1= new pattern position

On exit      R0= previous sequence position
             R1= previous pattern position (0-63)

Remarks      If the pattern position is changed this new position is played
             at the next tick (if the tempo is slow this may take some time).


DSym_TuneControl (SWI &4588D)

             Set/read tune replay status

On entry     R0= -1 to read status
          or R0= new status (lower byte)

On exit      R0= previous tune status
                   <>0 -> on
                   = 0 -> off i.e. the tune decoder is off, you can still
                          play custom notes.

Remarks      If the status goes to off current notes are not cut.


DSym_Pause (SWI &4588E)

             Pause song

On entry     -

On exit      The song is stopped and current notes on the song voices are cut.


DSym_Voices (SWI &4588F)

             Set/read number of hardware voices

On entry     R0= -1 to read number of hardware voices
          or R0= new number of hardware voices (1,2,4 or 8)

On exit      R0= previous number of hardware voices

Remarks      The change is taken into account during the next configure.
             The initial number of voices is 4.


DSym_Wait (SWI &45890)

             Read custom note buffer emptyness of a voice

On entry     R0= voice number (0-7)

On exit      C is set if custom note buffer of this voice is not empty,
             clear otherwise.


DSym_IntState (SWI &45891)

             See if current process has interrupted sound routines

On entry     -

On exit      C is set if the call has interrupted note decoding or sound
             filling routines,
             clear otherwise.


DSym_NoteInfo (SWI &45892)

             Read information on notes currently playing

On entry     -

On exit      R0= address of current notes table (1 word per voice)
                 note is 0 to 1023
             R1= address of current samples table (1 byte per voice)
                 sample is 0 to 63
             R2= address of effects table (1 word per voice)
                 effect is: bits 30-31 meaningless
                            bits 16-21 effect nr
                            bits  0-11 effect value
             R3= address of volumes table (1 byte per voice)
                 volume is 0 to 64


DSym_VuBar (SWI &45893)

             Read Vu bar of a voice

On entry     R0= voice number (0-7)

On exit      R1= Vu bar height (0-64)


DSym_Loop (SWI &45894)

             Set/read loop control and flag

On entry     R0= -1 to read loop control
          or R0= new loop control
             R1= -1 to read loop flag
          or R1= new loop flag

On exit      R0= previous loop control
                   = 0 -> looping enabled
                   <>0 -> looping disabled
             R1= previous loop flag
                   = 0 -> song has not looped
                   <>0 -> song has looped

Remarks      Loop control is initially enabled.
             If a song has looped and the loop is disabled, you can
             resume playing using TuneControl.


DSym_BufferAddress (SWI &45895)

             Read current hardware sound buffer address

On entry     -

On exit      R0= current hardware sound buffer address of system (with output
                 data interleaved, 208 bytes per voice). This buffer is the
                 latest to have been filled. Typically the system uses two
                 buffers alternatively.


DSym_VuGravity (SWI &45896)

             Set/read Vu bars gravity

On entry     R0= -1 to read Vu gravity
          or R0= new Vu gravity (lower byte)

On exit      R0= previous Vu gravity (0-255)

Remarks      The change is taken into account during the next configure.
             The initial gravity value is 2.


DSym_SampleRate (SWI &45897)

             Set/read sample rate (quality)

On entry     R0= -1 to read sample rate
         or  R0= new sample rate

On exit      R0= previous sample rate (0-99). Determines sample output density
                 and the output quality also.

Remarks      The change is taken into account during the next configure.
             The initial sample rate is 24, i.e. 24 s between samples. This
             is a quite high quality setting.


DSym_Configure (SWI &45898)

             Configure sound system

On entry     R0= -1 to reinstall previous system configuration
          or R0<>-1 to configure the system with selected voices number,
                    sample rate, Vu gravity and hardware speed.

On exit      -


DSym_Params (SWI &45899)

             Read song replay temporal information

On entry     -

On exit      R0= current song speed (1-&FFF)
             R1= current song tempo (1-&FFF)
             R2= current tick counter value (0-&FFE)
                 The counter varies from 1 to speed-1 at a speed
                 according to tempo (50 times a second for default tempo).
                 When the counter goes beyond its maximum value it is reset
                 and a new pattern position is selected for play.


DSym_TuneInfo (SWI &4589A)

             Read tune information

On entry     -

On exit      R0= tune length (number of sequence positions)
             R1= number of patterns
             R2= number of voices in song
             R3 to R7 corrupted


DSym_PlaySingle (SWI &4589B)

             Start playing a single pattern or a range of patterns

On entry     R0= -1 to play pattern R1 or return to normal play
          or R0= sequence position to start playing at
             R1= -1 to return to normal play if R0= -1
             R1= pattern to play if R0= -1
          or R1= last sequence position to play if R0<>-1
             R2= -1 to disable looping
          or R2<>-1 to enable looping

On exit      -

Remarks      The pattern position is reset to 0.
             In the case of playing a part of the sequence, the current
             position is set to the first position in that part.


DSym_DefaultStereo (SWI &4589C)

             Set/read default stereo position of a voice

On entry     R0= voice number (0-7)
             R1= 0 to read default stereo
          or R1= new default stereo

On exit      R1= previous default stereo position (1 to 7) for this voice

Remarks      Initial values are those of the Amiga.


DSym_InstrData (SWI &4589D)

             Set/read instrument information

On entry     R0= sample slot number (1-63)
                   bit 31 clear -> convert sample data if needed
                   bit 31 set   -> do not convert sample data
             R1= -1 to read sample data address
          or R1= new sample data address
                   bit 31 clear -> data is in VIDC1 format
                   bit 31 set   -> data is signed linear
             R2= -1 to read sample length
          or R2= new sample length
             R3= -1 to read repeat offset
          or R3= new repeat offset
             R4= -1 to read repeat length
          or R4= new repeat length
             R5= -1 to read volume
          or R5= new volume (0-64)
             R6= -1 to read finetune
          or R6= new finetune (0-15)

             R1 to R4 must be 2-byte aligned.
             Put a repeat length of 0 for no repeats.
             Repeat length can't be 2.

On exit      R1= previous sample data address
             R2= previous sample length
             R3= previous repeat offset
             R4= previous repeat length
             R5= previous volume
             R6= previous finetune

Remarks      If the sample data address is changed then the sample data is:
                - scaled to the current machine volume
                - converted to VIDC format if it is signed linear
             These conversions affect the sample data in place.

             However if bit 31 of R0 is set conversions do not occur. This
             would be used e.g. if the sample data was already previously
             converted with this call or if the sample comes from a read-only
             location. If you misuse this flag with a signed linear sample
             the mistake will be obvious. However with VIDC samples the
             mistake is not so obvious because it depends on the current
             configured volume. So beware.


DSym_HardSpeed (SWI &4589E)

             Set/read hardware sound frequency

On entry     R0=-1 to read output frequency
          or R0= 0 to enable frequency auto-detection
          or R0= new output frequency (in kHz)

On exit      R1= previous hardware frequency (in kHz)

Use          This is used to tell the buffer filling routine to adjust the
             speed it outputs samples to the hardware speed.

Remarks      The change is taken into account during the next configure.
             The initial frequency is 24000kHz.

             In 'auto detection' mode, the filling routine will try to
             guess the current VIDC frequency for outputting samples
             by averaging the number of calls to it and adjust its
             tables so that the same real pitch is produced whatever the
             hardware speed is. The 'auto detection' selects one of the
             three following speeds currently:

                 24000 kHz (normal modes)
                 25175 kHz (VGA modes)
                 36000 kHz (multi sync modes)

             However the auto-detection is currently only 99% reliable.

             This is of no use on the RiscPC since the sound output speed
             is independent from the graphic mode.
             Too bad to have the same clock for graphics and sound in
             pre-RiscPC machines!


DSym_LoopType (SWI &4589F)

             Set/read loop type

On entry     R0= -1 to read loop type
          or R0= new loop type

On exit      R0= previous loop type
                   =0 -> The loop flag is set if the song reaches position 0.
                   =1 -> The loop flag is set if the song jumps to a lower
                         sequence position position.


DSym_FillAddress (SWI &458A0)

             Read address of buffer filling routine

On entry     -

On exit      R0= address of buffer filling routine


DSym_AddInternalInstr (SWI &458A1)

             Associate an instrument slot to an instrument in internal format

On entry:    R0= sample slot number (1-63)
             R1= address of instrument to add (word-aligned)

On exit:     The instrument is linked to the slot. The block must remain there
             while the instrument is in use. The block is unaltered so may
             be reused later.

Use:         The instrument to add is in internal format. It is a relocatable
             block of data produced with DSym_LoadInstr and defined as follows:

                +0  : total length of block (word-aligned)
                +4  : sample data length (multiple of 2)
                +8  : repeat offset
                +12 : repeat length
                +16 : volume (0-64)
                +20 : finetune (-8 to 7)
                +24 : reserved (should be 0)
                +28 : sample data in VIDC format
                possible word alignment

             This operation is performed fast so you can use it to dynamically
             change samples of a song if you don't have enough with 63 slots.
             On exit the block you pass in R1 is unaltered.


DSym_LoadInstr (SWI &458A2)

             Load a Symphony instrument to memory

On entry:    R0= pointer to source file name
          or R0= start address of source data (word-aligned)
             R1= 0 to load from file
          or R1= 1 to load from memory
                   bit 31 clear -> load instrument
                   bit 31 set   -> do not load
             R2= destination address (word-aligned)
             R3= decompression buffer address (32K space)

On exit:     R0 preserved and V clear
          or R0 points to standard error block and V set
             R3= length of instrument in memory

Use:         The instrument is loaded from the specified file or memory address
             into the block pointed to by R2. The produced block is in internal
             format with default volume and finetune (see SWI
             DSym_AddInternalInstr). Bit 31 of R1 may be set to not load the
             instrument but only compute the length of the destination block
             to use.
             The sample data is scaled to the machine current volume if the
             current song was not in internal format when loaded.
             The decompression buffer is only needed if the sample is
             compressed using one of the two compression variants. In practice
             this variant is rarely used.


DSym_LoadInternal (SWI &458A3)

             Load a song in internal format

On entry:    R0= pointer to song block in internal format

On exit:     -

Use:         The player is updated so that the song pointed to by R0 becomes
             the current one. On exit the block is unaltered so it can
             live in read-only memory.
             This operation is performed relatively fast.
             The song must be in internal format. You should find the program
             to convert a song in Symphony format to internal format near
             this help file.



So, with such a tool in the hands of (good) demo and game writers, we hope
to see more and more demos and games with decent (if not very good) sound,
and never listen again to the horrible *noises* made by previous (and some
current) lamer samples and SoundTrackers replayers!!!

Before giving our addresses, we'd like to thank the following people/groups
for their constructive remarks and questions and bug reports concerning
this player:

                                 SICK

                               ARMAXESS

                            George Saliaris

                             Mirko Vidovic

If you find any bug or have any comment about this player or even Digital
Symphony, don't hesitate to contact us at one of the addresses below:

        +----------------------------------------------------------------+
        !       You can contact the guys who made this software at       !
        +--------------------------+-------------------------------------+
        !    Bernard Jungen        !    Gil Damoiseaux                   !
        !    Friddericht 27        !    Rue du Bois des Broux 5          !
        !    B-6706 Autelbas       !    B-5080 Rhisnes                   !
        !    Belgium               !    Belgium                          !
        !                          !                                     !
        ! E-mail (until end 1999): !                                     !
        !    bju@fun.cediti.be     !                                     !
        +--------------------------+-------------------------------------+

                      +----------------------------------+
                      ! John Tytgat                      !
                      ! Brusselbaan 445                  !
                      ! B-1600 St.-Pieters-Leeuw         !
                      ! Belgium                          !
                      !                                  !
                      ! E-mail:                          !
                      !  john.tytgat@barco.com           !
                      +----------------------------------+

If you would like to use our play routines in commercial products, or simply
want to buy Digital Symphony itself, then contact:

   +-------------------------------------------------------------------+
   ! You can obtain a fully multi-tasking sound tracker editor, called !
   ! Digital Symphony, which takes ProTracker, (Octo)MED, Tracker,     !
   !        Coconizer and native Symphony files as input from          !
   +-------------------------------------------------------------------+
   !                      Oregan Developments,                         !
   !                  36 Grosvenor Avenue, Streetly,                   !
   !                   Sutton Coldfield B74 3PE,                       !
   !                           England.                                !
   !              Tel: 0121 353 6044   Fax: 0121 353 6472              !
   !                E-mail: support@oregan.demon.co.uk                 !
   +-------------------------------------------------------------------+

 1992/1997 B. Jungen & G. Damoiseaux (members of BASS).
