diff --git a/stream/adpcm/adpcm.go b/stream/adpcm/adpcm.go index b4963efb..5359253e 100644 --- a/stream/adpcm/adpcm.go +++ b/stream/adpcm/adpcm.go @@ -97,9 +97,9 @@ func encodeSample(sample int16) byte { // adjust predicted sample based on calculated difference if nibble&8 != 0 { - encPred -= diff + encPred = capAdd16(encPred, -diff) } else { - encPred += diff + encPred = capAdd16(encPred, diff) } // check for underflow and overflow @@ -142,20 +142,8 @@ func decodeSample(nibble byte) int16 { diff = -diff } - // adjust predicted sample based on calculated difference, check for overflow - if diff > 0 { - if decPred > math.MaxInt16-diff { - decPred = math.MaxInt16 - } else { - decPred += diff - } - } else { - if decPred < math.MaxInt16-diff { - decPred = math.MaxInt16 - } else { - decPred += diff - } - } + // adjust predicted sample based on calculated difference + decPred = capAdd16(decPred, diff) // adjust index into step size lookup table using nibble decIndex += indexTable[nibble] @@ -173,6 +161,19 @@ func decodeSample(nibble byte) int16 { return decPred } +// capAdd16 adds two int16s together and caps at max/min int16 instead of overflowing +func capAdd16(a, b int16) int16 { + c := int32(a) + int32(b) + switch { + case c < math.MinInt16: + return math.MinInt16 + case c > math.MaxInt16: + return math.MaxInt16 + default: + return int16(c) + } +} + func calcHead(sample []byte) ([]byte, error) { // check that we are given 1 16-bit sample (2 bytes) sampSize := 2