From 2600fa884f6d71d325dfad995cc1d053106a88d6 Mon Sep 17 00:00:00 2001 From: Trek H Date: Fri, 29 Mar 2019 16:08:10 +1030 Subject: [PATCH] adpcm: modified the adpcm encoding and decoding to not use blocks --- audio/adpcm/adpcm.go | 50 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/audio/adpcm/adpcm.go b/audio/adpcm/adpcm.go index 595728a2..3e1f48f1 100644 --- a/audio/adpcm/adpcm.go +++ b/audio/adpcm/adpcm.go @@ -300,15 +300,20 @@ func (d *decoder) decodeBlock(block []byte) (int, error) { // It writes its output to the encoder's dest. // The number of bytes written out is returned along with any error that occured. func (e *encoder) Write(inPcm []byte) (int, error) { - numBlocks := len(inPcm) / PcmBS - n := 0 - for i := 0; i < numBlocks; i++ { - block := inPcm[PcmBS*i : PcmBS*(i+1)] - _n, err := e.encodeBlock(block) - n += _n + + n, err := e.calcHead(inPcm[0:2]) + if err != nil { + return n, err + } + + for i := 3; i < len(inPcm); i += 4 { + nib1 := e.encodeSample(int16(binary.LittleEndian.Uint16(inPcm[i-1 : i+1]))) + nib2 := e.encodeSample(int16(binary.LittleEndian.Uint16(inPcm[i+1 : i+3]))) + err = e.dest.WriteByte(byte((nib2 << 4) | nib1)) if err != nil { return n, err } + n++ } return n, nil @@ -318,11 +323,34 @@ func (e *encoder) Write(inPcm []byte) (int, error) { // It writes its output to the decoder's dest. // The number of bytes written out is returned along with any error that occured. func (d *decoder) Write(inAdpcm []byte) (int, error) { - numBlocks := len(inAdpcm) / AdpcmBS - n := 0 - for i := 0; i < numBlocks; i++ { - block := inAdpcm[AdpcmBS*i : AdpcmBS*(i+1)] - _n, err := d.decodeBlock(block) + + // Initialize decoder with first 4 bytes of the inAdpcm. + d.pred = int16(binary.LittleEndian.Uint16(inAdpcm[0:2])) + d.index = int16(inAdpcm[2]) + d.step = stepTable[d.index] + n, err := d.dest.Write(inAdpcm[0:2]) + if err != nil { + return n, err + } + + // For each byte, seperate it into two nibbles (each nibble is a compressed sample), + // then decode each nibble and output the resulting 16-bit samples. + for i := 4; i < len(inAdpcm); i++ { + twoNibs := inAdpcm[i] + nib2 := byte(twoNibs >> 4) + nib1 := byte((nib2 << 4) ^ twoNibs) + + firstBytes := make([]byte, 2) + binary.LittleEndian.PutUint16(firstBytes, uint16(d.decodeSample(nib1))) + _n, err := d.dest.Write(firstBytes) + n += _n + if err != nil { + return n, err + } + + secondBytes := make([]byte, 2) + binary.LittleEndian.PutUint16(secondBytes, uint16(d.decodeSample(nib2))) + _n, err = d.dest.Write(secondBytes) n += _n if err != nil { return n, err