Difference between revisions of "Xbox ADPCM"

From xboxdevwiki
Jump to: navigation, search
 
(16 intermediate revisions by the same user not shown)
Line 1: Line 1:
Xbox used it's own WAV file format to encode ADPCM data. This format is often called Xbox ADPCM.
+
Xbox used it's own WAV file format to encode data using [[Wikipedia:Adaptive differential pulse-code modulation|ADPCM]]. This format is often called Xbox ADPCM.
  
 
Standard IMA ADPCM WAV files would use format code 0x0011, whereas Xbox ADPCM files use format-code 0x0069.
 
Standard IMA ADPCM WAV files would use format code 0x0011, whereas Xbox ADPCM files use format-code 0x0069.
Line 8: Line 8:
 
This value is also stored in the 'fmt ' extra-data which is always 2 bytes, containing the Bytes <code>0x40, 0x00</code> (64 as unsigned 16-bit integer).
 
This value is also stored in the 'fmt ' extra-data which is always 2 bytes, containing the Bytes <code>0x40, 0x00</code> (64 as unsigned 16-bit integer).
 
Because of that, all Xbox ADPCM files will have a block alignment of 36 (Mono) or 72 (Stereo) Bytes.
 
Because of that, all Xbox ADPCM files will have a block alignment of 36 (Mono) or 72 (Stereo) Bytes.
As the decoder-setup in every block contains a predictor for each channel, there will be 65 samples / channel output per block (65:36 compression ratio = 44.6% compression).
+
As the decoder-setup in every block contains a predictor for each channel, there will be 65 samples / channel output per block (130:36 compression ratio = 72.3% compressed).
  
 
Aside from what was mentioned, there are no known differences to IMA ADPCM.
 
Aside from what was mentioned, there are no known differences to IMA ADPCM.
Line 20: Line 20:
 
In the following tables, the following notation is used:
 
In the following tables, the following notation is used:
  
 +
* All indices start at 0
 
* W# denotes a 32-bit word
 
* W# denotes a 32-bit word
 
* B# denotes a Byte (8-bit)
 
* B# denotes a Byte (8-bit)
Line 27: Line 28:
 
* Background color denotes the channel:
 
* Background color denotes the channel:
 
** <div style="display: inline-block; width:10px; height:10px; border:1px solid black; background-color:SkyBlue"></div> Blue: Left = Right
 
** <div style="display: inline-block; width:10px; height:10px; border:1px solid black; background-color:SkyBlue"></div> Blue: Left = Right
** <div style="display: inline-block; width:10px; height:10px; border:1px solid black; background-color:Snow;"></div> White: Left
+
** <div style="display: inline-block; width:10px; height:10px; border:1px solid black; background-color:White;"></div> White: Left
 
** <div style="display: inline-block; width:10px; height:10px; border:1px solid black; background-color:Tomato"></div> Red: Right
 
** <div style="display: inline-block; width:10px; height:10px; border:1px solid black; background-color:Tomato"></div> Red: Right
  
Line 33: Line 34:
  
 
{{FIXME|reason=Fix cell width}}
 
{{FIXME|reason=Fix cell width}}
{{FIXME|reason=Fix cell colors, can we somehow set the scope for background color?}}
+
{| class="wikitable" style="font-size:90%; text-align:center;"
 +
! 32-bit word
 +
| colspan="8" width="20%" | W0
 +
| colspan="8" width="20%" | W1
 +
| colspan="8" width="20%" | W2
 +
| rowspan="3" width="5%" | ...
 +
| colspan="8" width="20%" | W8
 +
|-
 +
! Byte       
 +
| colspan="2" | B0 || colspan="2" | B1 || colspan="2" | B2 || colspan="2" | B3
 +
| colspan="2" | B4 || colspan="2" | B5 || colspan="2" | B6 || colspan="2" | B7
 +
| colspan="2" | B8 || colspan="2" | B9 || colspan="2" | B10 || colspan="2" | B11
 +
| colspan="2" | B32 || colspan="2" | B33 || colspan="2" | B34 || colspan="2" | B35
 +
|-
 +
! Meaning
 +
| style="background-color:SkyBlue;" colspan="4" | P = S0
 +
| style="background-color:SkyBlue;" colspan="2" | SI
 +
| colspan="2" |
 +
| style="background-color:SkyBlue;" |  S2 || style="background-color:SkyBlue;" |  S1
 +
| style="background-color:SkyBlue;" |  S4 || style="background-color:SkyBlue;" |  S3
 +
| style="background-color:SkyBlue;" |  S6 || style="background-color:SkyBlue;" |  S5
 +
| style="background-color:SkyBlue;" |  S8 || style="background-color:SkyBlue;" |  S7
 +
| style="background-color:SkyBlue;" | S10 || style="background-color:SkyBlue;" |  S9
 +
| style="background-color:SkyBlue;" | S12 || style="background-color:SkyBlue;" | S11
 +
| style="background-color:SkyBlue;" | S14 || style="background-color:SkyBlue;" | S13
 +
| style="background-color:SkyBlue;" | S16 || style="background-color:SkyBlue;" | S15
 +
| style="background-color:SkyBlue;" | S58 || style="background-color:SkyBlue;" | S57
 +
| style="background-color:SkyBlue;" | S60 || style="background-color:SkyBlue;" | S59
 +
| style="background-color:SkyBlue;" | S62 || style="background-color:SkyBlue;" | S61
 +
| style="background-color:SkyBlue;" | S64 || style="background-color:SkyBlue;" | S63
 +
|}
 +
 
 +
==== Stereo ====
 +
 
 +
 
 +
{{FIXME|reason=Fix cell width}}
 
{| class="wikitable" style="font-size:90%; text-align:center;"
 
{| class="wikitable" style="font-size:90%; text-align:center;"
 
! 32-bit word
 
! 32-bit word
Line 39: Line 75:
 
| colspan="8" | W1
 
| colspan="8" | W1
 
| colspan="8" | W2
 
| colspan="8" | W2
| rowspan="3" | ...
+
| colspan="8" | W3
| colspan="8" | W7
 
| colspan="8" | W8
 
 
|-
 
|-
 
! Byte         
 
! Byte         
Line 47: Line 81:
 
| colspan="2" | B4 || colspan="2" | B5 || colspan="2" | B6 || colspan="2" | B7
 
| colspan="2" | B4 || colspan="2" | B5 || colspan="2" | B6 || colspan="2" | B7
 
| colspan="2" | B8 || colspan="2" | B9 || colspan="2" | B10 || colspan="2" | B11
 
| colspan="2" | B8 || colspan="2" | B9 || colspan="2" | B10 || colspan="2" | B11
| colspan="2" | B28 || colspan="2" | B29 || colspan="2" | B30 || colspan="2" | B31
+
| colspan="2" | B12 || colspan="2" | B13 || colspan="2" | B14 || colspan="2" | B15
| colspan="2" | B32 || colspan="2" | B33 || colspan="2" | B34 || colspan="2" | B35
 
 
|-
 
|-
 
! Meaning
 
! Meaning
| colspan="4" | P = S0
+
| style="background-color:White;"  colspan="4" | P = S0
| colspan="2" | SI
+
| style="background-color:White;"  colspan="2" | SI
 
| colspan="2" |  
 
| colspan="2" |  
| style="background-color:SkyBlue;" |  S2 ||  S1 ||  S4 ||  S3 ||  S6 ||  S5 ||  S8 ||  S7
+
| style="background-color:Tomato;" colspan="4" | P = S0
| style="background-color:SkyBlue;" | S10 |S9 || S12 || S11 || S14 || S13 || S16 || S15
+
| style="background-color:Tomato;" colspan="2" | SI
| style="background-color:SkyBlue;" | S50 || S49 || S52 || S51 || S54 || S53 || S56 || S55
+
| colspan="2" |
| style="background-color:SkyBlue;" | S58 || S57 || S60 || S59 || S62 || S61 || S64 || S63
+
| style="background-color:White;"  |  S2 || style="background-color:White;"  |  S1  
 +
| style="background-color:White;"  |  S4 || style="background-color:White;"  |  S3
 +
| style="background-color:White;"  |  S6 || style="background-color:White;"  |  S5
 +
| style="background-color:White;"  |  S8 || style="background-color:White;"  |  S7
 +
| style="background-color:Tomato;" |  S2 || style="background-color:Tomato;" | S1
 +
| style="background-color:Tomato;" | S4 || style="background-color:Tomato;" | S3
 +
| style="background-color:Tomato;" | S6 || style="background-color:Tomato;" | S5
 +
| style="background-color:Tomato;" | S8 || style="background-color:Tomato;" | S7
 
|}
 
|}
 +
...
 +
{| class="wikitable" style="font-size:90%; text-align:center;"
 +
! 32-bit word
 +
| colspan="8" | W14
 +
| colspan="8" | W15
 +
| colspan="8" | W16
 +
| colspan="8" | W17
 +
|-
 +
! Byte       
 +
| colspan="2" | B56 || colspan="2" | B57 || colspan="2" | B58 || colspan="2" | B59
 +
| colspan="2" | B60 || colspan="2" | B61 || colspan="2" | B62 || colspan="2" | B63
 +
| colspan="2" | B64 || colspan="2" | B65 || colspan="2" | B66 || colspan="2" | B67
 +
| colspan="2" | B68 || colspan="2" | B69 || colspan="2" | B70 || colspan="2" | B71
 +
|-
 +
! Meaning
  
==== Stereo ====
+
| style="background-color:White;"  | S50 || style="background-color:White;"  | S49
 
+
| style="background-color:White;"  | S52 || style="background-color:White;"  | S51
{{FIXME|reason=Add table}}
+
| style="background-color:White;"  | S54 || style="background-color:White;"  | S53
 +
| style="background-color:White;"  | S56 || style="background-color:White;"  | S55
 +
| style="background-color:Tomato;" | S50 || style="background-color:Tomato;" | S49
 +
| style="background-color:Tomato;" | S52 || style="background-color:Tomato;" | S51
 +
| style="background-color:Tomato;" | S54 || style="background-color:Tomato;" | S53
 +
| style="background-color:Tomato;" | S56 || style="background-color:Tomato;" | S55
 +
| style="background-color:White;"  | S58 || style="background-color:White;"  | S57
 +
| style="background-color:White;"  | S60 || style="background-color:White;"  | S59
 +
| style="background-color:White;"  | S62 || style="background-color:White;"  | S61
 +
| style="background-color:White;"  | S64 || style="background-color:White;"  | S63
 +
| style="background-color:Tomato;" | S58 || style="background-color:Tomato;" | S57
 +
| style="background-color:Tomato;" | S60 || style="background-color:Tomato;" | S59
 +
| style="background-color:Tomato;" | S62 || style="background-color:Tomato;" | S61
 +
| style="background-color:Tomato;" | S64 || style="background-color:Tomato;" | S63
 +
|}
  
 
=== Index-Table ===
 
=== Index-Table ===
Line 69: Line 138:
  
 
{| class="wikitable" style="text-align: right;"
 
{| class="wikitable" style="text-align: right;"
!     ||    +0 ||    +1 ||    +2 ||    +3 ||    +4 ||    +5 ||    +6 ||    +7
+
!
 +
! {{no-select}} | +0
 +
! {{no-select}} | +1
 +
! {{no-select}} | +2
 +
! {{no-select}} | +3
 +
! {{no-select}} | +4
 +
! {{no-select}} | +5
 +
! {{no-select}} | +6
 +
! {{no-select}} | +7
 
|-
 
|-
! 0
+
! {{no-select}} | 0
| -1 || -1 || -1 || -1 || 2 || 4 || 6 || 8  
+
| -1{{hc}} || -1{{hc}} || -1{{hc}} || -1{{hc}} || 2{{hc}} || 4{{hc}} || 6{{hc}} || 8{{hc}}
 
|-
 
|-
! 8
+
! {{no-select}} | 8
| -1 || -1 || -1 || -1 || 2 || 4 || 6 || 8  
+
| -1{{hc}} || -1{{hc}} || -1{{hc}} || -1{{hc}} || 2{{hc}} || 4{{hc}} || 6{{hc}} || 8
 
|}
 
|}
  
Line 83: Line 160:
  
 
{| class="wikitable" style="text-align: right;"
 
{| class="wikitable" style="text-align: right;"
!     ||    +0 ||    +1 ||    +2 ||    +3 ||    +4 ||    +5 ||    +6 ||    +7 ||    +8 ||    +9
+
!
 +
! {{no-select}} | +0  
 +
! {{no-select}} | +1  
 +
! {{no-select}} | +2  
 +
! {{no-select}} | +3  
 +
! {{no-select}} | +4  
 +
! {{no-select}} | +5  
 +
! {{no-select}} | +6  
 +
! {{no-select}} | +7  
 +
! {{no-select}} | +8  
 +
! {{no-select}} | +9
 
|-
 
|-
! 0
+
! {{no-select}} | 0
|    7 ||    8 ||    9 ||    10 ||    11 ||    12 ||    13 ||    14 ||    16 ||    17
+
|    7{{hc}} ||    8{{hc}} ||    9{{hc}} ||    10{{hc}} ||    11{{hc}} ||    12{{hc}} ||    13{{hc}} ||    14{{hc}} ||    16{{hc}} ||    17{{hc}}
 
|-
 
|-
! 10
+
! {{no-select}} | 10
|    19 ||    21 ||    23 ||    25 ||    28 ||    31 ||    34 ||    37 ||    41 ||    45  
+
|    19{{hc}} ||    21{{hc}} ||    23{{hc}} ||    25{{hc}} ||    28{{hc}} ||    31{{hc}} ||    34{{hc}} ||    37{{hc}} ||    41{{hc}} ||    45{{hc}}
 
|-
 
|-
! 20
+
! {{no-select}} | 20
|    50 ||    55 ||    60 ||    66 ||    73 ||    80 ||    88 ||    97 ||  107 ||  118  
+
|    50{{hc}} ||    55{{hc}} ||    60{{hc}} ||    66{{hc}} ||    73{{hc}} ||    80{{hc}} ||    88{{hc}} ||    97{{hc}} ||  107{{hc}} ||  118{{hc}}
 
|-
 
|-
! 30
+
! {{no-select}} | 30
|  130 ||  143 ||  157 ||  173 ||  190 ||  209 ||  230 ||  253 ||  279 ||  307
+
|  130{{hc}} ||  143{{hc}} ||  157{{hc}} ||  173{{hc}} ||  190{{hc}} ||  209{{hc}} ||  230{{hc}} ||  253{{hc}} ||  279{{hc}} ||  307{{hc}}
 
|-
 
|-
! 40
+
! {{no-select}} | 40
|  337 ||  371 ||  408 ||  449 ||  494 ||  544 ||  598 ||  658 ||  724 ||  796
+
|  337{{hc}} ||  371{{hc}} ||  408{{hc}} ||  449{{hc}} ||  494{{hc}} ||  544{{hc}} ||  598{{hc}} ||  658{{hc}} ||  724{{hc}} ||  796{{hc}}
 
|-
 
|-
! 50
+
! {{no-select}} | 50
|  876 ||  963 ||  1060 ||  1166 ||  1282 ||  1411 ||  1552 ||  1707 ||  1878 ||  2066
+
|  876{{hc}} ||  963{{hc}} ||  1060{{hc}} ||  1166{{hc}} ||  1282{{hc}} ||  1411{{hc}} ||  1552{{hc}} ||  1707{{hc}} ||  1878{{hc}} ||  2066{{hc}}
 
|-
 
|-
! 60
+
! {{no-select}} | 60
|  2272 ||  2499 ||  2749 ||  3024 ||  3327 ||  3660 ||  4026 ||  4428 ||  4871 ||  5358
+
|  2272{{hc}} ||  2499{{hc}} ||  2749{{hc}} ||  3024{{hc}} ||  3327{{hc}} ||  3660{{hc}} ||  4026{{hc}} ||  4428{{hc}} ||  4871{{hc}} ||  5358{{hc}}
 
|-
 
|-
! 70
+
! {{no-select}} | 70
|  5894 ||  6484 ||  7132 ||  7845 ||  8630 ||  9493 || 10442 || 11487 || 12635 || 13899
+
|  5894{{hc}} ||  6484{{hc}} ||  7132{{hc}} ||  7845{{hc}} ||  8630{{hc}} ||  9493{{hc}} || 10442{{hc}} || 11487{{hc}} || 12635{{hc}} || 13899{{hc}}
 
|-
 
|-
! 80
+
! {{no-select}} | 80
| 15289 || 16818 || 18500 || 20350 || 22385 || 24623 || 27086 || 29794 || 32767 ||       
+
| 15289{{hc}} || 16818{{hc}} || 18500{{hc}} || 20350{{hc}} || 22385{{hc}} || 24623{{hc}} || 27086{{hc}} || 29794{{hc}} || 32767       ||       
 
|}
 
|}
  
Line 124: Line 211:
 
* [https://github.com/JayFoxRox/xbox-tools/tree/master/adpcm-decoder Tool to decode Xbox ADPCM files]
 
* [https://github.com/JayFoxRox/xbox-tools/tree/master/adpcm-decoder Tool to decode Xbox ADPCM files]
 
* [http://samples.ffmpeg.org/game-formats/xbox-adpcm-wav/ Sample files by FFmpeg]
 
* [http://samples.ffmpeg.org/game-formats/xbox-adpcm-wav/ Sample files by FFmpeg]
 +
 +
[[Category:APU]]

Latest revision as of 16:03, 29 December 2018

Xbox used it's own WAV file format to encode data using ADPCM. This format is often called Xbox ADPCM.

Standard IMA ADPCM WAV files would use format code 0x0011, whereas Xbox ADPCM files use format-code 0x0069.

There are always 1 (Mono) or 2 (Stereo) channels[citation needed].

All Xbox ADPCM files seem to store 64 ADPCM input nibbles per block. This value is also stored in the 'fmt ' extra-data which is always 2 bytes, containing the Bytes 0x40, 0x00 (64 as unsigned 16-bit integer). Because of that, all Xbox ADPCM files will have a block alignment of 36 (Mono) or 72 (Stereo) Bytes. As the decoder-setup in every block contains a predictor for each channel, there will be 65 samples / channel output per block (130:36 compression ratio = 72.3% compressed).

Aside from what was mentioned, there are no known differences to IMA ADPCM. This is probably because the APU VP will decode ADPCM in hardware. Microsoft probably had little control over the APU ADPCM implementation and had to stay compatible to standard ADPCM. Players supporting IMA ADPCM also support Xbox ADPCM. However, they might reject files due to the different format-code.

Block format

Same as IMA ADPCM

In the following tables, the following notation is used:

  • All indices start at 0
  • W# denotes a 32-bit word
  • B# denotes a Byte (8-bit)
  • P denotes the ADPCM predictor for the block
  • SI denotes the Step-Index for the block
  • S# denotes a sample
  • Background color denotes the channel:
    • Blue: Left = Right
    • White: Left
    • Red: Right

Mono

[FIXME]

32-bit word W0 W1 W2 ... W8
Byte B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B32 B33 B34 B35
Meaning P = S0 SI S2 S1 S4 S3 S6 S5 S8 S7 S10 S9 S12 S11 S14 S13 S16 S15 S58 S57 S60 S59 S62 S61 S64 S63

Stereo

[FIXME]

32-bit word W0 W1 W2 W3
Byte B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 B15
Meaning P = S0 SI P = S0 SI S2 S1 S4 S3 S6 S5 S8 S7 S2 S1 S4 S3 S6 S5 S8 S7

...

32-bit word W14 W15 W16 W17
Byte B56 B57 B58 B59 B60 B61 B62 B63 B64 B65 B66 B67 B68 B69 B70 B71
Meaning S50 S49 S52 S51 S54 S53 S56 S55 S50 S49 S52 S51 S54 S53 S56 S55 S58 S57 S60 S59 S62 S61 S64 S63 S58 S57 S60 S59 S62 S61 S64 S63

Index-Table

Same as IMA ADPCM

+0 +1 +2 +3 +4 +5 +6 +7
0 -1, -1, -1, -1, 2, 4, 6, 8,
8 -1, -1, -1, -1, 2, 4, 6, 8

Step-Table

Same as IMA ADPCM

+0 +1 +2 +3 +4 +5 +6 +7 +8 +9
0 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
10 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
20 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
30 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
40 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
50 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
60 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
70 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
80 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767

Algorithm

The algorithms for encoding and decoding are the same as IMA ADPCM. For an example implementation and an explanation, refer to the related links.

Related links