Skip to content

Commit

Permalink
frame: fix inter-channel decorrelation of MidSide channels
Browse files Browse the repository at this point in the history
Trouble-shooting this issue was hugely facilitated by @wader and fq.

Updates #67.
  • Loading branch information
mewmew committed Oct 31, 2023
1 parent 212a4f1 commit 8b7bbe0
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 102 deletions.
147 changes: 49 additions & 98 deletions enc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,98 +23,64 @@ func TestEncode(t *testing.T) {
// flac test cases.
"testdata/19875.flac", // prediction method 3 (FIR)
"testdata/44127.flac", // prediction method 3 (FIR)
// TODO: fix diff.
//"testdata/59996.flac",
"testdata/59996.flac",
"testdata/80574.flac", // prediction method 3 (FIR)
// TODO: fix diff.
//"testdata/172960.flac",
// TODO: fix diff.
//"testdata/189983.flac",
"testdata/172960.flac",
"testdata/189983.flac",
// TODO: fix: invalid number of samples per channel; expected >= 16 && <= 65535, got 1
//"testdata/191885.flac",
// TODO: fix diff.
//"testdata/212768.flac",
"testdata/212768.flac",
"testdata/220014.flac", // prediction method 2 (Fixed)
"testdata/243749.flac", // prediction method 2 (Fixed)
// TODO: fix diff.
//"testdata/256529.flac",
"testdata/256529.flac",
"testdata/257344.flac", // prediction method 3 (FIR)
"testdata/8297-275156-0011.flac", // prediction method 3 (FIR)
"testdata/love.flac", // wasted bits
// IETF test cases.
// TODO: fix diff.
//"testdata/flac-test-files/subset/01 - blocksize 4096.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/02 - blocksize 4608.flac",
"testdata/flac-test-files/subset/01 - blocksize 4096.flac",
"testdata/flac-test-files/subset/02 - blocksize 4608.flac",
// TODO: fix: invalid number of samples per channel; expected >= 16 && <= 65535, got 12
//"testdata/flac-test-files/subset/03 - blocksize 16.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/04 - blocksize 192.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/05 - blocksize 254.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/06 - blocksize 512.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/07 - blocksize 725.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/08 - blocksize 1000.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/09 - blocksize 1937.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/10 - blocksize 2304.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/11 - partition order 8.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/12 - qlp precision 15 bit.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/13 - qlp precision 2 bit.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/14 - wasted bits.flac",
"testdata/flac-test-files/subset/04 - blocksize 192.flac",
"testdata/flac-test-files/subset/05 - blocksize 254.flac",
"testdata/flac-test-files/subset/06 - blocksize 512.flac",
"testdata/flac-test-files/subset/07 - blocksize 725.flac",
"testdata/flac-test-files/subset/08 - blocksize 1000.flac",
"testdata/flac-test-files/subset/09 - blocksize 1937.flac",
"testdata/flac-test-files/subset/10 - blocksize 2304.flac",
"testdata/flac-test-files/subset/11 - partition order 8.flac",
"testdata/flac-test-files/subset/12 - qlp precision 15 bit.flac",
"testdata/flac-test-files/subset/13 - qlp precision 2 bit.flac",
"testdata/flac-test-files/subset/14 - wasted bits.flac",
"testdata/flac-test-files/subset/15 - only verbatim subframes.flac",
// TODO: implement encoding of escaped partitions
//"testdata/flac-test-files/subset/16 - partition order 8 containing escaped partitions.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/17 - all fixed orders.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/18 - precision search.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/19 - samplerate 35467Hz.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/20 - samplerate 39kHz.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/21 - samplerate 22050Hz.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/22 - 12 bit per sample.flac",
"testdata/flac-test-files/subset/17 - all fixed orders.flac",
"testdata/flac-test-files/subset/18 - precision search.flac",
"testdata/flac-test-files/subset/19 - samplerate 35467Hz.flac",
"testdata/flac-test-files/subset/20 - samplerate 39kHz.flac",
"testdata/flac-test-files/subset/21 - samplerate 22050Hz.flac",
"testdata/flac-test-files/subset/22 - 12 bit per sample.flac",
// TODO: fix: invalid number of samples per channel; expected >= 16 && <= 65535, got 5
//"testdata/flac-test-files/subset/23 - 8 bit per sample.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/24 - variable blocksize file created with flake revision 264.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/25 - variable blocksize file created with flake revision 264, modified to create smaller blocks.flac",
"testdata/flac-test-files/subset/24 - variable blocksize file created with flake revision 264.flac",
"testdata/flac-test-files/subset/25 - variable blocksize file created with flake revision 264, modified to create smaller blocks.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/26 - variable blocksize file created with CUETools.Flake 2.1.6.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/27 - old format variable blocksize file created with Flake 0.11.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/28 - high resolution audio, default settings.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/29 - high resolution audio, blocksize 16384.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/30 - high resolution audio, blocksize 13456.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/31 - high resolution audio, using only 32nd order predictors.flac",
"testdata/flac-test-files/subset/28 - high resolution audio, default settings.flac",
"testdata/flac-test-files/subset/29 - high resolution audio, blocksize 16384.flac",
"testdata/flac-test-files/subset/30 - high resolution audio, blocksize 13456.flac",
"testdata/flac-test-files/subset/31 - high resolution audio, using only 32nd order predictors.flac",
// TODO: implement encoding of escaped partitions.
//"testdata/flac-test-files/subset/32 - high resolution audio, partition order 8 containing escaped partitions.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/33 - samplerate 192kHz.flac",
"testdata/flac-test-files/subset/33 - samplerate 192kHz.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/34 - samplerate 192kHz, using only 32nd order predictors.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/35 - samplerate 134560Hz.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/36 - samplerate 384kHz.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/37 - 20 bit per sample.flac",
"testdata/flac-test-files/subset/35 - samplerate 134560Hz.flac",
"testdata/flac-test-files/subset/36 - samplerate 384kHz.flac",
"testdata/flac-test-files/subset/37 - 20 bit per sample.flac",
"testdata/flac-test-files/subset/38 - 3 channels (3.0).flac",
"testdata/flac-test-files/subset/39 - 4 channels (4.0).flac",
"testdata/flac-test-files/subset/40 - 5 channels (5.0).flac",
Expand All @@ -123,36 +89,21 @@ func TestEncode(t *testing.T) {
"testdata/flac-test-files/subset/43 - 8 channels (7.1).flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/44 - 8-channel surround, 192kHz, 24 bit, using only 32nd order predictors.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/45 - no total number of samples set.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/46 - no min-max framesize set.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/47 - only STREAMINFO.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/48 - Extremely large SEEKTABLE.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/49 - Extremely large PADDING.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/50 - Extremely large PICTURE.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/51 - Extremely large VORBISCOMMENT.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/52 - Extremely large APPLICATION.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/53 - CUESHEET with very many indexes.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/54 - 1000x repeating VORBISCOMMENT.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/55 - file 48-53 combined.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/56 - JPG PICTURE.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/57 - PNG PICTURE.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/58 - GIF PICTURE.flac",
// TODO: fix diff.
//"testdata/flac-test-files/subset/59 - AVIF PICTURE.flac",
"testdata/flac-test-files/subset/45 - no total number of samples set.flac",
"testdata/flac-test-files/subset/46 - no min-max framesize set.flac",
"testdata/flac-test-files/subset/47 - only STREAMINFO.flac",
"testdata/flac-test-files/subset/48 - Extremely large SEEKTABLE.flac",
"testdata/flac-test-files/subset/49 - Extremely large PADDING.flac",
"testdata/flac-test-files/subset/50 - Extremely large PICTURE.flac",
"testdata/flac-test-files/subset/51 - Extremely large VORBISCOMMENT.flac",
"testdata/flac-test-files/subset/52 - Extremely large APPLICATION.flac",
"testdata/flac-test-files/subset/53 - CUESHEET with very many indexes.flac",
"testdata/flac-test-files/subset/54 - 1000x repeating VORBISCOMMENT.flac",
"testdata/flac-test-files/subset/55 - file 48-53 combined.flac",
"testdata/flac-test-files/subset/56 - JPG PICTURE.flac",
"testdata/flac-test-files/subset/57 - PNG PICTURE.flac",
"testdata/flac-test-files/subset/58 - GIF PICTURE.flac",
"testdata/flac-test-files/subset/59 - AVIF PICTURE.flac",
"testdata/flac-test-files/subset/60 - mono audio.flac",
"testdata/flac-test-files/subset/61 - predictor overflow check, 16-bit.flac",
"testdata/flac-test-files/subset/62 - predictor overflow check, 20-bit.flac",
Expand Down
7 changes: 3 additions & 4 deletions frame/frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import (
"hash"
"io"
"log"
"math"

"github.com/mewkiz/flac/internal/bits"
"github.com/mewkiz/flac/internal/hashutil"
Expand Down Expand Up @@ -593,9 +592,9 @@ func (frame *Frame) Correlate() {
// 2 channels: side, right; using inter-channel decorrelation.
side := frame.Subframes[0].Samples
right := frame.Subframes[1].Samples
// left = right + side
for i := range side {
side[i] += right[i]
// left = right + side
side[i] = right[i] + side[i]
}
case ChannelsMidSide:
// 2 channels: mid, side; using inter-channel decorrelation.
Expand Down Expand Up @@ -662,7 +661,7 @@ func (frame *Frame) Decorrelate() {
// side = left - right
l := left[i]
r := right[i]
mid := int32(math.Round((float64(l) + float64(r)) / 2.0)) // rounded up.
mid := int32((int64(l) + int64(r)) >> 1) // NOTE: using `(left + right) >> 1`, not the same as `(left + right) / 2`.
side := l - r
left[i] = mid
right[i] = side
Expand Down

0 comments on commit 8b7bbe0

Please sign in to comment.