package audio import "encoding/binary" const muLawBias = 0x84 const muLawClip = 32635 func EncodeULaw(pcm []byte) []byte { out := make([]byte, len(pcm)/2) for i := range out { out[i] = LinearToULaw(int16(binary.LittleEndian.Uint16(pcm[i*2:]))) } return out } func DecodeULaw(data []byte) []byte { out := make([]byte, len(data)*2) for i, sample := range data { binary.LittleEndian.PutUint16(out[i*2:], uint16(ULawToLinear(sample))) } return out } func LinearToULaw(sample int16) byte { pcm := int(sample) sign := byte(0) if pcm < 0 { pcm = -pcm sign = 0x80 } if pcm > muLawClip { pcm = muLawClip } pcm += muLawBias exponent := 7 for mask := 0x4000; (pcm&mask) == 0 && exponent > 0; mask >>= 1 { exponent-- } mantissa := (pcm >> (exponent + 3)) & 0x0f return ^(sign | byte(exponent<<4) | byte(mantissa)) } func ULawToLinear(sample byte) int16 { u := ^sample sign := u & 0x80 exponent := (u >> 4) & 0x07 mantissa := u & 0x0f pcm := ((int(mantissa) << 3) + muLawBias) << exponent pcm -= muLawBias if sign != 0 { pcm = -pcm } return int16(pcm) }