audio/loop.go
func (i *InfiniteLoop) Read(b []byte) (int, error) {
	if err := i.ensurePos(); err != nil {
		return 0, err
	}

	if i.pos+int64(len(b)) > i.length() {
		b = b[:i.length()-i.pos]
	}

	n, err := i.src.Read(b)
	i.pos += int64(n)
	if i.pos > i.length() {
		panic(fmt.Sprintf("audio: position must be <= length but not at (*InfiniteLoop).Read: pos: %d, length: %d", i.pos, i.length()))
	}

	if err != nil && err != io.EOF {
		return 0, err
	}

	if err == io.EOF || i.pos == i.length() {
		pos, err := i.Seek(i.lstart, io.SeekStart)
		if err != nil {
			return 0, err
		}
		i.pos = pos
	}
	return n, nil
}
func (i *InfiniteLoop) Read(b []byte) (int, error) {
	if err := i.ensurePos(); err != nil {
		return 0, err
	}

	if i.pos+int64(len(b)) > i.length() {
		b = b[:i.length()-i.pos]
	}

	n, err := i.src.Read(b)
	i.pos += int64(n)
	if i.pos > i.length() {
		panic(fmt.Sprintf("audio: position must be <= length but not at (*InfiniteLoop).Read: pos: %d, length: %d", i.pos, i.length()))
	}

	if err != nil && err != io.EOF {
		return 0, err
	}

	if err == io.EOF || i.pos == i.length() {
		pos, err := i.Seek(i.lstart, io.SeekStart)
		if err != nil {
			return 0, err
		}
		i.pos = pos
	}
	return n, nil
}
// Read is implementation of ReadSeekCloser's Read.