How to write G.711u (ulaw / mulaw) to wav?
Issue
I have a 8Khz 8-bit PCM ulaw byte slice that I would like to convert to a WAV file. When I try to convert it using this library, I get audio that is loud and choppy, sounding a bit like the following issue.
https://github.com/go-audio/audio/issues/16
I'm using an Encoder as follows:
wav := NewEncoder(f, 8000, 8, 1, 1)
I'm not quite sure how to convert the raw byte slice into an audio.IntBuffer so I'm doing the following, which results in the poor quality audio.
func BytesToInts(bytes []byte) []int {
ints := []int{}
for _, b := range bytes {
ints = append(ints, int(b))
}
return ints
}
func UlawByteSliceToIntBuffer(bytes []byte) *audio.IntBuffer {
return &audio.IntBuffer{
Format: &audio.Format{
NumChannels: 1,
SampleRate: 8000},
SourceBitDepth: 8,
Data: BytesToInts(bytes)}
}
Any tips on how to get this library to work for this?
Alternative 1 - Works
As an alternative, the following raw approach results in good sounding audio where I can write out the bytes without transformation.
var wavHeaderThin = []byte{0x52, 0x49, 0x46, 0x46, 0x62, 0xb8, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20,
0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x80, 0x3e, 0x00, 0x00,
0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66, 0x61, 0x63, 0x74, 0x04, 0x00, 0x00, 0x00, 0xc5, 0x5b,
0x00, 0x00, 0x64, 0x61, 0x74, 0x61}
func WriteFileWavFromUlaw(filename string, ulawBytes []byte) error {
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
_, err = WriteWavFromUlaw(f, ulawBytes)
return err
}
func WriteWavFromUlaw(w io.Writer, ulawBytes []byte) (n int, err error) {
n1, err := w.Write(wavHeaderThin)
if err != nil {
return n, err
}
n += n1
count := len(ulawBytes)
n2, err := w.Write([]byte{
byte(count % 256),
byte((count >> 8) % 256),
byte((count >> 16) % 256),
byte((count >> 24) % 256)})
if err != nil {
return n, err
}
n += n2
n3, err := w.Write(ulawBytes)
if err != nil {
return n, err
}
return n + n3, nil
}
I've added this here for easy reuse:
https://github.com/grokify/simplego/blob/master/audio/ulaw/ulaw.go
Alternative 2 - Works
$ ffmpeg -f mulaw -ar 8000 -i input.ulaw output.wav