public long SeekTo(
            long granulePos, int preRoll, GetPacketGranuleCountDelegate getPacketGranuleCount)
        {
            if (_reader == null)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }

            int pageIndex = _reader.FindPage(granulePos);

            int packetIndex;

            if (granulePos == 0)
            {
                // for this, we can generically say the first packet on the first page having a non-zero granule
                packetIndex = 0;
            }
            else
            {
                packetIndex  = FindPacket(pageIndex, ref granulePos, getPacketGranuleCount);
                packetIndex -= preRoll;
            }

            if (!NormalizePacketIndex(ref pageIndex, ref packetIndex))
            {
                throw new ArgumentOutOfRangeException(nameof(granulePos));
            }

            _lastPacket  = null;
            _pageIndex   = pageIndex;
            _packetIndex = packetIndex;
            return(granulePos);
        }
        private int FindPacket(
            int pageIndex, ref long granulePos, GetPacketGranuleCountDelegate getPacketGranuleCount)
        {
            // we will only look through the current page...
            // if the granule isn't on the page, behavior is:
            //   - if before: return 0
            //   - if after: return packetCount - (isContinued ? 2 : 1)
            // neither should happen because we're already looking at the correct page

            if (!_reader.GetPage(
                    pageIndex, out long pageGranulePos, out bool isResync, out _, out bool isContinued,
                    out int packetCount, out int pageOverhead))
            {
                return(-1);
            }

            var gp          = pageGranulePos;
            var packetIndex = packetCount - (isContinued ? 2 : 1);

            while (packetIndex > 0)
            {
                if (gp >= granulePos)
                {
                    var packet = CreatePacket(
                        ref pageIndex, ref packetIndex, false, pageGranulePos, isResync, isContinued,
                        packetCount, pageOverhead);

                    if (packet == null)
                    {
                        break;
                    }

                    gp -= getPacketGranuleCount(packet, false);
                }

                if (gp < granulePos)
                {
                    granulePos = gp;
                    return(packetIndex);
                }

                --packetIndex;
            }
            if (packetIndex == 0)
            {
                // we're likely in the right spot for the granulePos...
                if (pageIndex > 0 &&
                    _reader.GetPage(pageIndex - 1, out var prevGranulePos, out _, out _, out _, out _, out _))
                {
                    granulePos = prevGranulePos;
                    return(0);
                }
            }
            return(-1);
        }