Skip to main content

✍️ Learn how to decode stetho signal to PCM

Signal is A-law G 711 encoded with a sample rate of 4khz and each sample of 16 bit. In order to decode it in 16 bit PCM, here is an example of C algorithm:

int16_t alaw_decode(uint8_t c)
{
int16_t m, e;

/* Restore the original
bits */
c ^= 0x55;
/* Extract the mantissa and the
exponent */
m = c & 0x0f;
e = (c & 0x70) >> 4;
/* If the exponent is greater than 0, we have to set 5th bit to
1 */
if (e > 0) {
m |= 0x10;
}
/* Restore the full amplitude of the original
signal */
m <<= 4;
/* And set the least significant
bit */
m |= 0x08;
/* Shift the mantissa according to the
exponent */
if (e > 1) {
m <<= e-1;
}
/* If the most significant bit is not set, we have a negative
number */
if (c < 0x80) {
m = -m;
}

return m;
}

In Java:

object ALawCodec {

fun decode(sample: ByteArray): List<Short> {
return sample.map {
var mantissa: Short
val exponent: Short
var valueToDecode: UByte = it.toUByte()
valueToDecode = valueToDecode xor (0x55.toUByte())

mantissa = (valueToDecode and (0x0f.toUByte())).toShort()
exponent = ((valueToDecode and (0x70.toUByte())).toInt() shr 4).toShort()

if (exponent > 0) {
mantissa = mantissa or 0x10.toShort()
}
mantissa = (mantissa.toInt() shl 4).toShort()
mantissa = mantissa or 0x08.toShort()
if (exponent > 1) {
mantissa = (mantissa.toInt() shl (exponent.toInt() - 1)).toShort()
}
if (valueToDecode < 0x80.toUByte()) {
mantissa = (-mantissa).toShort()
}
mantissa
}
}
}