From d4e0c876356a6ca3315e398791600d4b899c9a2c Mon Sep 17 00:00:00 2001 From: Trek H Date: Fri, 15 Mar 2019 17:22:19 +1030 Subject: [PATCH] ADPCM: unexported encoder and decoder structs, documented Write funcs. --- audio/adpcm/adpcm.go | 53 +++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/audio/adpcm/adpcm.go b/audio/adpcm/adpcm.go index 5aaa98b1..ee6feaf6 100644 --- a/audio/adpcm/adpcm.go +++ b/audio/adpcm/adpcm.go @@ -38,31 +38,31 @@ import ( "fmt" ) -// Encoder is used to encode to ADPCM from PCM data. +// encoder is used to encode to ADPCM from PCM data. // pred and index hold state that persists between calls to encodeSample and calcHead. // dest is the output buffer that implements io.writer and io.bytewriter, ie. where the encoded ADPCM data is written to. -type Encoder struct { +type encoder struct { dest *bytes.Buffer pred int16 index int16 } -// Decoder is used to decode from ADPCM to PCM data. +// decoder is used to decode from ADPCM to PCM data. // pred, index, and step hold state that persists between calls to decodeSample. // dest is the output buffer that implements io.writer and io.bytewriter, ie. where the decoded PCM data is written to. -type Decoder struct { +type decoder struct { dest *bytes.Buffer pred int16 index int16 step int16 } -// PcmBS is the size of the blocks that an Encoder uses. -// 'EncodeBlock' will encode PcmBS bytes at a time and the output will be AdpcmBS bytes long. +// PcmBS is the size of the blocks that an encoder uses. +// 'encodeBlock' will encode PcmBS bytes at a time and the output will be AdpcmBS bytes long. const PcmBS = 1010 -// AdpcmBS is the size of the blocks that a Decoder uses. -// 'DecodeBlock' will decode AdpcmBS bytes at a time and the output will be PcmBS bytes long. +// AdpcmBS is the size of the blocks that a decoder uses. +// 'decodeBlock' will decode AdpcmBS bytes at a time and the output will be PcmBS bytes long. const AdpcmBS = 256 // Table of index changes (see spec). @@ -88,16 +88,16 @@ var stepTable = []int16{ } // NewEncoder retuns a new ADPCM encoder. -func NewEncoder(dst *bytes.Buffer) *Encoder { - e := Encoder{ +func NewEncoder(dst *bytes.Buffer) *encoder { + e := encoder{ dest: dst, } return &e } // NewDecoder retuns a new ADPCM decoder. -func NewDecoder(dst *bytes.Buffer) *Decoder { - d := Decoder{ +func NewDecoder(dst *bytes.Buffer) *decoder { + d := decoder{ step: stepTable[0], dest: dst, } @@ -106,7 +106,7 @@ func NewDecoder(dst *bytes.Buffer) *Decoder { // encodeSample takes a single 16 bit PCM sample and // returns a byte of which the last 4 bits are an encoded ADPCM nibble. -func (e *Encoder) encodeSample(sample int16) byte { +func (e *encoder) encodeSample(sample int16) byte { // Find difference of actual sample from encoder's prediction. delta := sample - e.pred @@ -139,6 +139,7 @@ func (e *Encoder) encodeSample(sample int16) byte { } e.index += indexTable[nib&7] + // Check for underflow and overflow. if e.index < 0 { e.index = 0 @@ -151,7 +152,7 @@ func (e *Encoder) encodeSample(sample int16) byte { // decodeSample takes a byte, the last 4 bits of which contain a single // 4 bit ADPCM nibble, and returns a 16 bit decoded PCM sample. -func (d *Decoder) decodeSample(nibble byte) int16 { +func (d *decoder) decodeSample(nibble byte) int16 { // Calculate difference. var diff int16 if nibble&4 != 0 { @@ -191,7 +192,7 @@ func (d *Decoder) decodeSample(nibble byte) int16 { // calcHead sets the state for the encoder by running the first sample through // the encoder, and writing the first sample. -func (e *Encoder) calcHead(sample []byte) (int, error) { +func (e *encoder) calcHead(sample []byte) (int, error) { // Check that we are given 1 16-bit sample (2 bytes). const sampSize = 2 if len(sample) != sampSize { @@ -220,13 +221,13 @@ func (e *Encoder) calcHead(sample []byte) (int, error) { return writ, nil } -// EncodeBlock takes a slice of 1010 bytes (505 16-bit PCM samples). +// encodeBlock takes a slice of 1010 bytes (505 16-bit PCM samples). // It outputs encoded (compressed) bytes (each byte containing two ADPCM nibbles) to the encoder's dest writer. // Note: nibbles are output in little endian order, eg. n1n0 n3n2 n5n4... // Note: first 4 bytes are for initializing the decoder before decoding a block. // - First two bytes contain the first 16-bit sample uncompressed. // - Third byte is the decoder's starting index for the block, the fourth is padding and ignored. -func (e *Encoder) EncodeBlock(block []byte) (int, error) { +func (e *encoder) encodeBlock(block []byte) (int, error) { writ := 0 if len(block) != PcmBS { return writ, fmt.Errorf("unsupported block size. Given: %v, expected: %v, ie. 505 16-bit PCM samples", len(block), PcmBS) @@ -250,9 +251,9 @@ func (e *Encoder) EncodeBlock(block []byte) (int, error) { return writ, nil } -// DecodeBlock takes a slice of 256 bytes, each byte after the first 4 should contain two ADPCM encoded nibbles. +// decodeBlock takes a slice of 256 bytes, each byte after the first 4 should contain two ADPCM encoded nibbles. // It outputs the resulting decoded (decompressed) 16-bit PCM samples to the decoder's dest writer. -func (d *Decoder) DecodeBlock(block []byte) (int, error) { +func (d *decoder) decodeBlock(block []byte) (int, error) { writ := 0 if len(block) != AdpcmBS { return writ, fmt.Errorf("unsupported block size. Given: %v, expected: %v", len(block), AdpcmBS) @@ -294,12 +295,15 @@ func (d *Decoder) DecodeBlock(block []byte) (int, error) { return writ, nil } -func (e *Encoder) Write(inPcm []byte) (int, error) { +// Write takes a slice of bytes of arbitrary length representing pcm and encodes in into adpcm. +// 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 writ := 0 for i := 0; i < numBlocks; i++ { block := inPcm[PcmBS*i : PcmBS*(i+1)] - writB, err := e.EncodeBlock(block) + writB, err := e.encodeBlock(block) writ += writB if err != nil { return writ, err @@ -309,12 +313,15 @@ func (e *Encoder) Write(inPcm []byte) (int, error) { return writ, nil } -func (d *Decoder) Write(inAdpcm []byte) (int, error) { +// Write takes a slice of bytes of arbitrary length representing adpcm and decodes in into pcm. +// 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 writ := 0 for i := 0; i < numBlocks; i++ { block := inAdpcm[AdpcmBS*i : AdpcmBS*(i+1)] - writB, err := d.DecodeBlock(block) + writB, err := d.decodeBlock(block) writ += writB if err != nil { return writ, err