Binary XACT SoundBank: Difference between revisions

From xoreos Wiki
Jump to navigation Jump to search
(Created page with "This is the binary version of the XACT SoundBank (XSB), version 11, as used by Jade Empire on the original Xbox. The Windows PC version of Jade Empire uses an ASCII variant, w...")
 
No edit summary
 
(5 intermediate revisions by the same user not shown)
Line 5: Line 5:
On the top-level, a SoundBank consists of cues and sounds. A sound is a collection of tracks, which each contain a list of events and a list of wave variations, while a cue consists of a list of references to sounds.
On the top-level, a SoundBank consists of cues and sounds. A sound is a collection of tracks, which each contain a list of events and a list of wave variations, while a cue consists of a list of references to sounds.


A structural example:
Both the cue variation and the wave variation can be selected using different methods. For example, they could be played in order, or randomly. Or they could be explicitly selected by game.
 
== A structural example ==


* Sounds
* Sounds
Line 16: Line 18:
***** PITCH
***** PITCH
**** Wave variations
**** Wave variations
***** Sound 23 out of WaveBank "foobar"
***** Sound 23 out of WaveBank "foobar"
***** Sound 24 out of WaveBank "foobar"
***** Sound 24 out of WaveBank "foobar"
***** Sound 12 out of WaveBank "quux"
***** Sound 12 out of WaveBank "quux"
** Sound 1
** Sound 1
*** Track 0
*** Track 0
Line 24: Line 26:
***** PLAY
***** PLAY
**** Wave variations
**** Wave variations
***** Sound 24 out of WaveBank "foobar"
***** Sound 24 out of WaveBank "foobar"
*** Track 1
*** Track 1
**** Event list
**** Event list
***** PLAY
***** PLAY
**** Wave variations
**** Wave variations
***** Sound 25 out of WaveBank "foobar"
***** Sound 25 out of WaveBank "foobar"
* Cues
* Cues
** Cue 0
** Cue 0
Line 41: Line 43:
*** Cue variations
*** Cue variations
**** Sound 1
**** Sound 1
Both the cue variation and the wave variation can be selected using different methods. For example, they could be played in order, or randomly. Or they could be explicitly selected by game.


== Structures ==
== Structures ==
Line 52: Line 52:
{| class="wikitable"
{| class="wikitable"
! Offset
! Offset
! Size
!align="right"| Size
! Description
! Description
|-
|-
|0x00 || 4 || FourCC, "SDBK"
| 0x00
|align="right"| 4
| FourCC, "SDBK"
|-
|-
|0x04 || 2 || Version, 11 (0B 00)
| 0x04
|align="right"| 2
| Version, 11 (0B 00)
|-
|-
|0x06 || 2 || CRC
| 0x06
|align="right"| 2
| CRC
|-
|-
|0x08 || 4 || Offset to WaveBank array
| 0x08
|align="right"| 4
| Offset to WaveBank array
|-
|-
|0x0C || 4 || Offset to ?
| 0x0C
|align="right"| 4
| Offset to crossfade parameters array
|-
|-
|0x10 || 4 || Offset to 3D parameters array
| 0x10
|align="right"| 4
| Offset to 3D parameters array
|-
|-
|0x14 || 4 || Offset to ?
| 0x14
|align="right"| 4
| Offset to ?
|-
|-
|0x18 || 2 || XSB flags
| 0x18
|align="right"| 2
| XSB flags
|-
|-
|0x1A || 2 || Number of ?
| 0x1A
|align="right"| 2
| Number of ?
|-
|-
|0x1C || 2 || Number of sounds (soundCount)
| 0x1C
|align="right"| 2
| Number of sounds (soundCount)
|-
|-
|0x1E || 2 || Number of cues (cueCount)
| 0x1E
|align="right"| 2
| Number of cues (cueCount)
|-
|-
|0x20 || 2 || Number of ?
| 0x20
|align="right"| 2
| Number of ?
|-
|-
|0x22 || 2 || Number of WaveBanks
| 0x22
|align="right"| 2
| Number of WaveBanks
|-
|-
|0x24 || 4 || ?
| 0x24
|align="right"| 4
| ?
|-
|-
|0x28 || 16 || SoundBank name
| 0x28
|align="right"| 16
| SoundBank name
|-
|-
|0x38 || cueCount * 20 || Cue entries
| 0x38
|align="right"| cueCount * 20
| Cue entries
|-
|-
|0x38 + cueCount * 20 || soundCount * 20 || Sound entries
| 0x38 + cueCount * 20
|align="right"| soundCount * 20
| Sound entries
|}
|}


=== WaveBank entry ===
=== WaveBank entry ===
Line 95: Line 128:
{| class="wikitable"
{| class="wikitable"
! Offset
! Offset
! Size
!align="right"| Size
! Description
! Description
|-
|-
| 0x00 || 16 || WaveBank file name (without extension)
| 0x00
|align="right"| 16
| WaveBank file name (without extension)
|}
|}


=== Cue entry ===
=== Cue entry ===
Line 106: Line 140:
{| class="wikitable"
{| class="wikitable"
! Offset
! Offset
! Size
!align="right"| Size
! Description
! Description
|-
|-
| 0x00 || 2 || Flags
| 0x00
|align="right"| 2
| Flags
|-
|-
| 0x02 || 2 || Sound index, if the cue has only one variation. 0xFFFF otherwise
| 0x02
|align="right"| 2
| Sound index (see below)
|-
|-
| 0x04 || 4 || Offset to name. 0xFFFFFFFF if the cue has no name. Should be ignored if XSB_FLAG_NO_CUE_NAMES is set
| 0x04
|align="right"| 4
| Offset to name (see below)
|-
|-
| 0x08 || 4 || Offset to variations. 0xFFFFFFFF if the sound has no variations
| 0x08
|align="right"| 4
| Offset to cue variations (see below)
|-
|-
| 0x0C || 4 || ?
| 0x0C
|align="right"| 2
| Index into the crossfade parameters array
|-
|-
| 0x10 || 4 || ?
| 0x0E
|align="right"| 2
| ?
|-
| 0x10
|align="right"| 4
| Interactive transitions (see below)
|}
|}


Sound index: 0xFFFF if the cue has only one variations.
Offset to name: 0xFFFFFFFF if the cue has no name. Should be ignored if XSB_FLAG_NO_CUE_NAMES is set.
Offset to cue variations: 0xFFFFFFFF if the cue has no variations
Interactive transitions: AAAAAAAAAAAAAAAAAAAAAAAABBBBB???
* A, 24 bits: Offset to the interactive transition definitions
* B, 5 bits: Trigger variable


=== Sound entry ===
=== Sound entry ===
Line 127: Line 187:
{| class="wikitable"
{| class="wikitable"
! Offset
! Offset
! Size
!align="right"| Size
! Description
! Description
|-
|-
| 0x00 || 4 || Offset to non-trivial entry, or 2 bytes of wave index and 2 bytes of wavebank index
| 0x00
|align="right"| 4
| Offset or indices (see below)
|-
|-
| 0x04 || 2 || Volume
| 0x04
|align="right"| 2
| Volume and LFE volume (see below)
|-
|-
| 0x06 || 2 || Pitch
| 0x06
|align="right"| 2
| Pitch
|-
|-
| 0x08 || 1 || Number of tracks
| 0x08
|align="right"| 1
| Number of tracks
|-
|-
| 0x09 || 1 || Layer
| 0x09
|align="right"| 1
| Layer
|-
|-
| 0x0A || 1 || Category
| 0x0A
|align="right"| 1
| Category
|-
|-
| 0x0B || 1 || Flags
| 0x0B
|align="right"| 1
| Flags
|-
|-
| 0x0C || 2 || Index into the 3D parameters array
| 0x0C
|align="right"| 2
| Index into the 3D parameters array
|-
|-
| 0x0E || 1 || Priority
| 0x0E
|align="right"| 1
| Priority
|-
|-
| 0x0F || 1 || 3D volume
| 0x0F
|align="right"| 1
| I3DL2 volume in 2.56th dB
|-
|-
| 0x10 || 2 || EQ?
| 0x10
|align="right"| 2
| Parametric EQ gain in 8192th dB
|-
|-
| 0x12 || 2 || EQ?
| 0x12
|align="right"| 2
| EQ Q and EQ frequency (see below)
|}
|}


Offset or indices: Offset to non-trivial entry, or 2 bytes of wave index and 2 bytes of wavebank index.


=== Simple sound track (one track, one event (PLAY), multiple wave variations) ===
Volume and LFE volume: AAAAAAABBBBBBBBB
 
* A, 7 bits: LFE volume. VolumeLFE = -A * 0.5
* B, 9 bits: volume: Volume = -B * 0.16
 
EQ Q and EQ frequency: AAAAAAAAAAAAABBB
 
* A, 13 bits: EQ frequency
* B, 3 bits: EQ Q coefficient. Q = 1 / 2^B
 
=== Simple sound track ===
 
One track, one PLAY event, multiple wave variations.


{| class="wikitable"
{| class="wikitable"
! Offset
! Offset
! Size
!align="right"| Size
! Description
! Description
|-
|-
| 0x00 || 4 ||
| 0x00
* 13 bits: Number of variations (variationCount)
|align="right"| 4
* 4 bits: Variation selection method
| Variation parameters (see below)
* 13 bits: Current variation
* 2 bits: Flags
|-
|-
| 0x04 || variationCount * 4 || Variation entry (2 bytes of wave index and 2 bytes of wavebank index)
| 0x04
|align="right"| variationCount * 4
| Variation entry (see below)
|}
|}


Variation parameters: AABBBBBBBBBBBBBCCCCDDDDDDDDDDDDD
* A, 2 bits: Flags
* B, 13 bits: Current variation
* C, 4 bits: Variation selection method
* D, 13 bits: Number of variations (variationCount)
Variation entry: 2 bytes of wave index and 2 bytes of wavebank index.
=== Complex sound tracks ===


=== Complex sound tracks (multiple tracks or more than just a simple PLAY event) ===
Multiple tracks or more than just a simple PLAY event.


{| class="wikitable"
{| class="wikitable"
! Offset
! Offset
! Size
!align="right"| Size
! Description
! Description
|-
|-
| 0x00 || 1 || Number of events
| 0x00
|align="right"| 1
| Number of events
|-
|-
| 0x01 || 3 || Offset to event list
| 0x01
|align="right"| 3
| Offset to event list
|}
|}


=== Variation table ===
=== Variation table ===
Line 190: Line 300:
{| class="wikitable"
{| class="wikitable"
! Offset
! Offset
! Size
!align="right"| Size
! Description
! Description
|-
|-
| 0x00 || 4 ||
| 0x00
* 13 bits: Number of variations (variationCount)
|align="right"| 4
* 4 bits: Variation selection method
| Variation parameters (see below)
* 13 bits: Current variation
* 2 bits: Flags
|-
|-
| 0x04 || variationCount * 8 || Variation entry
| 0x04
|align="right"| variationCount * 8
| Variation entry
|}
|}


Variation parameters: AABBBBBBBBBBBBBCCCCDDDDDDDDDDDDD
* A, 2 bits: Flags
* B, 13 bits: Current variation
* C, 4 bits: Variation selection method
* D, 13 bits: Number of variations (variationCount)


=== Event list entry ===
=== Event list entry ===
Line 207: Line 323:
{| class="wikitable"
{| class="wikitable"
! Offset
! Offset
! Size
!align="right"| Size
! Description
|-
| 0x00
|align="right"| 1
| Event type
|-
| 0x01
|align="right"| 3
| Timestamp in milliseconds
|-
| 0x04
|align="right"| 1
| Parameter size in bytes
|-
| 0x05
|align="right"| 1
| Flags
|-
| 0x06
|align="right"| 2
| ?
|-
| ....
|align="right"|
 
| Parameters
|}
 
==== Event list entry for a PLAY event ====
 
{| class="wikitable"
! Offset
!align="right"| Size
! Description
! Description
|-
|-
| 0x00 || 1 || Event type
| 0x00
|align="right"| 1
| Event type (= 0x00)
|-
|-
| 0x01 || 3 || ?
| 0x01
|align="right"| 3
| Timestamp in milliseconds
|-
|-
| 0x04 || 1 || Parameter size in bytes
| 0x04
|align="right"| 1
| Parameter size in bytes (= 0x04)
|-
|-
| 0x05 || 1 || Flags
| 0x05
|align="right"| 1
| Flags
|-
|-
| 0x06 || 2 || ?
| 0x06
|align="right"| 2
| Loop count
|-
|-
| .... || || Parameters
| 0x08
|align="right"| 4
| Offset or indices (see below)
|}
|}


Offset or indices: If XSB_PLAY_EVENT_FLAG_COMPLEX in Flags is set, this is an offset to a wave variation list (see "Simple sound track" above). Otherwise, this is 2 bytes of a sound index followed by 2 bytes of bank index.


=== Event list entry for a PLAY or PLAY_COMPLEX event ===
==== Event list entry for a PLAY_COMPLEX event ====


{| class="wikitable"
{| class="wikitable"
! Offset
! Offset
! Size
!align="right"| Size
! Description
! Description
|-
|-
| 0x00 || 1 || Event type (= 0x00 or 0x01)
| 0x00
|align="right"| 1
| Event type (= 0x01)
|-
| 0x01
|align="right"| 3
| Timestamp in milliseconds
|-
| 0x04
|align="right"| 1
| Parameter size in bytes (= 0x10)
|-
|-
| 0x01 || 3 || ?
| 0x05
|align="right"| 1
| Flags
|-
|-
| 0x04 || 1 || Parameter size in bytes (= 0x04 or 0x10)
| 0x06
|align="right"| 2
| Loop count
|-
|-
| 0x05 || 1 || Flags
| 0x08
|align="right"| 4
| Offset or indices (see below)
|-
|-
| 0x06 || 2 || ?
| 0x0C
|align="right"| 2
| Pitch variation, lower bound
|-
|-
| 0x08 || 4 || If XSB_PLAY_EVENT_FLAG_COMPLEX in Flags is set, this is an offset to a wave variation list (see "Simple sound track" above). Otherwise, this is 2 bytes of a sound index followed by 2 bytes of bank index.
| 0x0E
|align="right"| 2
| Pitch variation, upper bound
|-
| 0x10
|align="right"| 2
| Volume variation, lower bound
|-
| 0x12
|align="right"| 2
| Volume variation, upper bound
|-
| 0x14
|align="right"| 2
| Maximum variable sound delay in milliseconds
|-
| 0x16
|align="right"| 2
| ?
|}
|}


Offset or indices: If XSB_PLAY_EVENT_FLAG_COMPLEX in Flags is set, this is an offset to a wave variation list (see "Simple sound track" above). Otherwise, this is 2 bytes of a sound index followed by 2 bytes of bank index.
==== Event list entry for a PITCH event ====
{| class="wikitable"
! Offset
!align="right"| Size
! Description
|-
| 0x00
|align="right"| 1
| Event type (= 0x04)
|-
| 0x01
|align="right"| 3
| Timestamp in milliseconds
|-
| 0x04
|align="right"| 1
| Parameter size in bytes (= 0x08)
|-
| 0x05
|align="right"| 1
| Flags
|-
| 0x06
|align="right"| 2
| Number of fade steps
|-
| 0x08
|align="right"| 2
| Pitch, lower bound or starting value
|-
| 0x0A
|align="right"| 2
| Pitch, upper bound or starting value
|-
| 0x0C
|align="right"| 1
| ?
|-
| 0x0D
|align="right"| 3
| Fade duration in milliseconds
|}
==== Event list entry for a VOLUME event ====
{| class="wikitable"
! Offset
!align="right"| Size
! Description
|-
| 0x00
|align="right"| 1
| Event type (= 0x05)
|-
| 0x01
|align="right"| 3
| Timestamp in milliseconds
|-
| 0x04
|align="right"| 1
| Parameter size in bytes (= 0x08)
|-
| 0x05
|align="right"| 1
| Flags
|-
| 0x06
|align="right"| 2
| Number of fade steps
|-
| 0x08
|align="right"| 2
| Volume, lower bound or starting value
|-
| 0x0A
|align="right"| 2
| Volume, upper bound or starting value
|-
| 0x0C
|align="right"| 1
| ?
|-
| 0x0D
|align="right"| 3
| Fade duration in milliseconds
|}
==== Event list entry for a LOWPASS event ====
{| class="wikitable"
! Offset
!align="right"| Size
! Description
|-
| 0x00
|align="right"| 1
| Event type (= 0x07)
|-
| 0x01
|align="right"| 3
| Timestamp in milliseconds
|-
| 0x04
|align="right"| 1
| Parameter size in bytes (= 0x0C)
|-
| 0x05
|align="right"| 1
| Flags
|-
| 0x06
|align="right"| 2
| Sweep step count
|-
| 0x08
|align="right"| 2
| Cut-off frequency start
|-
| 0x0A
|align="right"| 2
| Cut-off frequency end
|-
| 0x0C
|align="right"| 1
| ?
|-
| 0x0D
|align="right"| 3
| Sweep duration
|-
| 0x10
|align="right"| 2
| Resonance start
|-
| 0x12
|align="right"| 2
| Resonance end
|}
==== Event list entry for a LFO_PITCH event ====
{| class="wikitable"
! Offset
!align="right"| Size
! Description
|-
| 0x00
|align="right"| 1
| Event type (= 0x08)
|-
| 0x01
|align="right"| 3
| Timestamp in milliseconds
|-
| 0x04
|align="right"| 1
| Parameter size in bytes (= 0x04)
|-
| 0x05
|align="right"| 1
| Flags
|-
| 0x06
|align="right"| 2
| ?
|-
| 0x08
|align="right"| 1
| ?
|-
| 0x09
|align="right"| 1
| ?
|-
| 0x0A
|align="right"| 1
| Delta
|-
| 0x0B
|align="right"| 1
| Pitch modulation
|}
==== Event list entry for a LFO_MULTI event ====
{| class="wikitable"
! Offset
!align="right"| Size
! Description
|-
| 0x00
|align="right"| 1
| Event type (= 0x09)
|-
| 0x01
|align="right"| 3
| Timestamp in milliseconds
|-
| 0x04
|align="right"| 1
| Parameter size in bytes (= 0x08)
|-
| 0x05
|align="right"| 1
| Flags
|-
| 0x06
|align="right"| 2
| ?
|-
| 0x08
|align="right"| 1
| ?
|-
| 0x09
|align="right"| 1
| ?
|-
| 0x0A
|align="right"| 1
| Delta
|-
| 0x0B
|align="right"| 1
| Pitch modulation
|-
| 0x0C
|align="right"| 1
| Filter modulation
|-
| 0x0D
|align="right"| 1
| Amplitude modulation
|-
| 0x0E
|align="right"| 1
| ?
|-
| 0x0F
|align="right"| 1
| ?
|}
==== Event list entry for a ENVELOPE_AMPLITUDE event ====
{| class="wikitable"
! Offset
!align="right"| Size
! Description
|-
| 0x00
|align="right"| 1
| Event type (= 0x0A)
|-
| 0x01
|align="right"| 3
| Timestamp in milliseconds
|-
| 0x04
|align="right"| 1
| Parameter size in bytes (= 0x0C)
|-
| 0x05
|align="right"| 1
| Flags
|-
| 0x06
|align="right"| 2
| ?
|-
| 0x08
|align="right"| 2
| Delay in seconds
|-
| 0x0A
|align="right"| 2
| Attack in seconds
|-
| 0x0C
|align="right"| 2
| Hold in seconds
|-
| 0x0E
|align="right"| 2
| Decay in seconds
|-
| 0x10
|align="right"| 2
| Release in seconds
|-
| 0x12
|align="right"| 1
| Sustain power
|-
| 0x13
|align="right"| 1
| ?
|}
==== Event list entry for a ENVELOPE_PITCH event ====
{| class="wikitable"
! Offset
!align="right"| Size
! Description
|-
| 0x00
|align="right"| 1
| Event type (= 0x0B)
|-
| 0x01
|align="right"| 3
| Timestamp in milliseconds
|-
| 0x04
|align="right"| 1
| Parameter size in bytes (= 0x10)
|-
| 0x05
|align="right"| 1
| Flags
|-
| 0x06
|align="right"| 2
| ?
|-
| 0x08
|align="right"| 2
| Delay in seconds
|-
| 0x0A
|align="right"| 2
| Attack in seconds
|-
| 0x0C
|align="right"| 2
| Hold in seconds
|-
| 0x0E
|align="right"| 2
| Decay in seconds
|-
| 0x10
|align="right"| 2
| Release in seconds
|-
| 0x12
|align="right"| 1
| Sustain power
|-
| 0x13
|align="right"| 1
| ?
|-
| 0x14
|align="right"| 1
| ?
|-
| 0x15
|align="right"| 1
| ?
|-
| 0x16
|align="right"| 1
| Pitch scale
|-
| 0x17
|align="right"| 1
| Filter cut-off
|}
==== Event list entry for a LOOP event ====
{| class="wikitable"
! Offset
!align="right"| Size
! Description
|-
| 0x00
|align="right"| 1
| Event type (= 0x0C)
|-
| 0x01
|align="right"| 3
| Timestamp in milliseconds
|-
| 0x04
|align="right"| 1
| Parameter size in bytes (= 0x00)
|-
| 0x05
|align="right"| 1
| Flags
|-
| 0x06
|align="right"| 2
| Number of loops (see below)
|}
Number of loops: 0xFFFF for looping indefinitely.
==== Event list entry for a MARKER event ====
{| class="wikitable"
! Offset
!align="right"| Size
! Description
|-
| 0x00
|align="right"| 1
| Event type (= 0x0E)
|-
| 0x01
|align="right"| 3
| Timestamp in milliseconds
|-
| 0x04
|align="right"| 1
| Parameter size in bytes (= 0x00)
|-
| 0x05
|align="right"| 1
| Flags
|-
| 0x06
|align="right"| 2
| Marker occurrences
|-
| 0x08
|align="right"| 4
| Marker value
|-
| 0x0C
|align="right"| 1
| ?
|-
| 0x0D
|align="right"| 3
| Repeat duration in milliseconds
|}
==== Event list entry for a MIXBINS event ====
{| class="wikitable"
! Offset
!align="right"| Size
! Description
|-
| 0x00
|align="right"| 1
| Event type (= 0x10)
|-
| 0x01
|align="right"| 3
| Timestamp in milliseconds
|-
| 0x04
|align="right"| 1
| Parameter size in bytes (= 0x20)
|-
| 0x05
|align="right"| 1
| Flags
|-
| 0x06
|align="right"| 2
| ?
|-
| 0x08
|align="right"| 1
| Channel index 0
|-
| 0x09
|align="right"| 1
| ?
|-
| 0x0A
|align="right"| 2
| Channel volume 0
|-
| 0x0C
|align="right"| 1
| Channel index 1
|-
| 0x0D
|align="right"| 1
| ?
|-
| 0x0E
|align="right"| 2
| Channel volume 1
|-
| 0x10
|align="right"| 1
| Channel index 2
|-
| 0x11
|align="right"| 1
| ?
|-
| 0x12
|align="right"| 2
| Channel volume 2
|-
| 0x14
|align="right"| 1
| Channel index 3
|-
| 0x15
|align="right"| 1
| ?
|-
| 0x16
|align="right"| 2
| Channel volume 3
|-
| 0x18
|align="right"| 1
| Channel index 4
|-
| 0x19
|align="right"| 1
| ?
|-
| 0x1A
|align="right"| 2
| Channel volume 4
|-
| 0x1C
|align="right"| 1
| Channel index 5
|-
| 0x1D
|align="right"| 1
| ?
|-
| 0x1E
|align="right"| 2
| Channel volume 5
|-
| 0x20
|align="right"| 1
| Channel index 6
|-
| 0x21
|align="right"| 1
| ?
|-
| 0x22
|align="right"| 2
| Channel volume 6
|-
| 0x24
|align="right"| 1
| Channel index 7
|-
| 0x25
|align="right"| 1
| ?
|-
| 0x26
|align="right"| 2
| Channel volume 7
|}
==== Event list entry for an ENVIRONMENT_REVERB event ====
{| class="wikitable"
! Offset
!align="right"| Size
! Description
|-
| 0x00
|align="right"| 1
| Event type (= 0x11)
|-
| 0x01
|align="right"| 3
| Timestamp in milliseconds
|-
| 0x04
|align="right"| 1
| Parameter size in bytes (= 0x30)
|-
| 0x05
|align="right"| 1
| Flags
|-
| 0x06
|align="right"| 2
| ?
|-
| 0x08
|align="right"| 4
| Room effect attenuation
|-
| 0x0C
|align="right"| 4
| High-frequency room effect attenuation
|-
| 0x10
|align="right"| 4
| Roll-off factor for the room effect
|-
| 0x14
|align="right"| 4
| Decay time
|-
| 0x18
|align="right"| 4
| High-frequency to low-frequency decay time ratio
|-
| 0x1C
|align="right"| 4
| (Early) Reflection attenuation
|-
| 0x20
|align="right"| 4
| (Early) Reflection delay
|-
| 0x24
|align="right"| 4
| (Late) Reverb attenuation
|-
| 0x28
|align="right"| 4
| (Late) Reverb delay
|-
| 0x2C
|align="right"| 4
| Diffusion, echo density in (late) reverb decay
|-
| 0x30
|align="right"| 4
| Density, modal density in (late) reverb decay
|-
| 0x34
|align="right"| 4
| Reference high frequency
|}
==== Event list entry for a MIXBINSPAN event ====
{| class="wikitable"
! Offset
!align="right"| Size
! Description
|-
| 0x00
|align="right"| 1
| Event type (= 0x10)
|-
| 0x01
|align="right"| 3
| Timestamp in milliseconds
|-
| 0x04
|align="right"| 1
| Parameter size in bytes (= 0x14)
|-
| 0x05
|align="right"| 1
| Flags
|-
| 0x06
|align="right"| 2
| ?
|-
| 0x08
|align="right"| 1
| Speaker configuration (see below)
|-
| 0x09
|align="right"| 3
| Angle and flag (see below)
|-
| 0x0C
|align="right"| 1
| Channel index 0
|-
| 0x0D
|align="right"| 1
| ?
|-
| 0x0E
|align="right"| 2
| Channel volume 0
|-
| 0x10
|align="right"| 1
| Channel index 1
|-
| 0x11
|align="right"| 1
| ?
|-
| 0x12
|align="right"| 2
| Channel volume 1
|-
| 0x14
|align="right"| 1
| Channel index 2
|-
| 0x15
|align="right"| 1
| ?
|-
| 0x16
|align="right"| 2
| Channel volume 2
|-
| 0x18
|align="right"| 1
| Channel index 3
|-
| 0x19
|align="right"| 1
| ?
|-
| 0x1A
|align="right"| 2
| Channel volume 3
|}
Speaker configuration: 0 for 5 channels, 1 for 4 channels
Angle and flags: 00000ABBBBBBBBBCCCCCCCCC
* A, 1 bit: If set, use 3D mix bins
* B, 9 bits: end angle
* C, 9 bits: start angle


=== Variation entry ===
=== Variation entry ===
Line 249: Line 1,182:
{| class="wikitable"
{| class="wikitable"
! Offset
! Offset
! Size
!align="right"| Size
! Description
! Description
|-
|-
| 0x00 || 2 || Sound index
| 0x00
|align="right"| 2
| Sound index
|-
|-
| 0x02 || 2 || ?
| 0x02
|align="right"| 2
| ?
|-
|-
| 0x04 || 2 || Weight minimum
| 0x04
|align="right"| 2
| Weight minimum
|-
|-
| 0x06 || 2 || Weight maximum
| 0x06
|align="right"| 2
| Weight maximum
|}
|}


=== 3D parameters entry ===
{| class="wikitable"
! Offset
!align="right"| Size
! Description
|-
| 0x00
|align="right"| 2
| Inside cone angle
|-
| 0x02
|align="right"| 2
| Outside cone angle
|-
| 0x04
|align="right"| 2
| Cone outside volume
|-
| 0x06
|align="right"| 2
| ?
|-
| 0x08
|align="right"| 4
| Minimum distance
|-
| 0x0C
|align="right"| 4
| Maximum distance
|-
| 0x10
|align="right"| 4
| Distance factor
|-
| 0x14
|align="right"| 4
| Rolloff factor
|-
| 0x18
|align="right"| 4
| Doppler factor
|-
| 0x1C
|align="right"| 1
| Mode
|-
| 0x1D
|align="right"| 4
| ?
|-
| 0x20
|align="right"| 4
| ?
|-
| 0x24
|align="right"| 4
| ?
|}


=== 3D parameters entry ===
=== Crossfade parameters entry ===


{| class="wikitable"
{| class="wikitable"
! Offset
! Offset
! Size
!align="right"| Size
! Description
! Description
|-
|-
| 0x00 || 2 || Inside cone angle
| 0x00
|align="right"| 4
| Fade-in time in 10^-7 seconds
|-
| 0x04
|align="right"| 2
| Initial volume
|-
| 0x06
|align="right"| 1
| Type (see below)
|-
|-
| 0x02 || 2 || Outside cone angle
| 0x07
|align="right"| 1
| Fade-in step count
|-
|-
| 0x04 || 2 || Cone outside volume
| 0x08
|align="right"| 4
| Fade-out time in 10^-7 seconds
|-
|-
| 0x06 || 2 || ?
| 0x0C
|align="right"| 2
| Final volume
|-
|-
| 0x08 || 4 || minimum distance
| 0x0E
|align="right"| 1
| Type (see below)
|-
|-
| 0x0C || 4 || maximum distance
| 0x0F
|align="right"| 1
| Fade-out step count
|}
 
Type: AAAA????
 
* A, 4 bits: 0 for disabled, 1 for linear, 2 for logarithmic
 
=== Interactive transitions array ===
 
{| class="wikitable"
! Offset
!align="right"| Size
! Description
|-
|-
| 0x10 || 4 || Distance factor
| 0x00
|align="right"| 4
| Number of transitions (transitionCount)
|-
|-
| 0x14 || 4 || Rolloff factor
| 0x04
|align="right"| transitionCount * 24
| Transition entry
|}
 
In general, there's one transition per sound combination (excluding the cases where to and from are the same), plus one set for silence to each sound, plus one set for each sound to silence.
 
I.e. for N sounds, there's N^2 - N + 2N, or N^2 + N in shorter, transitions.
 
The order is as follows:
 
* Silence -> N_0
* Silence -> N_1
* Silence -> N_2
* ...
* N_0 -> Silence
* N_0 -> N_1
* N_0 -> N_2
* ...
* N_1 -> Silence
* N_1 -> N_0
* N_1 -> N_2
* ...
 
=== Interactive transition entry ===
 
{| class="wikitable"
! Offset
!align="right"| Size
! Description
|-
| 0x00
|align="right"| 2
| Flags (see below)
|-
| 0x02
|align="right"| 2
| Transitional sound index
|-
|-
| 0x18 || 4 || Doppler factor
| 0x04
|align="right"| 2
| Source fade-out duration in milliseconds
|-
|-
| 0x1C || 1 || Mode
| 0x06
|align="right"| 2
| Destination fade-in duration in milliseconds
|-
|-
| 0x1D || 4 || ?
| 0x08
|align="right"| 4
| Source marker, low
|-
|-
| 0x20 || 4 || ?
| 0x0C
|align="right"| 4
| Source marker, high
|-
|-
| 0x24 || 4 || ?
| 0x10
|align="right"| 4
| Destination marker, low
|-
| 0x14
|align="right"| 4
| Destination marker, high
|}
|}


Flags: 00000AAAABBBCCCC
* A, 4 bits: Transition destination
* B, 3 bits: Transition effect
* C, 4 bits: Transition source


== Flags ==
== Flags ==
Line 302: Line 1,392:


{| class="wikitable"
{| class="wikitable"
! Name
!width="26%"| Name
! Value
!align="right" width="9%"| Value
! Description
!width="64%"| Description
|-
|-
| XSB_FLAG_NO_CUE_NAMES || 0x0001 || If set, cues in the XSB file have no human-readable name
| XSB_FLAG_NO_CUE_NAMES
|align="right"| 0x0001
| If set, cues in the XSB file have no human-readable name
|}
|}


Line 313: Line 1,405:
{| class="wikitable"
{| class="wikitable"
! Name
! Name
! Value
!align="right"| Value
! Description
! Description
|-
|-
| XSB_CUE_FLAG_INTERACTIVE || 0x0008 || If set, the cue is interactive
| XSB_CUE_FLAG_SEQUENTIAL
|align="right"| 0x0001
| If set, cue for sequential playback
|-
| XSB_CUE_FLAG_CROSSFADE
|align="right"| 0x0002
| If set, enable crossfade
|-
| XSB_CUE_FLAG_STOPONSTARVE
|align="right"| 0x0004
| If set, stop on starvation
|-
| XSB_CUE_FLAG_INTERACTIVE
|align="right"| 0x0008
| If set, the cue is interactive
|}
|}


=== Sound flags ===
=== Sound flags ===
{| class="wikitable"
!width="25%"| Name
!align="right" width="8%"| Value
!width="65%"| Description
|-
| XSB_SOUND_FLAG_3D
|align="right"| 0x01
| If set, the sound has 3D parameters
|-
| XSB_SOUND_FLAG_GAINBOOST
|align="right"| 0x02
| If set, the sound has a gain boost of 6dB applied
|-
| XSB_SOUND_FLAG_EQ
|align="right"| 0x04
| If set, the sound has parametric EQ enabled
|-
| XSB_SOUND_FLAG_TRIVIAL
|align="right"| 0x08
| Trivial sound: one track, one PLAY event, one wave variation
|-
| XSB_SOUND_FLAG_SIMPLE
|align="right"| 0x10
| Simple sound: one track, one PLAY event, multiple wave variations
|-
| XSB_SOUND_FLAG_LINGER
|align="right"| 0x20
| If set, the sound should linger in an interactive cue
|}
=== PLAY event flags ===
{| class="wikitable"
!width="41%"| Name
!align="right" width="10%"| Value
!width="48%"| Description
|-
| XSB_PLAY_EVENT_FLAG_COMPLEX
|align="right"| 0x04
| Complex wave variations definition
|-
| XSB_PLAY_EVENT_FLAG_LOOPVARIATION
|align="right"| 0x40
| Select new wave variation on each loop
|}
=== PITCH event flags ===


{| class="wikitable"
{| class="wikitable"
! Name
! Name
! Value
!align="right"| Value
! Description
! Description
|-
|-
| XSB_SOUND_FLAG_3D      ||   0x01 || If set, the sound has 3D parameters
| XSB_PITCH_EVENT_FLAG_VARIATION
|align="right"| 0x04
| Enable variation
|-
|-
| XSB_SOUND_FLAG_TRIVIAL ||   0x08 || If set, the sound only has one track, one event (PLAY) and one wave variation
| XSB_PITCH_EVENT_FLAG_RELATIVE
|align="right"| 0x10
| Use relative values
|-
|-
| XSB_SOUND_FLAG_SIMPLE  ||   0x10 || If set, the sound only has one track, one event (PLAY), but multiple wave variations
| XSB_PITCH_EVENT_FLAG_FADE
|align="right"| 0x20
| Enable fade
|}
|}


=== VOLUME event flags ===
{| class="wikitable"
! Name
!align="right"| Value
! Description
|-
| XSB_VOLUME_EVENT_FLAG_VARIATION
|align="right"| 0x04
| Enable variation
|-
| XSB_VOLUME_EVENT_FLAG_RELATIVE
|align="right"| 0x10
| Use relative values
|-
| XSB_VOLUME_EVENT_FLAG_FADE
|align="right"| 0x20
| Enable fade
|}


=== PLAY event flags ===
=== LOWPASS event flags ===


{| class="wikitable"
{| class="wikitable"
! Name
! Name
! Value
!align="right"| Value
! Description
! Description
|-
|-
| XSB_PLAY_EVENT_FLAG_COMPLEX      ||   0x04 || Complex wave variations definition
| XSB_LOWPASS_EVENT_FLAG_RANDOM
|align="right"| 0x04
| Random values
|-
| XSB_LOWPASS_EVENT_FLAG_RELATIVE
|align="right"| 0x10
| Use relative values
|-
| XSB_LOWPASS_EVENT_FLAG_SWEEP
|align="right"| 0x20
| Sweep cut-off frequencies
|}
|}


=== MARKER event flags ===
{| class="wikitable"
! Name
!align="right"| Value
! Description
|-
| XSB_MARKER_EVENT_FLAG_REPEAT
|align="right"| 0x20
| Repeat marker
|}


== Enums ==
== Enums ==
Line 350: Line 1,550:


{| class="wikitable"
{| class="wikitable"
! Name
!width="34%"| Name
! Value
!align="right" width="8%"| Value
! Description
!width="56%"| Description
|-
|-
| XSB_EVENT_TYPE_PLAY               ||   0x00 || Play a wave, from start to finish
| XSB_EVENT_TYPE_PLAY
|align="right"| 0x00
| Play a wave, from start to finish
|-
|-
| XSB_EVENT_TYPE_PLAY_COMPLEX       ||   0x01 || Play a wave, with parameters
| XSB_EVENT_TYPE_PLAY_COMPLEX
|align="right"| 0x01
| Play a wave, with parameters
|-
|-
| XSB_EVENT_TYPE_STOP               ||   0x03 || Stop playing
| XSB_EVENT_TYPE_STOP
|align="right"| 0x03
| Stop playing
|-
|-
| XSB_EVENT_TYPE_PITCH             ||   0x04 || Set the pitch
| XSB_EVENT_TYPE_PITCH
|align="right"| 0x04
| Set the pitch
|-
|-
| XSB_EVENT_TYPE_VOLUME             ||   0x05 || Set the volume
| XSB_EVENT_TYPE_VOLUME
|align="right"| 0x05
| Set the volume
|-
|-
| XSB_EVENT_TYPE_LOWPASS           ||   0x07 || Low-pass filter
| XSB_EVENT_TYPE_LOWPASS
|align="right"| 0x07
| Low-pass filter
|-
|-
| XSB_EVENT_TYPE_LFO_PITCH         ||   0x08 || Low-frequency oscillator on the pitch
| XSB_EVENT_TYPE_LFO_PITCH
|align="right"| 0x08
| Low-frequency oscillator on the pitch
|-
|-
| XSB_EVENT_TYPE_LFO_MULTI         ||   0x09 || Low-frequency oscillator on the pitch and amplitude
| XSB_EVENT_TYPE_LFO_MULTI
|align="right"| 0x09
| Low-frequency oscillator on the pitch and amplitude
|-
|-
| XSB_EVENT_TYPE_ENVELOPE_AMPLITUDE ||   0x0A || DAHDSR envelope on the amplitude
| XSB_EVENT_TYPE_ENVELOPE_AMPLITUDE
|align="right"| 0x0A
| DAHDSR envelope on the amplitude
|-
|-
| XSB_EVENT_TYPE_ENVELOPE_PITCH     ||   0x0B || DAHDSR envelope on the pitch
| XSB_EVENT_TYPE_ENVELOPE_PITCH
|align="right"| 0x0B
| DAHDSR envelope on the pitch
|-
|-
| XSB_EVENT_TYPE_LOOP               ||   0x0C || Loop a wave
| XSB_EVENT_TYPE_LOOP
|align="right"| 0x0C
| Loop a wave
|-
|-
| XSB_EVENT_TYPE_MARKER             ||   0x0E || Marker
| XSB_EVENT_TYPE_MARKER
|align="right"| 0x0E
| Marker
|-
|-
| XSB_EVENT_TYPE_DISABLED           ||   0x0F || A disabled event
| XSB_EVENT_TYPE_DISABLED
|align="right"| 0x0F
| A disabled event
|-
|-
| XSB_EVENT_TYPE_MIXBINS           ||   0x10 || Set a separate volume for each channel
| XSB_EVENT_TYPE_MIXBINS
|align="right"| 0x10
| Set a separate volume for each channel
|-
|-
| XSB_EVENT_TYPE_ENVIRONMENT_REVERB ||   0x11 || Environmental reverb
| XSB_EVENT_TYPE_ENVIRONMENT_REVERB
|align="right"| 0x11
| Environmental reverb
|-
|-
| XSB_EVENT_TYPE_MIXBINSPAN         ||   0x12 || Set channel volumes according to a listener orientation
| XSB_EVENT_TYPE_MIXBINSPAN
|align="right"| 0x12
| Set channel volumes according to a listener orientation
|}
|}


Line 390: Line 1,622:


{| class="wikitable"
{| class="wikitable"
! Name
!width="44%"| Name
! Value
!align="right" width="9%"| Value
! Description
!width="45%"| Description
|-
| XSB_VARIATION_SELECT_RANDOM_NOREPEATS
|align="right"| 0x00
| Random, but no immediate repeats
|-
| XSB_VARIATION_SELECT_ORDERED
|align="right"| 0x01
| One after the other, in order
|-
| XSB_VARIATION_SELECT_SHUFFLE
|align="right"| 0x02
| Random, no repeats at all
|-
| XSB_VARIATION_SELECT_PARAMETER
|align="right"| 0x03
| Game-controlled
|-
| XSB_VARIATION_SELECT_RANDOM
|align="right"| 0x04
| Completely random
|-
| XSB_VARIATION_SELECT_ORDERED_FROMRANDOM
|align="right"| 0x05
| Start with a random entry, then in order
|}
 
=== Transition source ===
 
{| class="wikitable"
!width="41%"| Name
!align="right" width="9%"| Value
!width="48%"| Description
|-
| XSB_TRANSITION_SOURCE_IMMEDIATE
|align="right"| 0x00
| Immediately
|-
| XSB_TRANSITION_SOURCE_MARKER
|align="right"| 0x01
| From a marker with a given range
|-
| XSB_TRANSITION_SOURCE_RANDOM_MARKER
|align="right"| 0x02
| From a random marker within a given range
|-
| XSB_TRANSITION_SOURCE_END_LOOP
|align="right"| 0x04
| End of loop
|-
| XSB_TRANSITION_SOURCE_END_SOUND
|align="right"| 0x08
| End of sound
|}
 
=== Transition destination ===
 
{| class="wikitable"
!width="45%"| Name
!align="right" width="9%"| Value
!width="45%"| Description
|-
| XSB_TRANSITION_DESTINATION_BEGINNING
|align="right"| 0x00
| To the beginning
|-
| XSB_TRANSITION_DESTINATION_ALIGNED_TIME
|align="right"| 0x01
| To the same time
|-
| XSB_TRANSITION_DESTINATION_ALIGNED_MARKER
|align="right"| 0x02
| To the same marker
|-
| XSB_TRANSITION_DESTINATION_MARKER
|align="right"| 0x04
| To a marker with a given range
|-
| XSB_TRANSITION_DESTINATION_RANDOM_MARKER
|align="right"| 0x08
| To a random marker within a given range
|}
 
=== Transition effect ===
 
{| class="wikitable"
!width="45%"| Name
!align="right" width="9%"| Value
!width="45%"| Description
|-
| XSB_TRANSITION_EFFECT_NONE
|align="right"| 0x00
| No effect
|-
| XSB_TRANSITION_EFFECT_CROSSFADE
|align="right"| 0x01
| Crossfade
|-
| XSB_TRANSITION_EFFECT_SOUND
|align="right"| 0x02
| Use a transitional sound
|-
| XSB_TRANSITION_EFFECT_SOUND_FADE_TO
|align="right"| 0x03
| Fade into a transitional sound
|-
| XSB_TRANSITION_EFFECT_SOUND_FADE_FROM
|align="right"| 0x06
| Fade from a transitional sound
|-
|-
| XSB_VARIATION_SELECT_PARAMETER    ||   0x03 || Parameter-controlled
| XSB_TRANSITION_EFFECT_SOUND_FADE_TOFROM
|align="right"| 0x07
| Fade into and from a transitional sound
|}
|}

Latest revision as of 11:29, 6 January 2019

This is the binary version of the XACT SoundBank (XSB), version 11, as used by Jade Empire on the original Xbox. The Windows PC version of Jade Empire uses an ASCII variant, which contains the same information.

Conceptually, it's very similar to later XSB versions that are used by Microsoft's XNA toolset.

On the top-level, a SoundBank consists of cues and sounds. A sound is a collection of tracks, which each contain a list of events and a list of wave variations, while a cue consists of a list of references to sounds.

Both the cue variation and the wave variation can be selected using different methods. For example, they could be played in order, or randomly. Or they could be explicitly selected by game.

A structural example

  • Sounds
    • Sound 0
      • Track 0
        • Event list
          • PLAY
          • LOOP
          • VOLUME
          • PITCH
        • Wave variations
          • Sound 23 out of WaveBank "foobar"
          • Sound 24 out of WaveBank "foobar"
          • Sound 12 out of WaveBank "quux"
    • Sound 1
      • Track 0
        • Event list
          • PLAY
        • Wave variations
          • Sound 24 out of WaveBank "foobar"
      • Track 1
        • Event list
          • PLAY
        • Wave variations
          • Sound 25 out of WaveBank "foobar"
  • Cues
    • Cue 0
      • Cue variations
        • Sound 0
        • Sound 1
    • Cue 1
      • Cue variations
        • Sound 0
    • Cue 2
      • Cue variations
        • Sound 1

Structures

All numerical values are little-endian.

Header

Offset Size Description
0x00 4 FourCC, "SDBK"
0x04 2 Version, 11 (0B 00)
0x06 2 CRC
0x08 4 Offset to WaveBank array
0x0C 4 Offset to crossfade parameters array
0x10 4 Offset to 3D parameters array
0x14 4 Offset to ?
0x18 2 XSB flags
0x1A 2 Number of ?
0x1C 2 Number of sounds (soundCount)
0x1E 2 Number of cues (cueCount)
0x20 2 Number of ?
0x22 2 Number of WaveBanks
0x24 4 ?
0x28 16 SoundBank name
0x38 cueCount * 20 Cue entries
0x38 + cueCount * 20 soundCount * 20 Sound entries

WaveBank entry

Offset Size Description
0x00 16 WaveBank file name (without extension)

Cue entry

Offset Size Description
0x00 2 Flags
0x02 2 Sound index (see below)
0x04 4 Offset to name (see below)
0x08 4 Offset to cue variations (see below)
0x0C 2 Index into the crossfade parameters array
0x0E 2 ?
0x10 4 Interactive transitions (see below)

Sound index: 0xFFFF if the cue has only one variations.

Offset to name: 0xFFFFFFFF if the cue has no name. Should be ignored if XSB_FLAG_NO_CUE_NAMES is set.

Offset to cue variations: 0xFFFFFFFF if the cue has no variations

Interactive transitions: AAAAAAAAAAAAAAAAAAAAAAAABBBBB???

  • A, 24 bits: Offset to the interactive transition definitions
  • B, 5 bits: Trigger variable

Sound entry

Offset Size Description
0x00 4 Offset or indices (see below)
0x04 2 Volume and LFE volume (see below)
0x06 2 Pitch
0x08 1 Number of tracks
0x09 1 Layer
0x0A 1 Category
0x0B 1 Flags
0x0C 2 Index into the 3D parameters array
0x0E 1 Priority
0x0F 1 I3DL2 volume in 2.56th dB
0x10 2 Parametric EQ gain in 8192th dB
0x12 2 EQ Q and EQ frequency (see below)

Offset or indices: Offset to non-trivial entry, or 2 bytes of wave index and 2 bytes of wavebank index.

Volume and LFE volume: AAAAAAABBBBBBBBB

  • A, 7 bits: LFE volume. VolumeLFE = -A * 0.5
  • B, 9 bits: volume: Volume = -B * 0.16

EQ Q and EQ frequency: AAAAAAAAAAAAABBB

  • A, 13 bits: EQ frequency
  • B, 3 bits: EQ Q coefficient. Q = 1 / 2^B

Simple sound track

One track, one PLAY event, multiple wave variations.

Offset Size Description
0x00 4 Variation parameters (see below)
0x04 variationCount * 4 Variation entry (see below)

Variation parameters: AABBBBBBBBBBBBBCCCCDDDDDDDDDDDDD

  • A, 2 bits: Flags
  • B, 13 bits: Current variation
  • C, 4 bits: Variation selection method
  • D, 13 bits: Number of variations (variationCount)

Variation entry: 2 bytes of wave index and 2 bytes of wavebank index.

Complex sound tracks

Multiple tracks or more than just a simple PLAY event.

Offset Size Description
0x00 1 Number of events
0x01 3 Offset to event list

Variation table

Offset Size Description
0x00 4 Variation parameters (see below)
0x04 variationCount * 8 Variation entry

Variation parameters: AABBBBBBBBBBBBBCCCCDDDDDDDDDDDDD

  • A, 2 bits: Flags
  • B, 13 bits: Current variation
  • C, 4 bits: Variation selection method
  • D, 13 bits: Number of variations (variationCount)

Event list entry

Offset Size Description
0x00 1 Event type
0x01 3 Timestamp in milliseconds
0x04 1 Parameter size in bytes
0x05 1 Flags
0x06 2 ?
.... Parameters

Event list entry for a PLAY event

Offset Size Description
0x00 1 Event type (= 0x00)
0x01 3 Timestamp in milliseconds
0x04 1 Parameter size in bytes (= 0x04)
0x05 1 Flags
0x06 2 Loop count
0x08 4 Offset or indices (see below)

Offset or indices: If XSB_PLAY_EVENT_FLAG_COMPLEX in Flags is set, this is an offset to a wave variation list (see "Simple sound track" above). Otherwise, this is 2 bytes of a sound index followed by 2 bytes of bank index.

Event list entry for a PLAY_COMPLEX event

Offset Size Description
0x00 1 Event type (= 0x01)
0x01 3 Timestamp in milliseconds
0x04 1 Parameter size in bytes (= 0x10)
0x05 1 Flags
0x06 2 Loop count
0x08 4 Offset or indices (see below)
0x0C 2 Pitch variation, lower bound
0x0E 2 Pitch variation, upper bound
0x10 2 Volume variation, lower bound
0x12 2 Volume variation, upper bound
0x14 2 Maximum variable sound delay in milliseconds
0x16 2 ?

Offset or indices: If XSB_PLAY_EVENT_FLAG_COMPLEX in Flags is set, this is an offset to a wave variation list (see "Simple sound track" above). Otherwise, this is 2 bytes of a sound index followed by 2 bytes of bank index.

Event list entry for a PITCH event

Offset Size Description
0x00 1 Event type (= 0x04)
0x01 3 Timestamp in milliseconds
0x04 1 Parameter size in bytes (= 0x08)
0x05 1 Flags
0x06 2 Number of fade steps
0x08 2 Pitch, lower bound or starting value
0x0A 2 Pitch, upper bound or starting value
0x0C 1 ?
0x0D 3 Fade duration in milliseconds

Event list entry for a VOLUME event

Offset Size Description
0x00 1 Event type (= 0x05)
0x01 3 Timestamp in milliseconds
0x04 1 Parameter size in bytes (= 0x08)
0x05 1 Flags
0x06 2 Number of fade steps
0x08 2 Volume, lower bound or starting value
0x0A 2 Volume, upper bound or starting value
0x0C 1 ?
0x0D 3 Fade duration in milliseconds

Event list entry for a LOWPASS event

Offset Size Description
0x00 1 Event type (= 0x07)
0x01 3 Timestamp in milliseconds
0x04 1 Parameter size in bytes (= 0x0C)
0x05 1 Flags
0x06 2 Sweep step count
0x08 2 Cut-off frequency start
0x0A 2 Cut-off frequency end
0x0C 1 ?
0x0D 3 Sweep duration
0x10 2 Resonance start
0x12 2 Resonance end

Event list entry for a LFO_PITCH event

Offset Size Description
0x00 1 Event type (= 0x08)
0x01 3 Timestamp in milliseconds
0x04 1 Parameter size in bytes (= 0x04)
0x05 1 Flags
0x06 2 ?
0x08 1 ?
0x09 1 ?
0x0A 1 Delta
0x0B 1 Pitch modulation

Event list entry for a LFO_MULTI event

Offset Size Description
0x00 1 Event type (= 0x09)
0x01 3 Timestamp in milliseconds
0x04 1 Parameter size in bytes (= 0x08)
0x05 1 Flags
0x06 2 ?
0x08 1 ?
0x09 1 ?
0x0A 1 Delta
0x0B 1 Pitch modulation
0x0C 1 Filter modulation
0x0D 1 Amplitude modulation
0x0E 1 ?
0x0F 1 ?

Event list entry for a ENVELOPE_AMPLITUDE event

Offset Size Description
0x00 1 Event type (= 0x0A)
0x01 3 Timestamp in milliseconds
0x04 1 Parameter size in bytes (= 0x0C)
0x05 1 Flags
0x06 2 ?
0x08 2 Delay in seconds
0x0A 2 Attack in seconds
0x0C 2 Hold in seconds
0x0E 2 Decay in seconds
0x10 2 Release in seconds
0x12 1 Sustain power
0x13 1 ?

Event list entry for a ENVELOPE_PITCH event

Offset Size Description
0x00 1 Event type (= 0x0B)
0x01 3 Timestamp in milliseconds
0x04 1 Parameter size in bytes (= 0x10)
0x05 1 Flags
0x06 2 ?
0x08 2 Delay in seconds
0x0A 2 Attack in seconds
0x0C 2 Hold in seconds
0x0E 2 Decay in seconds
0x10 2 Release in seconds
0x12 1 Sustain power
0x13 1 ?
0x14 1 ?
0x15 1 ?
0x16 1 Pitch scale
0x17 1 Filter cut-off

Event list entry for a LOOP event

Offset Size Description
0x00 1 Event type (= 0x0C)
0x01 3 Timestamp in milliseconds
0x04 1 Parameter size in bytes (= 0x00)
0x05 1 Flags
0x06 2 Number of loops (see below)

Number of loops: 0xFFFF for looping indefinitely.

Event list entry for a MARKER event

Offset Size Description
0x00 1 Event type (= 0x0E)
0x01 3 Timestamp in milliseconds
0x04 1 Parameter size in bytes (= 0x00)
0x05 1 Flags
0x06 2 Marker occurrences
0x08 4 Marker value
0x0C 1 ?
0x0D 3 Repeat duration in milliseconds

Event list entry for a MIXBINS event

Offset Size Description
0x00 1 Event type (= 0x10)
0x01 3 Timestamp in milliseconds
0x04 1 Parameter size in bytes (= 0x20)
0x05 1 Flags
0x06 2 ?
0x08 1 Channel index 0
0x09 1 ?
0x0A 2 Channel volume 0
0x0C 1 Channel index 1
0x0D 1 ?
0x0E 2 Channel volume 1
0x10 1 Channel index 2
0x11 1 ?
0x12 2 Channel volume 2
0x14 1 Channel index 3
0x15 1 ?
0x16 2 Channel volume 3
0x18 1 Channel index 4
0x19 1 ?
0x1A 2 Channel volume 4
0x1C 1 Channel index 5
0x1D 1 ?
0x1E 2 Channel volume 5
0x20 1 Channel index 6
0x21 1 ?
0x22 2 Channel volume 6
0x24 1 Channel index 7
0x25 1 ?
0x26 2 Channel volume 7

Event list entry for an ENVIRONMENT_REVERB event

Offset Size Description
0x00 1 Event type (= 0x11)
0x01 3 Timestamp in milliseconds
0x04 1 Parameter size in bytes (= 0x30)
0x05 1 Flags
0x06 2 ?
0x08 4 Room effect attenuation
0x0C 4 High-frequency room effect attenuation
0x10 4 Roll-off factor for the room effect
0x14 4 Decay time
0x18 4 High-frequency to low-frequency decay time ratio
0x1C 4 (Early) Reflection attenuation
0x20 4 (Early) Reflection delay
0x24 4 (Late) Reverb attenuation
0x28 4 (Late) Reverb delay
0x2C 4 Diffusion, echo density in (late) reverb decay
0x30 4 Density, modal density in (late) reverb decay
0x34 4 Reference high frequency

Event list entry for a MIXBINSPAN event

Offset Size Description
0x00 1 Event type (= 0x10)
0x01 3 Timestamp in milliseconds
0x04 1 Parameter size in bytes (= 0x14)
0x05 1 Flags
0x06 2 ?
0x08 1 Speaker configuration (see below)
0x09 3 Angle and flag (see below)
0x0C 1 Channel index 0
0x0D 1 ?
0x0E 2 Channel volume 0
0x10 1 Channel index 1
0x11 1 ?
0x12 2 Channel volume 1
0x14 1 Channel index 2
0x15 1 ?
0x16 2 Channel volume 2
0x18 1 Channel index 3
0x19 1 ?
0x1A 2 Channel volume 3

Speaker configuration: 0 for 5 channels, 1 for 4 channels

Angle and flags: 00000ABBBBBBBBBCCCCCCCCC

  • A, 1 bit: If set, use 3D mix bins
  • B, 9 bits: end angle
  • C, 9 bits: start angle

Variation entry

Offset Size Description
0x00 2 Sound index
0x02 2 ?
0x04 2 Weight minimum
0x06 2 Weight maximum

3D parameters entry

Offset Size Description
0x00 2 Inside cone angle
0x02 2 Outside cone angle
0x04 2 Cone outside volume
0x06 2 ?
0x08 4 Minimum distance
0x0C 4 Maximum distance
0x10 4 Distance factor
0x14 4 Rolloff factor
0x18 4 Doppler factor
0x1C 1 Mode
0x1D 4 ?
0x20 4 ?
0x24 4 ?

Crossfade parameters entry

Offset Size Description
0x00 4 Fade-in time in 10^-7 seconds
0x04 2 Initial volume
0x06 1 Type (see below)
0x07 1 Fade-in step count
0x08 4 Fade-out time in 10^-7 seconds
0x0C 2 Final volume
0x0E 1 Type (see below)
0x0F 1 Fade-out step count

Type: AAAA????

  • A, 4 bits: 0 for disabled, 1 for linear, 2 for logarithmic

Interactive transitions array

Offset Size Description
0x00 4 Number of transitions (transitionCount)
0x04 transitionCount * 24 Transition entry

In general, there's one transition per sound combination (excluding the cases where to and from are the same), plus one set for silence to each sound, plus one set for each sound to silence.

I.e. for N sounds, there's N^2 - N + 2N, or N^2 + N in shorter, transitions.

The order is as follows:

  • Silence -> N_0
  • Silence -> N_1
  • Silence -> N_2
  • ...
  • N_0 -> Silence
  • N_0 -> N_1
  • N_0 -> N_2
  • ...
  • N_1 -> Silence
  • N_1 -> N_0
  • N_1 -> N_2
  • ...

Interactive transition entry

Offset Size Description
0x00 2 Flags (see below)
0x02 2 Transitional sound index
0x04 2 Source fade-out duration in milliseconds
0x06 2 Destination fade-in duration in milliseconds
0x08 4 Source marker, low
0x0C 4 Source marker, high
0x10 4 Destination marker, low
0x14 4 Destination marker, high

Flags: 00000AAAABBBCCCC

  • A, 4 bits: Transition destination
  • B, 3 bits: Transition effect
  • C, 4 bits: Transition source

Flags

XSB flags

Name Value Description
XSB_FLAG_NO_CUE_NAMES 0x0001 If set, cues in the XSB file have no human-readable name

Cue flags

Name Value Description
XSB_CUE_FLAG_SEQUENTIAL 0x0001 If set, cue for sequential playback
XSB_CUE_FLAG_CROSSFADE 0x0002 If set, enable crossfade
XSB_CUE_FLAG_STOPONSTARVE 0x0004 If set, stop on starvation
XSB_CUE_FLAG_INTERACTIVE 0x0008 If set, the cue is interactive

Sound flags

Name Value Description
XSB_SOUND_FLAG_3D 0x01 If set, the sound has 3D parameters
XSB_SOUND_FLAG_GAINBOOST 0x02 If set, the sound has a gain boost of 6dB applied
XSB_SOUND_FLAG_EQ 0x04 If set, the sound has parametric EQ enabled
XSB_SOUND_FLAG_TRIVIAL 0x08 Trivial sound: one track, one PLAY event, one wave variation
XSB_SOUND_FLAG_SIMPLE 0x10 Simple sound: one track, one PLAY event, multiple wave variations
XSB_SOUND_FLAG_LINGER 0x20 If set, the sound should linger in an interactive cue

PLAY event flags

Name Value Description
XSB_PLAY_EVENT_FLAG_COMPLEX 0x04 Complex wave variations definition
XSB_PLAY_EVENT_FLAG_LOOPVARIATION 0x40 Select new wave variation on each loop

PITCH event flags

Name Value Description
XSB_PITCH_EVENT_FLAG_VARIATION 0x04 Enable variation
XSB_PITCH_EVENT_FLAG_RELATIVE 0x10 Use relative values
XSB_PITCH_EVENT_FLAG_FADE 0x20 Enable fade

VOLUME event flags

Name Value Description
XSB_VOLUME_EVENT_FLAG_VARIATION 0x04 Enable variation
XSB_VOLUME_EVENT_FLAG_RELATIVE 0x10 Use relative values
XSB_VOLUME_EVENT_FLAG_FADE 0x20 Enable fade

LOWPASS event flags

Name Value Description
XSB_LOWPASS_EVENT_FLAG_RANDOM 0x04 Random values
XSB_LOWPASS_EVENT_FLAG_RELATIVE 0x10 Use relative values
XSB_LOWPASS_EVENT_FLAG_SWEEP 0x20 Sweep cut-off frequencies

MARKER event flags

Name Value Description
XSB_MARKER_EVENT_FLAG_REPEAT 0x20 Repeat marker

Enums

Event types

Name Value Description
XSB_EVENT_TYPE_PLAY 0x00 Play a wave, from start to finish
XSB_EVENT_TYPE_PLAY_COMPLEX 0x01 Play a wave, with parameters
XSB_EVENT_TYPE_STOP 0x03 Stop playing
XSB_EVENT_TYPE_PITCH 0x04 Set the pitch
XSB_EVENT_TYPE_VOLUME 0x05 Set the volume
XSB_EVENT_TYPE_LOWPASS 0x07 Low-pass filter
XSB_EVENT_TYPE_LFO_PITCH 0x08 Low-frequency oscillator on the pitch
XSB_EVENT_TYPE_LFO_MULTI 0x09 Low-frequency oscillator on the pitch and amplitude
XSB_EVENT_TYPE_ENVELOPE_AMPLITUDE 0x0A DAHDSR envelope on the amplitude
XSB_EVENT_TYPE_ENVELOPE_PITCH 0x0B DAHDSR envelope on the pitch
XSB_EVENT_TYPE_LOOP 0x0C Loop a wave
XSB_EVENT_TYPE_MARKER 0x0E Marker
XSB_EVENT_TYPE_DISABLED 0x0F A disabled event
XSB_EVENT_TYPE_MIXBINS 0x10 Set a separate volume for each channel
XSB_EVENT_TYPE_ENVIRONMENT_REVERB 0x11 Environmental reverb
XSB_EVENT_TYPE_MIXBINSPAN 0x12 Set channel volumes according to a listener orientation

Variation selection methods

Name Value Description
XSB_VARIATION_SELECT_RANDOM_NOREPEATS 0x00 Random, but no immediate repeats
XSB_VARIATION_SELECT_ORDERED 0x01 One after the other, in order
XSB_VARIATION_SELECT_SHUFFLE 0x02 Random, no repeats at all
XSB_VARIATION_SELECT_PARAMETER 0x03 Game-controlled
XSB_VARIATION_SELECT_RANDOM 0x04 Completely random
XSB_VARIATION_SELECT_ORDERED_FROMRANDOM 0x05 Start with a random entry, then in order

Transition source

Name Value Description
XSB_TRANSITION_SOURCE_IMMEDIATE 0x00 Immediately
XSB_TRANSITION_SOURCE_MARKER 0x01 From a marker with a given range
XSB_TRANSITION_SOURCE_RANDOM_MARKER 0x02 From a random marker within a given range
XSB_TRANSITION_SOURCE_END_LOOP 0x04 End of loop
XSB_TRANSITION_SOURCE_END_SOUND 0x08 End of sound

Transition destination

Name Value Description
XSB_TRANSITION_DESTINATION_BEGINNING 0x00 To the beginning
XSB_TRANSITION_DESTINATION_ALIGNED_TIME 0x01 To the same time
XSB_TRANSITION_DESTINATION_ALIGNED_MARKER 0x02 To the same marker
XSB_TRANSITION_DESTINATION_MARKER 0x04 To a marker with a given range
XSB_TRANSITION_DESTINATION_RANDOM_MARKER 0x08 To a random marker within a given range

Transition effect

Name Value Description
XSB_TRANSITION_EFFECT_NONE 0x00 No effect
XSB_TRANSITION_EFFECT_CROSSFADE 0x01 Crossfade
XSB_TRANSITION_EFFECT_SOUND 0x02 Use a transitional sound
XSB_TRANSITION_EFFECT_SOUND_FADE_TO 0x03 Fade into a transitional sound
XSB_TRANSITION_EFFECT_SOUND_FADE_FROM 0x06 Fade from a transitional sound
XSB_TRANSITION_EFFECT_SOUND_FADE_TOFROM 0x07 Fade into and from a transitional sound