void MP3StreamState::seekWithinFile(float seekNPT) { if (fFidIsReallyASocket) return; // it's not seekable float fileDuration = filePlayTime(); if (seekNPT < 0.0) { seekNPT = 0.0; } else if (seekNPT > fileDuration) { seekNPT = fileDuration; } float seekFraction = seekNPT/fileDuration; unsigned seekByteNumber; if (fHasXingTOC) { // The file is VBR, with a Xing TOC; use it to determine which byte to seek to: float percent = seekFraction*100.0f; unsigned a = (unsigned)percent; if (a > 99) a = 99; unsigned fa = fXingTOC[a]; unsigned fb; if (a < 99) { fb = fXingTOC[a+1]; } else { fb = 256; } float seekByteFraction = (fa + (fb-fa)*(percent-a))/256.0f; seekByteNumber = (unsigned)(seekByteFraction*fFileSize); } else { // Normal case: Treat the file as if it's CBR: seekByteNumber = (unsigned)(seekFraction*fFileSize); } fseek(fFid, seekByteNumber, SEEK_SET); }
void MP3FileSource::seekWithinFile(double seekNPT, double streamDuration) { float fileDuration = filePlayTime(); // First, make sure that 0.0 <= seekNPT <= seekNPT + streamDuration <= fileDuration if (seekNPT < 0.0) { seekNPT = 0.0; } else if (seekNPT > fileDuration) { seekNPT = fileDuration; } if (streamDuration < 0.0) { streamDuration = 0.0; } else if (seekNPT + streamDuration > fileDuration) { streamDuration = fileDuration - seekNPT; } float seekFraction = (float)seekNPT/fileDuration; unsigned seekByteNumber = fStreamState->getByteNumberFromPositionFraction(seekFraction); fStreamState->seekWithinFile(seekByteNumber); fLimitNumBytesToStream = False; // by default if (streamDuration > 0.0) { float endFraction = (float)(seekNPT + streamDuration)/fileDuration; unsigned endByteNumber = fStreamState->getByteNumberFromPositionFraction(endFraction); if (endByteNumber > seekByteNumber) { // sanity check fNumBytesToStream = endByteNumber - seekByteNumber; fLimitNumBytesToStream = True; } } }