SInt64 SFB::Audio::DSFDecoder::_SeekToFrame(SInt64 frame) { // Round down to nearest multiple of 8 frames frame = (frame / 8) * 8; // Seek to the start of the block containing frame auto blockSizePerChannelInFrames = mFormat.ByteCountToFrameCount(mBlockByteSizePerChannel); auto blockNumber = (size_t)frame / blockSizePerChannelInFrames; auto blockOffset = blockNumber * mBlockByteSizePerChannel * mFormat.mChannelsPerFrame; if(!GetInputSource().SeekToOffset(mAudioOffset + (SInt64)blockOffset)) { LOGGER_WARNING("org.sbooth.AudioEngine.Decoder.DSF", "_SeekToFrame() failed for offset: " << mAudioOffset + (SInt64)blockOffset); return -1; } if(!ReadAndDeinterleaveDSDBlock()) return -1; // Skip to the specified frame UInt32 framesToSkip = (UInt32)frame % blockSizePerChannelInFrames; UInt32 framesInBuffer = (UInt32)mFormat.ByteCountToFrameCount(mBufferList->mBuffers[0].mDataByteSize); // Copy data from the buffer to output for(UInt32 i = 0; i < mBufferList->mNumberBuffers; ++i) { uint8_t *dst = (uint8_t *)mBufferList->mBuffers[i].mData; memmove(dst, dst + mFormat.FrameCountToByteCount(framesToSkip), mFormat.FrameCountToByteCount(framesInBuffer - framesToSkip)); mBufferList->mBuffers[i].mDataByteSize -= (UInt32)mFormat.FrameCountToByteCount(framesToSkip); } mCurrentFrame = frame; return _GetCurrentFrame(); }
SInt64 SFB::Audio::Decoder::GetCurrentFrame() const { if(!IsOpen()) { LOGGER_INFO("org.sbooth.AudioEngine.Decoder", "GetCurrentFrame() called on a Decoder that hasn't been opened"); return -1; } return _GetCurrentFrame(); }
SInt64 SFB::Audio::LoopableRegionDecoder::_SeekToFrame(SInt64 frame) { mCompletedPasses = (UInt32)(frame / mFrameCount); mFramesReadInCurrentPass = (UInt32)(frame % mFrameCount); mTotalFramesRead = frame; mDecoder->SeekToFrame(mStartingFrame + mFramesReadInCurrentPass); return _GetCurrentFrame(); }
SInt64 SFB::Audio::CoreAudioDecoder::_SeekToFrame(SInt64 frame) { OSStatus result = ExtAudioFileSeek(mExtAudioFile, frame); if(noErr != result) { LOGGER_ERR("org.sbooth.AudioEngine.Decoder.CoreAudio", "ExtAudioFileSeek failed: " << result); return -1; } if(mUseM4AWorkarounds) mCurrentFrame = frame; return _GetCurrentFrame(); }