audio/internal/convert: Seek with incomplete bytes should work

Usually users use audio.Player objects and doesn't use Resampling
object directly. Resampling object itself is exposed by
audio.Resample, but this is usually used with audio.Player objects.
Thus, this issue is not so serious in the real world.
This commit is contained in:
Hajime Hoshi 2024-07-14 18:33:13 +09:00
parent fc70392093
commit 1d75c9e967
2 changed files with 27 additions and 3 deletions

View File

@ -298,5 +298,7 @@ func (r *Resampling) Seek(offset int64, whence int) (int64, error) {
if r.Length() <= r.pos {
r.pos = r.Length()
}
size := r.bytesPerSample()
r.pos = r.pos / int64(size) * int64(size)
return r.pos, nil
}

View File

@ -89,10 +89,32 @@ func TestResampling(t *testing.T) {
t.Run(fmt.Sprintf("bitDepthInBytes=%d", bitDepthInBytes), func(t *testing.T) {
inB := newSoundBytes(c.In, bitDepthInBytes)
outS := convert.NewResampling(bytes.NewReader(inB), int64(len(inB)), c.In, c.Out, bitDepthInBytes)
gotB, err := io.ReadAll(outS)
var gotB []byte
for {
var buf [97]byte
n, err := outS.Read(buf[:])
gotB = append(gotB, buf[:n]...)
if err != nil {
if err != io.EOF {
t.Fatal(err)
}
break
}
cur, err := outS.Seek(0, io.SeekCurrent)
if err != nil {
t.Fatal(err)
}
// Shifting by incomplete bytes should not affect the result.
for i := 0; i < bitDepthInBytes*2-1; i++ {
pos, err := outS.Seek(int64(i), io.SeekCurrent)
if err != nil {
t.Fatal(err)
}
if cur != pos {
t.Errorf("cur: %d, pos: %d", cur, pos)
}
}
}
wantB := newSoundBytes(c.Out, bitDepthInBytes)
if len(gotB) != len(wantB) {
t.Errorf("len(gotB) == %d but len(wantB) == %d", len(gotB), len(wantB))