void SourceFile::seek( size_t readPositionFrames ) { if( readPositionFrames >= mNumFrames ) return; // adjust read pos for samplerate conversion so that it is relative to file num frames size_t fileReadPos = readPositionFrames; if( getSampleRate() != getSampleRateNative() ) fileReadPos *= size_t( (float)mFileNumFrames / (float)mNumFrames ); performSeek( fileReadPos ); mReadPos = readPositionFrames; }
void SourceFile::setupSampleRateConversion() { size_t nativeSampleRate = getSampleRateNative(); size_t outputSampleRate = getSampleRate(); if( ! outputSampleRate ) { outputSampleRate = nativeSampleRate; setSampleRate( nativeSampleRate ); } else if( outputSampleRate != nativeSampleRate ) { mNumFrames = (size_t)std::ceil( (float)mFileNumFrames * (float)outputSampleRate / (float)nativeSampleRate ); if( ! supportsConversion() ) { size_t numChannels = getNumChannels(); mConverter = audio::dsp::Converter::create( nativeSampleRate, outputSampleRate, numChannels, numChannels, getMaxFramesPerRead() ); mConverterReadBuffer.setSize( getMaxFramesPerRead(), numChannels ); } } else { mNumFrames = mFileNumFrames; mConverter.reset(); } }
size_t SourceFile::read( Buffer *buffer ) { CI_ASSERT( buffer->getNumChannels() == getNumChannels() ); CI_ASSERT( mReadPos < mNumFrames ); size_t numRead; if( mConverter ) { size_t sourceBufFrames = size_t( buffer->getNumFrames() * (float)getSampleRateNative() / (float)getSampleRate() ); size_t numFramesNeeded = std::min( mFileNumFrames - mReadPos, std::min( getMaxFramesPerRead(), sourceBufFrames ) ); mConverterReadBuffer.setNumFrames( numFramesNeeded ); performRead( &mConverterReadBuffer, 0, numFramesNeeded ); pair<size_t, size_t> count = mConverter->convert( &mConverterReadBuffer, buffer ); numRead = count.second; } else { size_t numFramesNeeded = std::min( mNumFrames - mReadPos, std::min( getMaxFramesPerRead(), buffer->getNumFrames() ) ); numRead = performRead( buffer, 0, numFramesNeeded ); } mReadPos += numRead; return numRead; }