private void prefetchAllHeaders( final Info firstInfo, final Comment firstComment, final int dataoffset) { final Page page = new Page(); this.m_info = new Info[this.m_links]; this.m_comments = new Comment[this.m_links]; this.m_dataOffsets = new long[this.m_links]; this.m_pcmLengths = new long[this.m_links]; this.m_serialnos = new int[this.m_links]; for (int i = 0; i < this.m_links; ++i) { if (firstInfo != null && firstComment != null && i == 0) { this.m_info[i] = firstInfo; this.m_comments[i] = firstComment; this.m_dataOffsets[i] = dataoffset; } else { this.seekHelper(this.m_offsets[i]); this.m_info[i] = new Info(); this.m_comments[i] = new Comment(); if (this.fetchHeaders(this.m_info[i], this.m_comments[i], null, null) == -1) { this.m_dataOffsets[i] = -1L; } else { this.m_dataOffsets[i] = this.m_offset; this.m_oggStreamState.clear(); } } final long end = this.m_offsets[i + 1]; this.seekHelper(end); while (true) { final int ret = this.getPreviousPage(page); if (ret == -1) { this.m_info[i].clear(); break; } if (page.granulepos() != -1L) { this.m_serialnos[i] = page.serialno(); this.m_pcmLengths[i] = page.granulepos(); break; } } } }
@Override public int pcmSeek(final long pos) { if (!this.m_vorbisStream.isSeekable()) { return -1; } long total = this.pcmTotal(-1); if (pos < 0L || pos > total) { this.m_pcmOffset = -1L; this.decodeClear(); return -1; } int link; for (link = this.m_links - 1; link >= 0; --link) { total -= this.m_pcmLengths[link]; if (pos >= total) { break; } } final long target = pos - total; long end = this.m_offsets[link + 1]; long begin = this.m_offsets[link]; int best = (int) begin; final Page page = new Page(); while (begin < end) { long bisect; if (end - begin < this.m_chunkSize) { bisect = begin; } else { bisect = (end + begin) / 2L; } this.seekHelper(bisect); final int ret = this.getNextPage(page, end - bisect); if (ret == -1) { end = bisect; } else { final long granulepos = page.granulepos(); if (granulepos < target) { best = ret; begin = this.m_offset; } else { end = bisect; } } } if (this.rawSeek(best) != 0) { this.m_pcmOffset = -1L; this.decodeClear(); return -1; } if (this.m_pcmOffset >= pos) { this.m_pcmOffset = -1L; this.decodeClear(); return -1; } if (pos > this.pcmTotal(-1)) { this.m_pcmOffset = -1L; this.decodeClear(); return -1; } while (this.m_pcmOffset < pos) { final int target2 = (int) (pos - this.m_pcmOffset); final int[] _index = new int[this.m_info[this.m_currentLink].channelsCount]; int samples = this.m_dspState.synthesis_pcmout(this.m_pcmf_buffer, _index); if (samples > target2) { samples = target2; } this.m_dspState.synthesis_read(samples); this.m_pcmOffset += samples; if (samples < target2 && this.processPacket(true) == 0) { this.m_pcmOffset = this.pcmTotal(-1); } } return 0; }