The SCI01+ sound resource format

Originally written by Rickard Lind, 2000-01-05
Extensively rewritten by Lars Skovlund, 2002-10-27
Again updated by Lars Skovlund, 2005-10-12

Used in:
Quest for Glory II: Trial by Fire (QfG2)
Christmas greeting card 1990 (CC1990)

The magic number (84 00) is left out, offset 0 is directly after these two
bytes.

If you examine a SCI01 sound resource use "sciunpack --without-header" to
get the pointers within the file correct for your hex viewer.

DESCRIPTION
-----------

The SCI01 sound resource consists of a number of track lists and the
tracks themselves. There is one track list for (almost) every piece of
sound hardware supported by the game. Each track either contains track
data for one specific channel or a digital sample.

SCI1 resources are the same, except that sample chunks are no longer
allowed (since they are now separate resources).

  Optional Priority Header
  ------------------------

  Some SCI1 songs contain an 8-byte header before the track list. At
  least on PC platforms, its data is mostly unused. The priority value
  is used if the script does not override it.

  offset   size         description
    -------------------------------------------------------
      0	   byte		0xf0 Priority header marker byte
      1    byte		Recommended priority for this song
      2    6 bytes	Apparently unused

  Track List
  ----------

  The track list tells us which tracks are to be played on particular
  hardware platforms. Each entry either terminates the previous list
  or contains an entry for the current one.

  List Termination
  ----------------

    offset size description
    -----------------------
      0    byte 0xff
      1    byte Hardware ID of next list, 0xff if none

  List Entry
  ----------

    offset size description
    -----------------------
      0	   byte 0
      1    byte 0
      2    word Data Chunk pointer
      4    word Data Chunk size

    The very first list in a file looks a little odd, in that it
    starts with a single byte which tells us the hardware ID
    associated with the first list (0 in all the cases I've seen)
    followed by list entries as usual.

    Known Hardware IDs
    ------------------

    Some of these are used by multiple drivers, probably because they
    support the same number of polyphonic voices. Note that the
    hardware ID does not necessarily tell us whether samples are
    supported - thus, the list for Roland MT-32 also contains sample
    tracks, because the user may also have a Sound Blaster card
    connected. SCI1 most likely has more hardware IDs than these.

    0x00 - Sound Blaster, AdLib
    0x06 - MT-32 with Sound Blaster (for digital audio)
    0x09 - CMS/Game Blaster
    0x0c - Roland MT-32
    0x12 - PC Speaker
    0x13 - IBM PS/1, Tandy 3-voice

  Data Chunks
  -----------

  In the sound resources of QfG2 and CC1990 I've seen two types of Data
  Chunks, Sample and MIDI channel track.


    Sample Chunk
    ------------

    offset size description
    -----------------------
      0    byte =0xfe
      1    byte !=0xfe (always 0 in QfG2 and CC1990)
      2    word Sample rate (Hz)
      4    word Sample length
      6    word Sample point 1 (begin?)
      8    word Sample point 2 (end?)
     10         Unsigned 8-bit mono sample data


    MIDI channel track Chunk
    ------------------------

    This chunk begins with a 2 byte header. The low nibble of the
    first byte indicates the channel number. The high nibble controls
    certain aspects of (dynamic) track channel/hardware channel mapping.

    The second byte tells us how many notes will be
    playing simultaneously in the channel. From the third byte onward
    is the MIDI track data which looks just like normal SCI0 MIDI
    track data, but all status bytes are targeted at one specific MIDI
    channel.

Example, sound.833 from QfG2 (--without-header)
-----------------------------------------------

offset  data description
------------------------
 0000     00 Hardware ID for first track list
 0001     00 Track list continuation
 0002     00 Same hardware device
 0003   003F Data Chunk pointer (Little Endian)
 0005   0013 Data Chunk length (LE)
 0007     00 Track list continuation
 0008     00 Same hardware device
 0009   006A Data Chunk pointer (LE)
 000B   0015 Data Chunk length (LE)
 000D     FF Next track list
 000E     09 for hardware device 0x09
 000F     00 Track list continuation
 0010     00 Same hardware device
 0011   003F Data Chunk pointer (LE)
 0013   0013 Data Chunk length (LE)
 0015     00 Track list continuation
 0016     00 Same hardware device
 0017   0052 Data Chunk pointer (LE)
 0019   0018 Data Chunk length (LE)
 001B     00 Track list continuation
 001C     00 Same hardware device
 001D   0094 Data Chunk pointer (LE)
 001F   0012 Data Chunk length (LE)
 0021     FF Next track list
 0022     0C for hardware device 0x0C
 0023     00 Track list continuation
 0024     00 Same hardware device
 0025   003F Data Chunk pointer (LE)
 0027   0013 Data Chunk length (LE)
 0029     00 Track list continuation
 002A     00 Same hardware device
 002B   0052 Data Chunk pointer (LE)
 002D   0018 Data Chunk length (LE)
 002F     FF Next track list
 0030     13 for hardware device 0x13
 0031     00 Track list continuation
 0032     00 Same hardware device
 0033   003F Data Chunk pointer (LE)
 0035   0013 Data Chunk length (LE)
 0037     00 Track list continuation
 0038     00 Same hardware device
 0039   007F Data Chunk pointer (LE)
 003B   0015 Data Chunk length (LE)

 003D  FF FF Sequence Control - End of Sequence Blocks
 ------------------------------------------------------------
 003F     0F MIDI Track channel 15 (control channel)
 0040     01 One note playing on track (probably just to satisfy the
	     MIDI engine)
 0041        MIDI Track data like SCI0
 0052     02 MIDI Track channel 2
 0053     02 Two notes playing on track
 0054        MIDI Track data like SCI0
 006A	  03 MIDI Track channel 3
 006B	  01 One note playing on track
 006C	     MIDI Track data like SCI0
 007F	  0A MIDI Track channel 10
 0080	  01 One note playing on track
 0081	     MIDI Track data like SCI0
 0094	  02 MIDI Track channel 2
 0095	  01 One note playing on track
 0096	     MIDI Track data like SCI0

Addendum (provided by Lars Skovlund)
------------------------------------

First of all, tracks do not loop individually. No loop signals are
reported.

Absolute cues are generally stored in the signal selector, and
cumulative cues are generally stored in the dataInc selector, with
some interesting twists:

1. The server's record of the absolute cue value is reset as part of
   UPDATE_CUES.
2. When a cumulative cue is reported to the VM object, it will be
   placed in _both_ fields. In such a case, a constant of 0x7f will be
   added to the _signal_ selector only, to be able to distinguish the
   two kinds of cue (this has already been coded).
3. The above only happens if the sound does not use absolute cues
   (i.e. if the signal is 0 a priori). Note that, because of 1)
   above, this does not cause problems neither with successive
   cumulative cues nor with mixed cumulative/absolute cues.
4. A signal of 0xff will stop the sound object playing. This may be
   for purely internal purposes.
5. There no longer is a field indicating the amount of increment for
   a cue.
