Skip to content

28 August 2026

M. T. Kimmins edited this page Aug 31, 2026 · 4 revisions

Untangling the A1800 Codec

Alrighty. Reading through John-K's documentation of the a1800 codec has me walking through the whole process step by step. It seems that some of the difficulty is in the fact that the soundwave at any given point is fragmented into frequencies and further encoded on the bit level. So, each hexadecimal byte is actually a collection of 1s and 0s in an 8 digit sequence. Each byte is a permutation of the different combinations of binary within 8 digits. Any digit can be either 1 or 0 in any order and pattern. It is the translation of our erroneous byte sequence into bits where we make the first un-twisting of the a1800 codec. The range of digits in hex range from 0-9 then extend to include the letters A-F (altogether, 0-F).

Byte to Bit Translation

Bytes (Hex) Bytes (Decimal) Bit Sequence (Binary)
54 84 01010100
B1 177 10110001
69 105 01101001
04 4 00000010
A9 169 10101001
32 50 00110010
0F 15 00001111
E4 228 11100100
26 38 00100110
D1 209 11010001
D6 214 11010110
41 65 01000001
D4 212 11010100
5A 90 01011010
98 152 10011000
52 82 01010010
3F 63 00111111
76 118 01110110
76 118 01110110
46 70 01000110
42 66 01000010
B0 176 10110000
36 54 00110110
52 82 01010010
43 67 01000011
EB 235 11101011
B6 182 10110110
07 7 00000111
DA 218 11011010
A3 163 10100011
21 33 00100001
18 24 00011000
D7 215 11010111
8F 143 10001111
7C 124 01111100
07 7 00000111
E2 226 11100010
8B 139 10001011
2B 43 00101011
8A 138 10001010

One can see that the number in hex can be misleading, as if a byte is comprised of 2 digits, then it is easy to assume that those two digits are the decimal value. However, as hex incorporates letters to extend the range of each character from 10 to 15, then we can see how this expansion skews the digits to misrepresent its value prima facie.

So altogether, we see the translation of the following hex string:

54 B1 69 04 A9 32 0F E4 26 D1 D6 41 D4 5A 98 52 3F 76 76 46 42 B0 36 52 43 EB B6 07 DA A3 21 18 D7 8F 7C 07 E2 8B 2B 8A

Turns into the following "bitstream":

01010100 10110001 01101001 00000100 10101001 00110010 00001111 11100100 00100110 11010001 11010110 01000001 11010100 01011010 10011000 01010010 00111111 01110110 01110110 01000110 01000010 10110000 00110110 01010010 01000011 11101011 10110110 00000111 11011010 10100011 00100001 00011000 11010111 10001111 01111100 00000111 11100010 10001011 00101011 10001010

Now What..?

Every sound we hear is made up of multiple frequencies of air pressure overlapping each other. For the codec, we can represent sound as how loud a frequency is, then track those changes over time. Imagine having several buckets, each labelled with a particular frequency. The codec tries to represent sound by how “full”, or loud, each frequency bucket is. These buckets are called “subbands.” Our next step is to determine what loudness each subband starts at. What are the starting frequencies of this particular sound? Luckily, John-K has revealed that the first subband's frequency is quantified by the first 5 bits of the bitstream above. This would give us:

01010

Which translates to 10 in decimal. According to John-K’s repo, we see that the first subband “gain”, energy, or loudness value is represented as such: $$G_i=G_r-7$$ Where

  • $G_i$ is the actual value we want to set for the subband,
  • $G_r$ is the raw, 5-bit decoded value (in our case, 10).

So the real value of the first subband is $$10-7=3$$.


⟵ Older Table of Contents Newer ⟶

Clone this wiki locally