fix: measure FLAC files that have data after the audio
This commit is contained in:
1 parent
2fb58e001e
commit
5fdeda2ede
2 files changed
+42
No files matched your search
@@ -318,8 +318,13 @@ func newFLACDecoder(r io.Reader) (Decoder, error) {
|
||||
info := stream.Info
|
||||
divisor := float64(int64(1) << (info.BitsPerSample - 1))
|
||||
d := &streamDecoder{rate: int(info.SampleRate), ch: int(info.NChannels)}
|
||||
var decoded uint64
|
||||
d.fill = func() error {
|
||||
for {
|
||||
// QQ 音乐的 FLAC 在音频之后还有数据:继续读会被当成音频帧报错,整首的分析结果都会作废。NSamples 为 0 表示文件没有声明总数。
|
||||
if info.NSamples > 0 && decoded >= info.NSamples {
|
||||
return io.EOF
|
||||
}
|
||||
frame, err := stream.ParseNext()
|
||||
if err != nil {
|
||||
return err // 含 io.EOF
|
||||
@@ -328,6 +333,7 @@ func newFLACDecoder(r io.Reader) (Decoder, error) {
|
||||
continue
|
||||
}
|
||||
n := frame.Subframes[0].NSamples
|
||||
decoded += uint64(n)
|
||||
ch := len(frame.Subframes)
|
||||
out := d.q.buf[d.q.grow(n*ch):]
|
||||
for c, sub := range frame.Subframes {
|
||||
|
||||
@@ -271,6 +271,42 @@ func TestDecodeRejectsUndecodableMP3(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeFLACStopsAtDeclaredSamples(t *testing.T) {
|
||||
file, err := os.ReadFile("testdata/sine.flac")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want, err := Decode(bytes.NewReader(file))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
withTrailer := append(slices.Clone(file), 0x00, 0x01, 0x02, 0x03)
|
||||
got, err := Decode(bytes.NewReader(withTrailer))
|
||||
if err != nil {
|
||||
t.Fatalf("音频之后有多余数据:%v", err)
|
||||
}
|
||||
if got.Frames() != want.Frames() {
|
||||
t.Errorf("采样帧 = %d,期望 %d", got.Frames(), want.Frames())
|
||||
}
|
||||
|
||||
// STREAMINFO 的总采样数占第 21 字节的低 4 位和之后的 4 个字节,全 0 表示未知。
|
||||
undeclared := slices.Clone(file)
|
||||
undeclared[21] &= 0xF0
|
||||
clear(undeclared[22:26])
|
||||
got, err = Decode(bytes.NewReader(undeclared))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got.Frames() != want.Frames() {
|
||||
t.Errorf("未声明总采样数时采样帧 = %d,期望读到文件结束的 %d", got.Frames(), want.Frames())
|
||||
}
|
||||
|
||||
if _, err := Decode(bytes.NewReader(file[:len(file)-200])); err == nil {
|
||||
t.Error("音频比声明的少时应该报错")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDamageReportsSkippedMP3Data(t *testing.T) {
|
||||
decode := func(t *testing.T, file []byte) Decoder {
|
||||
t.Helper()
|
||||
|
||||
Reference in new issue
Block a user