55 lines
1.1 KiB
Go
55 lines
1.1 KiB
Go
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)
|
|
}
|