From b18e5f0993c5b83a1fbbb2e24d4135398990abef Mon Sep 17 00:00:00 2001 From: Peter Csiba Date: Fri, 17 Nov 2023 08:28:10 -0800 Subject: [PATCH 1/3] [test] Add 24khz sample to testing, remove the log line nudging users --- .gitignore | 1 + enc_test.go | 1 + flac_test.go | 1 + frame/frame.go | 2 -- frame/frame_test.go | 1 + meta/meta_test.go | 10 ++++++++++ testdata/README.md | 5 +++++ 7 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 939f6a5..47a4816 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.idea *.flac *.wav _resources_ diff --git a/enc_test.go b/enc_test.go index de1acb6..4051036 100644 --- a/enc_test.go +++ b/enc_test.go @@ -34,6 +34,7 @@ func TestEncode(t *testing.T) { "testdata/256529.flac", "testdata/257344.flac", // prediction method 3 (FIR) "testdata/8297-275156-0011.flac", // prediction method 3 (FIR) + "testdata/24000-tts-sf.flac", // 24khz test "testdata/love.flac", // wasted bits // IETF test cases. "testdata/flac-test-files/subset/01 - blocksize 4096.flac", diff --git a/flac_test.go b/flac_test.go index 231f648..0e1ce8a 100644 --- a/flac_test.go +++ b/flac_test.go @@ -97,6 +97,7 @@ func TestDecode(t *testing.T) { "testdata/256529.flac", "testdata/257344.flac", "testdata/8297-275156-0011.flac", + "testdata/24000-tts-sf.flac", "testdata/love.flac", // IETF test cases. // diff --git a/frame/frame.go b/frame/frame.go index 877569a..223d765 100644 --- a/frame/frame.go +++ b/frame/frame.go @@ -475,8 +475,6 @@ func (frame *Frame) parseSampleRate(br *bits.Reader, sampleRate uint64) error { case 0x7: // 0111: 24 kHz. frame.SampleRate = 24000 - // TODO(u): Remove log message when the test cases have been extended. - log.Printf("frame.Frame.parseHeader: The flac library test cases do not yet include any audio files with sample rate %d. If possible please consider contributing this audio sample to improve the reliability of the test cases.", frame.SampleRate) case 0x8: // 1000: 32 kHz. frame.SampleRate = 32000 diff --git a/frame/frame_test.go b/frame/frame_test.go index 405cd5c..0ef0c8c 100644 --- a/frame/frame_test.go +++ b/frame/frame_test.go @@ -25,6 +25,7 @@ var golden = []struct { {path: "../testdata/243749.flac"}, {path: "../testdata/256529.flac"}, {path: "../testdata/257344.flac"}, + {path: "../testdata/24000-tts-sf.flac"}, // IETF test cases. {path: "../testdata/flac-test-files/subset/01 - blocksize 4096.flac"}, diff --git a/meta/meta_test.go b/meta/meta_test.go index 268e63a..f1d665c 100644 --- a/meta/meta_test.go +++ b/meta/meta_test.go @@ -193,6 +193,16 @@ var golden = []struct { }, }, }, + { + path: "../testdata/24000-tts-sf.flac", + info: &meta.StreamInfo{BlockSizeMin: 0x1200, BlockSizeMax: 0x1200, FrameSizeMin: 0x94d, FrameSizeMax: 0x264a, SampleRate: 0xac44, NChannels: 0x2, BitsPerSample: 0x10, NSamples: 0x50f4, MD5sum: [16]uint8{0x63, 0x28, 0xed, 0x6d, 0xd3, 0xe, 0x55, 0xfb, 0xa5, 0x73, 0x69, 0x2b, 0xb7, 0x35, 0x73, 0xb7}}, + blocks: []*meta.Block{ + { + Header: meta.Header{Type: 0x4, Length: 40, IsLast: true}, + Body: &meta.VorbisComment{Vendor: "reference libFLAC 1.2.1 20070917", Tags: nil}, + }, + }, + }, } func TestParseBlocks(t *testing.T) { diff --git a/testdata/README.md b/testdata/README.md index ac6d321..ca717db 100644 --- a/testdata/README.md +++ b/testdata/README.md @@ -20,3 +20,8 @@ The following testcase sounds have been released into the [public domain]. The following flac files are CC BY 4.0: * [8297-275156-0011.flac](http://www.openslr.org/12/) - a single file from the LibriSpeech ASR corpus, by Vassil Panyotov and DanielPovey. + + +The following flac files are TODO: + +* [24000-tts-sf.flac](https://platform.openai.com/docs/guides/text-to-speech/do-i-own-the-outputted-audio-files) \ No newline at end of file From 157d4035b0c041a31b7915ab6f90a20f1227791f Mon Sep 17 00:00:00 2001 From: Petrzlen Date: Fri, 17 Nov 2023 08:49:14 -0800 Subject: [PATCH 2/3] fix some tests --- frame/frame_test.go | 3 +++ meta/meta_test.go | 12 +++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/frame/frame_test.go b/frame/frame_test.go index 0ef0c8c..744ea5a 100644 --- a/frame/frame_test.go +++ b/frame/frame_test.go @@ -120,6 +120,9 @@ func TestFrameHash(t *testing.T) { got := md5sum.Sum(nil) // Verify the decoded audio samples by comparing the MD5 checksum that is // stored in StreamInfo with the computed one. + // TODO WELP, seems OpenAI is moving so fast they don't even have time to compute checksums :/ + // frame_test.go:124: path="../testdata/24000-tts-sf.flac": MD5 checksum mismatch for decoded audio samples; + // expected 00000000000000000000000000000000, got f5e621f2580ee8ace6158966793abdbf if !bytes.Equal(got, want) { t.Errorf("path=%q: MD5 checksum mismatch for decoded audio samples; expected %32x, got %32x", g.path, want, got) } diff --git a/meta/meta_test.go b/meta/meta_test.go index f1d665c..b8b66d0 100644 --- a/meta/meta_test.go +++ b/meta/meta_test.go @@ -193,13 +193,19 @@ var golden = []struct { }, }, }, + // TODO reviewer: These values look weird, Apple Music cannot play it, but ffmpeg converts it just fine + // ffmpeg -i testdata/24000-tts-sf.flac -acodec pcm_s16le converted.wav { path: "../testdata/24000-tts-sf.flac", - info: &meta.StreamInfo{BlockSizeMin: 0x1200, BlockSizeMax: 0x1200, FrameSizeMin: 0x94d, FrameSizeMax: 0x264a, SampleRate: 0xac44, NChannels: 0x2, BitsPerSample: 0x10, NSamples: 0x50f4, MD5sum: [16]uint8{0x63, 0x28, 0xed, 0x6d, 0xd3, 0xe, 0x55, 0xfb, 0xa5, 0x73, 0x69, 0x2b, 0xb7, 0x35, 0x73, 0xb7}}, + info: &meta.StreamInfo{BlockSizeMin: 0x1000, BlockSizeMax: 0x1000, FrameSizeMin: 0x0, FrameSizeMax: 0x0, SampleRate: 0x5dc0, NChannels: 0x1, BitsPerSample: 0x10, NSamples: 0x0, MD5sum: [16]uint8{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, blocks: []*meta.Block{ { - Header: meta.Header{Type: 0x4, Length: 40, IsLast: true}, - Body: &meta.VorbisComment{Vendor: "reference libFLAC 1.2.1 20070917", Tags: nil}, + Header: meta.Header{Type: 0x4, Length: 40, IsLast: false}, + Body: &meta.VorbisComment{Vendor: "reference libFLAC 1.3.3 20190804", Tags: [][2]string(nil)}, + }, + { + Header: meta.Header{Type: 0x1, Length: 8192, IsLast: true}, + Body: nil, }, }, }, From e49c0d0becf2d9bdc60699080912a8a641e86e28 Mon Sep 17 00:00:00 2001 From: Petrzlen Date: Fri, 17 Nov 2023 12:39:43 -0800 Subject: [PATCH 3/3] add 24000-tts-sf.flac to testdata --- testdata/24000-tts-sf.flac | Bin 0 -> 29612 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 testdata/24000-tts-sf.flac diff --git a/testdata/24000-tts-sf.flac b/testdata/24000-tts-sf.flac new file mode 100644 index 0000000000000000000000000000000000000000..bc58e66622d1b4fc939c38665b3264e24a89381e GIT binary patch literal 29612 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 JgsNpg|NZQkoVfr1 literal 0 HcmV?d00001