11namespace tracktion {
inline namespace engine
16 :
juce::AudioFormatReader (nullptr,
"BufferedAudioReader"),
17 source (
std::
move (sourceReader)), thread (t)
21 sampleRate = source->sampleRate;
22 bitsPerSample = source->bitsPerSample;
23 lengthInSamples = source->lengthInSamples;
24 numChannels = source->numChannels;
25 usesFloatingPointData =
true;
26 metadataValues = source->metadataValues;
28 data.resize (choc::buffer::Size::create (numChannels, lengthInSamples));
34BufferedAudioReader::~BufferedAudioReader()
36 thread.removeTimeSliceClient (
this);
39float BufferedAudioReader::getProportionComplete()
const
41 return source->lengthInSamples == 0 ? 0.0f
45bool BufferedAudioReader::readSamples (
int*
const* destSamples,
int numDestChannels,
int startOffsetInDestBuffer,
48 clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer,
49 startSampleInFile, numSamples, lengthInSamples);
54 using namespace choc::buffer;
55 const auto srcRange = FrameRange {
static_cast<FrameCount
> (startSampleInFile),
56 static_cast<FrameCount
> (startSampleInFile + numSamples) };
57 const auto srcView = data.getFrameRange (srcRange);
59 const auto numChannelsToRead =
std::min (srcView.getNumChannels(),
static_cast<FrameCount
> (numDestChannels));
60 const auto destSize = choc::buffer::Size::create (numChannelsToRead, numSamples);
61 const auto destView = createChannelArrayView (
reinterpret_cast<float* const*
> (destSamples),
62 destSize.getChannelRange().size(),
63 destSize.getFrameRange().size());
71 copyIntersectionAndClearOutside (destView, srcView);
76int BufferedAudioReader::useTimeSlice()
78 return readNextChunk() ? 0 : -1;
81bool BufferedAudioReader::readNextChunk()
86 using namespace choc::buffer;
88 const auto end =
std::min (start + chunkSize, sourceLength);
90 if (readIntoBuffer ({ start,
end }))
94 if (
const bool hasFinished = end == sourceLength; hasFinished)
104bool BufferedAudioReader::readIntoBuffer (choc::buffer::FrameRange range)
109 return source->read (destView.getArrayOfWritePointers(),
static_cast<int> (destView.getNumChannels()),
110 static_cast<juce::int64> (range.start),
static_cast<int> (range.size()));
115BufferedAudioFileManager::BufferedAudioFileManager (
Engine& e)
122 TRACKTION_ASSERT_MESSAGE_THREAD
123 auto& item = cache[f];
127 if (
auto reader = createReader (f))
131 readThread.
startThread (juce::Thread::Priority::normal);
134 timer.startTimer (5'000);
141void BufferedAudioFileManager::cleanUp()
143 TRACKTION_ASSERT_MESSAGE_THREAD
146 return item.second.use_count() == 1;
155 if (
auto mappedFileAndReader = AudioFileUtils::createMappedFileAndReaderFor (engine, f))
void addTimeSliceClient(TimeSliceClient *clientToAdd, int millisecondsBeforeStarting=0)
void stopTimer() noexcept
bool isTimerRunning() const noexcept
juce::AudioBuffer< float > toAudioBuffer(choc::buffer::ChannelArrayView< float > view)
Creates a juce::AudioBuffer from a choc::buffer::BufferView.