mirror of https://bitbucket.org/ausocean/av.git
ADPCM: 'writ' variables changed to 'n' as per convention. Documentation improved.
This commit is contained in:
parent
d4e0c87635
commit
14a602f423
|
@ -191,7 +191,8 @@ func (d *decoder) decodeSample(nibble byte) int16 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// calcHead sets the state for the encoder by running the first sample through
|
// calcHead sets the state for the encoder by running the first sample through
|
||||||
// the encoder, and writing the first sample.
|
// the encoder, and writing the first sample to the encoder's io.Writer (dest).
|
||||||
|
// It returns the number of bytes written to the encoder's io.Writer (dest) along with any errors.
|
||||||
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).
|
// Check that we are given 1 16-bit sample (2 bytes).
|
||||||
const sampSize = 2
|
const sampSize = 2
|
||||||
|
@ -202,40 +203,40 @@ func (e *encoder) calcHead(sample []byte) (int, error) {
|
||||||
intSample := int16(binary.LittleEndian.Uint16(sample))
|
intSample := int16(binary.LittleEndian.Uint16(sample))
|
||||||
e.encodeSample(intSample)
|
e.encodeSample(intSample)
|
||||||
|
|
||||||
writ, err := e.dest.Write(sample)
|
n, err := e.dest.Write(sample)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return writ, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = e.dest.WriteByte(byte(uint16(e.index)))
|
err = e.dest.WriteByte(byte(uint16(e.index)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return writ, err
|
return n, err
|
||||||
}
|
}
|
||||||
writ++
|
n++
|
||||||
|
|
||||||
err = e.dest.WriteByte(byte(0x00))
|
err = e.dest.WriteByte(byte(0x00))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return writ, err
|
return n, err
|
||||||
}
|
}
|
||||||
writ++
|
n++
|
||||||
return writ, nil
|
return n, 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.
|
// It writes encoded (compressed) bytes (each byte containing two ADPCM nibbles) to the encoder's io.Writer (dest).
|
||||||
|
// The number of bytes written is returned along with any errors.
|
||||||
// Note: nibbles are output in little endian order, eg. n1n0 n3n2 n5n4...
|
// 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.
|
// Note: first 4 bytes are for initializing the decoder before decoding a block.
|
||||||
// - First two bytes contain the first 16-bit sample uncompressed.
|
// - 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.
|
// - 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 {
|
if len(block) != PcmBS {
|
||||||
return writ, fmt.Errorf("unsupported block size. Given: %v, expected: %v, ie. 505 16-bit PCM samples", len(block), PcmBS)
|
return 0, fmt.Errorf("unsupported block size. Given: %v, expected: %v, ie. 505 16-bit PCM samples", len(block), PcmBS)
|
||||||
}
|
}
|
||||||
|
|
||||||
writ, err := e.calcHead(block[0:2])
|
n, err := e.calcHead(block[0:2])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return writ, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 3; i < PcmBS; i += 4 {
|
for i := 3; i < PcmBS; i += 4 {
|
||||||
|
@ -243,29 +244,29 @@ func (e *encoder) encodeBlock(block []byte) (int, error) {
|
||||||
nib2 := e.encodeSample(int16(binary.LittleEndian.Uint16(block[i+1 : i+3])))
|
nib2 := e.encodeSample(int16(binary.LittleEndian.Uint16(block[i+1 : i+3])))
|
||||||
err = e.dest.WriteByte(byte((nib2 << 4) | nib1))
|
err = e.dest.WriteByte(byte((nib2 << 4) | nib1))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return writ, err
|
return n, err
|
||||||
}
|
}
|
||||||
writ++
|
n++
|
||||||
}
|
}
|
||||||
|
|
||||||
return writ, nil
|
return n, 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.
|
// It writes the resulting decoded (decompressed) 16-bit PCM samples to the decoder's io.Writer (dest).
|
||||||
|
// The number of bytes written is returned along with any errors.
|
||||||
func (d *decoder) decodeBlock(block []byte) (int, error) {
|
func (d *decoder) decodeBlock(block []byte) (int, error) {
|
||||||
writ := 0
|
|
||||||
if len(block) != AdpcmBS {
|
if len(block) != AdpcmBS {
|
||||||
return writ, fmt.Errorf("unsupported block size. Given: %v, expected: %v", len(block), AdpcmBS)
|
return 0, fmt.Errorf("unsupported block size. Given: %v, expected: %v", len(block), AdpcmBS)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize decoder with first 4 bytes of the block.
|
// Initialize decoder with first 4 bytes of the block.
|
||||||
d.pred = int16(binary.LittleEndian.Uint16(block[0:2]))
|
d.pred = int16(binary.LittleEndian.Uint16(block[0:2]))
|
||||||
d.index = int16(block[2])
|
d.index = int16(block[2])
|
||||||
d.step = stepTable[d.index]
|
d.step = stepTable[d.index]
|
||||||
writ, err := d.dest.Write(block[0:2])
|
n, err := d.dest.Write(block[0:2])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return writ, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each byte, seperate it into two nibbles (each nibble is a compressed sample),
|
// For each byte, seperate it into two nibbles (each nibble is a compressed sample),
|
||||||
|
@ -277,22 +278,22 @@ func (d *decoder) decodeBlock(block []byte) (int, error) {
|
||||||
|
|
||||||
firstBytes := make([]byte, 2)
|
firstBytes := make([]byte, 2)
|
||||||
binary.LittleEndian.PutUint16(firstBytes, uint16(d.decodeSample(nib1)))
|
binary.LittleEndian.PutUint16(firstBytes, uint16(d.decodeSample(nib1)))
|
||||||
writS, err := d.dest.Write(firstBytes)
|
_n, err := d.dest.Write(firstBytes)
|
||||||
writ += writS
|
n += _n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return writ, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
secondBytes := make([]byte, 2)
|
secondBytes := make([]byte, 2)
|
||||||
binary.LittleEndian.PutUint16(secondBytes, uint16(d.decodeSample(nib2)))
|
binary.LittleEndian.PutUint16(secondBytes, uint16(d.decodeSample(nib2)))
|
||||||
writS, err = d.dest.Write(secondBytes)
|
_n, err = d.dest.Write(secondBytes)
|
||||||
writ += writS
|
n += _n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return writ, err
|
return n, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return writ, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write takes a slice of bytes of arbitrary length representing pcm and encodes in into adpcm.
|
// Write takes a slice of bytes of arbitrary length representing pcm and encodes in into adpcm.
|
||||||
|
@ -300,17 +301,17 @@ func (d *decoder) decodeBlock(block []byte) (int, error) {
|
||||||
// The number of bytes written out is returned along with any error that occured.
|
// The number of bytes written out is returned along with any error that occured.
|
||||||
func (e *encoder) Write(inPcm []byte) (int, error) {
|
func (e *encoder) Write(inPcm []byte) (int, error) {
|
||||||
numBlocks := len(inPcm) / PcmBS
|
numBlocks := len(inPcm) / PcmBS
|
||||||
writ := 0
|
n := 0
|
||||||
for i := 0; i < numBlocks; i++ {
|
for i := 0; i < numBlocks; i++ {
|
||||||
block := inPcm[PcmBS*i : PcmBS*(i+1)]
|
block := inPcm[PcmBS*i : PcmBS*(i+1)]
|
||||||
writB, err := e.encodeBlock(block)
|
_n, err := e.encodeBlock(block)
|
||||||
writ += writB
|
n += _n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return writ, err
|
return n, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return writ, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write takes a slice of bytes of arbitrary length representing adpcm and decodes in into pcm.
|
// Write takes a slice of bytes of arbitrary length representing adpcm and decodes in into pcm.
|
||||||
|
@ -318,15 +319,15 @@ func (e *encoder) Write(inPcm []byte) (int, error) {
|
||||||
// The number of bytes written out is returned along with any error that occured.
|
// The number of bytes written out is returned along with any error that occured.
|
||||||
func (d *decoder) Write(inAdpcm []byte) (int, error) {
|
func (d *decoder) Write(inAdpcm []byte) (int, error) {
|
||||||
numBlocks := len(inAdpcm) / AdpcmBS
|
numBlocks := len(inAdpcm) / AdpcmBS
|
||||||
writ := 0
|
n := 0
|
||||||
for i := 0; i < numBlocks; i++ {
|
for i := 0; i < numBlocks; i++ {
|
||||||
block := inAdpcm[AdpcmBS*i : AdpcmBS*(i+1)]
|
block := inAdpcm[AdpcmBS*i : AdpcmBS*(i+1)]
|
||||||
writB, err := d.decodeBlock(block)
|
_n, err := d.decodeBlock(block)
|
||||||
writ += writB
|
n += _n
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return writ, err
|
return n, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return writ, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue