Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Absolute seek #46

Merged
merged 14 commits into from
Jan 27, 2021
Prev Previous commit
Next Next commit
flac: Make searchFromStart return an error instead of panic
karlek committed Jan 26, 2021
commit a3a25a9cea5c206f6d86658cb46a4b21264e00e7
21 changes: 15 additions & 6 deletions flac.go
Original file line number Diff line number Diff line change
@@ -133,9 +133,13 @@ var (
// id3Signature marks the beginning of an ID3 stream, used to skip over ID3 data.
id3Signature = []byte("ID3")

// ErrNoSeeker tells you if the Reader you passed to New/Parse is not
// a `io.ReadSeeker`, and thus does not allow for seeking.
// ErrNoSeeker reports that flac.NewSeek was called with an io.Reader not
// implementing io.Seeker, and thus does not allow for seeking.
ErrNoSeeker = errors.New("stream.Seek: reader does not implement io.Seeker")

// ErrNoSeektable reports that no seektable has been generated. Therefore,
// it is not possible to seek in the stream.
ErrNoSeektable = errors.New("stream.searchFromStart: no seektable exists")
)

const (
@@ -321,7 +325,10 @@ func (stream *Stream) Seek(sampleNum uint64) (uint64, error) {
if isBiggerThanStream || sampleNum < 0 {
return 0, fmt.Errorf("unable to seek to sample number %d", sampleNum)
}
point := stream.searchFromStart(sampleNum)
point, err := stream.searchFromStart(sampleNum)
if err != nil {
return 0, err
}

if _, err := rs.Seek(stream.dataStart+int64(point.Offset), io.SeekStart); err != nil {
return 0, err
@@ -345,14 +352,16 @@ func (stream *Stream) Seek(sampleNum uint64) (uint64, error) {
}

// TODO(_): Utilize binary search.
func (stream *Stream) searchFromStart(sample uint64) meta.SeekPoint {

//
func (stream *Stream) searchFromStart(sample uint64) (meta.SeekPoint, error) {
if len(stream.seekTable.Points) == 0 {
panic("do not reach this lol")
return meta.SeekPoint{}, ErrNoSeektable
}
prev := stream.seekTable.Points[0]
for _, p := range stream.seekTable.Points {
if p.SampleNum+uint64(p.NSamples) >= sample {
return prev
return prev, nil
}
prev = p
}