//============================================================================== bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int numSamples) override { clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, startSampleInFile, numSamples, lengthInSamples); if (numSamples <= 0) return true; if (lastReadPosition != startSampleInFile) { OSStatus status = ExtAudioFileSeek (audioFileRef, startSampleInFile); if (status != noErr) return false; lastReadPosition = startSampleInFile; } while (numSamples > 0) { const int numThisTime = jmin (8192, numSamples); const size_t numBytes = sizeof (float) * (size_t) numThisTime; audioDataBlock.ensureSize (numBytes * numChannels, false); float* data = static_cast<float*> (audioDataBlock.getData()); for (int j = (int) numChannels; --j >= 0;) { bufferList->mBuffers[j].mNumberChannels = 1; bufferList->mBuffers[j].mDataByteSize = (UInt32) numBytes; bufferList->mBuffers[j].mData = data; data += numThisTime; } UInt32 numFramesToRead = (UInt32) numThisTime; OSStatus status = ExtAudioFileRead (audioFileRef, &numFramesToRead, bufferList); if (status != noErr) return false; for (int i = numDestChannels; --i >= 0;) { if (destSamples[i] != nullptr) { if (i < (int) numChannels) memcpy (destSamples[i] + startOffsetInDestBuffer, bufferList->mBuffers[i].mData, numBytes); else zeromem (destSamples[i] + startOffsetInDestBuffer, numBytes); } } startOffsetInDestBuffer += numThisTime; numSamples -= numThisTime; lastReadPosition += numThisTime; } return true; }
//============================================================================== bool AudioSubsectionReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int numSamples) { clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, startSampleInFile, numSamples, length); return source->readSamples (destSamples, numDestChannels, startOffsetInDestBuffer, startSampleInFile + startSample, numSamples); }
bool BufferingAudioReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, int64 startSampleInFile, int numSamples) { const uint32 startTime = Time::getMillisecondCounter(); clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, startSampleInFile, numSamples, lengthInSamples); const ScopedLock sl (lock); nextReadPosition = startSampleInFile; while (numSamples > 0) { if (const BufferedBlock* const block = getBlockContaining (startSampleInFile)) { const int offset = (int) (startSampleInFile - block->range.getStart()); const int numToDo = jmin (numSamples, (int) (block->range.getEnd() - startSampleInFile)); for (int j = 0; j < numDestChannels; ++j) { if (float* dest = (float*) destSamples[j]) { dest += startOffsetInDestBuffer; if (j < (int) numChannels) FloatVectorOperations::copy (dest, block->buffer.getReadPointer (j, offset), numToDo); else FloatVectorOperations::clear (dest, numToDo); } } startOffsetInDestBuffer += numToDo; startSampleInFile += numToDo; numSamples -= numToDo; } else { if (timeoutMs >= 0 && Time::getMillisecondCounter() >= startTime + (uint32) timeoutMs) { for (int j = 0; j < numDestChannels; ++j) if (float* dest = (float*) destSamples[j]) FloatVectorOperations::clear (dest + startOffsetInDestBuffer, numSamples); break; } else { ScopedUnlock ul (lock); Thread::yield(); } } } return true; }