Browse Source

audiofile: better use of local vs internal pool

tags/v2.3.0-RC1
falkTX 4 years ago
parent
commit
e5ff619c8b
2 changed files with 193 additions and 110 deletions
  1. +176
    -100
      source/native-plugins/audio-base.hpp
  2. +17
    -10
      source/native-plugins/audio-file.cpp

+ 176
- 100
source/native-plugins/audio-base.hpp View File

@@ -1,6 +1,6 @@
/* /*
* Carla Native Plugins * Carla Native Plugins
* Copyright (C) 2013-2019 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2013-2021 Filipe Coelho <falktx@falktx.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
@@ -47,12 +47,15 @@ extern "C" {
# define CARLA_MLOCK(ptr, size) mlock((ptr), (size)) # define CARLA_MLOCK(ptr, size) mlock((ptr), (size))
#endif #endif


// #define DEBUG_FILE_OPS

typedef struct adinfo ADInfo; typedef struct adinfo ADInfo;


struct AudioFilePool { struct AudioFilePool {
float* buffer[2]; float* buffer[2];
float* tmpbuf[2]; float* tmpbuf[2];
uint32_t numFrames; uint32_t numFrames;
uint32_t maxFrame;
volatile uint64_t startFrame; volatile uint64_t startFrame;
water::SpinLock mutex; water::SpinLock mutex;


@@ -61,6 +64,7 @@ struct AudioFilePool {
: buffer{nullptr}, : buffer{nullptr},
tmpbuf{nullptr}, tmpbuf{nullptr},
numFrames(0), numFrames(0),
maxFrame(0),
startFrame(0), startFrame(0),
mutex() {} mutex() {}
#else #else
@@ -79,7 +83,7 @@ struct AudioFilePool {
destroy(); destroy();
} }


void create(const uint32_t desiredNumFrames, const bool withTempBuffers)
void create(const uint32_t desiredNumFrames, const uint32_t fileNumFrames, const bool withTempBuffers)
{ {
CARLA_ASSERT(buffer[0] == nullptr); CARLA_ASSERT(buffer[0] == nullptr);
CARLA_ASSERT(buffer[1] == nullptr); CARLA_ASSERT(buffer[1] == nullptr);
@@ -87,9 +91,12 @@ struct AudioFilePool {
CARLA_ASSERT(tmpbuf[1] == nullptr); CARLA_ASSERT(tmpbuf[1] == nullptr);
CARLA_ASSERT(startFrame == 0); CARLA_ASSERT(startFrame == 0);
CARLA_ASSERT(numFrames == 0); CARLA_ASSERT(numFrames == 0);
CARLA_ASSERT(maxFrame == 0);


buffer[0] = new float[desiredNumFrames]; buffer[0] = new float[desiredNumFrames];
buffer[1] = new float[desiredNumFrames]; buffer[1] = new float[desiredNumFrames];
carla_zeroFloats(buffer[0], desiredNumFrames);
carla_zeroFloats(buffer[1], desiredNumFrames);
CARLA_MLOCK(buffer[0], sizeof(float)*desiredNumFrames); CARLA_MLOCK(buffer[0], sizeof(float)*desiredNumFrames);
CARLA_MLOCK(buffer[1], sizeof(float)*desiredNumFrames); CARLA_MLOCK(buffer[1], sizeof(float)*desiredNumFrames);


@@ -97,11 +104,17 @@ struct AudioFilePool {
{ {
tmpbuf[0] = new float[desiredNumFrames]; tmpbuf[0] = new float[desiredNumFrames];
tmpbuf[1] = new float[desiredNumFrames]; tmpbuf[1] = new float[desiredNumFrames];
carla_zeroFloats(tmpbuf[0], desiredNumFrames);
carla_zeroFloats(tmpbuf[1], desiredNumFrames);
CARLA_MLOCK(tmpbuf[0], sizeof(float)*desiredNumFrames); CARLA_MLOCK(tmpbuf[0], sizeof(float)*desiredNumFrames);
CARLA_MLOCK(tmpbuf[1], sizeof(float)*desiredNumFrames); CARLA_MLOCK(tmpbuf[1], sizeof(float)*desiredNumFrames);
} }


reset(desiredNumFrames);
const water::GenericScopedLock<water::SpinLock> gsl(mutex);

startFrame = 0;
numFrames = desiredNumFrames;
maxFrame = fileNumFrames;
} }


void destroy() noexcept void destroy() noexcept
@@ -137,25 +150,73 @@ struct AudioFilePool {
} }
} }


void reset(const uint32_t desiredNumFrames) noexcept
// NOTE it is assumed that mutex is locked
bool tryPutData(float* const out1,
float* const out2,
uint64_t framePos,
const uint32_t frames,
const bool loopingMode,
const bool isOffline,
bool& needsRead,
uint32_t& needsReadFrame)
{ {
if (desiredNumFrames != 0)
CARLA_SAFE_ASSERT_RETURN(numFrames != 0, false);
CARLA_SAFE_ASSERT_RETURN(maxFrame != 0, false);

if (framePos >= maxFrame)
{
if (loopingMode)
framePos %= maxFrame;
else
return false;
}

uint64_t frameDiff;
const uint32_t numFramesNearEnd = numFrames*3/5;

if (framePos < startFrame)
{ {
carla_zeroFloats(buffer[0], desiredNumFrames);
carla_zeroFloats(buffer[1], desiredNumFrames);
if (startFrame + numFrames <= maxFrame)
{
needsRead = true;
needsReadFrame = framePos;
return false;
}

frameDiff = framePos + (maxFrame - startFrame);


if (tmpbuf[0] != nullptr)
carla_zeroFloats(tmpbuf[0], desiredNumFrames);
if (tmpbuf[1] != nullptr)
carla_zeroFloats(tmpbuf[1], desiredNumFrames);
if (frameDiff + frames >= numFrames)
{
needsRead = true;
needsReadFrame = framePos;
return false;
}

carla_copyFloats(out1, buffer[0] + frameDiff, frames);
carla_copyFloats(out2, buffer[1] + frameDiff, frames);
} }
else
{
frameDiff = framePos - startFrame;


const water::GenericScopedLock<water::SpinLock> gsl(mutex);
if (frameDiff + frames >= numFrames)
{
needsRead = true;
needsReadFrame = framePos;
return false;
}

carla_copyFloats(out1, buffer[0] + frameDiff, frames);
carla_copyFloats(out2, buffer[1] + frameDiff, frames);
}


if (frameDiff > numFramesNearEnd)
{ {
startFrame = 0;
numFrames = desiredNumFrames;
needsRead = true;
needsReadFrame = framePos + (isOffline ? 0 : frames);
} }

return true;
} }


CARLA_DECLARE_NON_COPY_STRUCT(AudioFilePool) CARLA_DECLARE_NON_COPY_STRUCT(AudioFilePool)
@@ -171,13 +232,14 @@ public:
fNeedsRead(false), fNeedsRead(false),
fFilePtr(nullptr), fFilePtr(nullptr),
fFileNfo(), fFileNfo(),
fMaxFrame(0),
fResampleRatio(0.0),
fPollTempData(nullptr), fPollTempData(nullptr),
fPollTempSize(0), fPollTempSize(0),
fResampleRatio(0.0),
fResampleTempData(nullptr), fResampleTempData(nullptr),
fResampleTempSize(0), fResampleTempSize(0),
fPool(), fPool(),
fPoolMutex(),
fPoolReadyToSwap(false),
fResampler(), fResampler(),
fReaderMutex() fReaderMutex()
{ {
@@ -239,17 +301,7 @@ public:


uint32_t getMaxFrame() const noexcept uint32_t getMaxFrame() const noexcept
{ {
return fMaxFrame;
}

uint64_t getPoolStartFrame() const noexcept
{
return fPool.startFrame;
}

uint32_t getPoolNumFrames() const noexcept
{
return fPool.numFrames;
return fPool.maxFrame;
} }


ADInfo getFileInfo() const noexcept ADInfo getFileInfo() const noexcept
@@ -302,6 +354,7 @@ public:
const uint32_t fileNumFrames = static_cast<uint32_t>(fFileNfo.frames); const uint32_t fileNumFrames = static_cast<uint32_t>(fFileNfo.frames);
const uint32_t maxPoolNumFrames = sampleRate * 30; const uint32_t maxPoolNumFrames = sampleRate * 30;
const bool needsResample = fFileNfo.sample_rate != sampleRate; const bool needsResample = fFileNfo.sample_rate != sampleRate;
uint32_t maxFrame;


if (needsResample) if (needsResample)
{ {
@@ -315,18 +368,22 @@ public:
} }


fResampleRatio = static_cast<double>(sampleRate) / static_cast<double>(fFileNfo.sample_rate); fResampleRatio = static_cast<double>(sampleRate) / static_cast<double>(fFileNfo.sample_rate);
maxFrame = static_cast<uint32_t>(static_cast<double>(fileNumFrames) * fResampleRatio + 0.5);
} }
else else
{ {
fResampler.clear(); fResampler.clear();
fResampleRatio = 0.0; fResampleRatio = 0.0;
maxFrame = fileNumFrames;
} }


if (fileNumFrames <= maxPoolNumFrames) if (fileNumFrames <= maxPoolNumFrames)
{ {
// entire file fits in a small pool, lets read it now // entire file fits in a small pool, lets read it now
fPool.create(needsResample ? static_cast<uint32_t>(static_cast<double>(fileNumFrames) * fResampleRatio + 0.5)
: fileNumFrames, false);
const uint32_t poolNumFrames = needsResample
? static_cast<uint32_t>(static_cast<double>(fileNumFrames) * fResampleRatio + 0.5)
: fileNumFrames;
fPool.create(poolNumFrames, maxFrame, false);
readEntireFileIntoPool(needsResample); readEntireFileIntoPool(needsResample);
ad_close(fFilePtr); ad_close(fFilePtr);
fFilePtr = nullptr; fFilePtr = nullptr;
@@ -343,13 +400,13 @@ public:
else else
{ {
// file is too big for our audio pool, we need an extra buffer // file is too big for our audio pool, we need an extra buffer
const uint32_t poolNumFrames = sampleRate * 1;
const uint32_t poolNumFrames = sampleRate * 5;
const uint pollTempSize = poolNumFrames * fFileNfo.channels; const uint pollTempSize = poolNumFrames * fFileNfo.channels;
uint resampleTempSize = 0; uint resampleTempSize = 0;


readFilePreview(previewDataSize, previewData); readFilePreview(previewDataSize, previewData);


fPool.create(poolNumFrames, true);
fPool.create(poolNumFrames, maxFrame, true);


try { try {
fPollTempData = new float[pollTempSize]; fPollTempData = new float[pollTempSize];
@@ -387,10 +444,6 @@ public:
fResampleTempSize = resampleTempSize; fResampleTempSize = resampleTempSize;
} }


fMaxFrame = carla_isNotZero(fResampleRatio)
? static_cast<uint32_t>(static_cast<double>(fileNumFrames) * fResampleRatio + 0.5)
: fileNumFrames;

fNeedsRead = true; fNeedsRead = true;
return true; return true;
} }
@@ -404,13 +457,20 @@ public:
} }
} }


void createSwapablePool(AudioFilePool& pool)
{
pool.create(fPool.numFrames, fPool.maxFrame, false);
}

void putAndSwapAllData(AudioFilePool& pool) void putAndSwapAllData(AudioFilePool& pool)
{ {
const water::GenericScopedLock<water::SpinLock> gsl1(fPool.mutex); const water::GenericScopedLock<water::SpinLock> gsl1(fPool.mutex);
const water::GenericScopedLock<water::SpinLock> gsl2(pool.mutex); const water::GenericScopedLock<water::SpinLock> gsl2(pool.mutex);
CARLA_SAFE_ASSERT_RETURN(fPool.numFrames != 0,); CARLA_SAFE_ASSERT_RETURN(fPool.numFrames != 0,);
CARLA_SAFE_ASSERT_RETURN(pool.numFrames == 0,);
CARLA_SAFE_ASSERT_RETURN(fPool.buffer[0] != nullptr,);
CARLA_SAFE_ASSERT_RETURN(fPool.tmpbuf[0] == nullptr,); CARLA_SAFE_ASSERT_RETURN(fPool.tmpbuf[0] == nullptr,);
CARLA_SAFE_ASSERT_RETURN(pool.numFrames == 0,);
CARLA_SAFE_ASSERT_RETURN(pool.buffer[0] == nullptr,);
CARLA_SAFE_ASSERT_RETURN(pool.tmpbuf[0] == nullptr,); CARLA_SAFE_ASSERT_RETURN(pool.tmpbuf[0] == nullptr,);


pool.startFrame = fPool.startFrame; pool.startFrame = fPool.startFrame;
@@ -424,70 +484,33 @@ public:
fPool.buffer[1] = nullptr; fPool.buffer[1] = nullptr;
} }


bool tryPutData(float* const out1,
bool tryPutData(AudioFilePool& pool,
float* const out1,
float* const out2, float* const out2,
uint64_t framePos, uint64_t framePos,
const uint32_t frames, const uint32_t frames,
const bool loopMode,
const bool isOffline, const bool isOffline,
bool& needsRead)
bool& needsIdleRequest)
{ {
const water::GenericScopedLock<water::SpinLock> gsl(fPool.mutex);
CARLA_SAFE_ASSERT_RETURN(fPool.numFrames != 0, false);
_tryPoolSwap(pool);


if (framePos >= fMaxFrame)
{
if (fLoopingMode)
framePos %= fMaxFrame;
else
return false;
}

uint64_t frameDiff;
const uint64_t numFramesNearEnd = fPool.numFrames*3/5;

if (framePos < fPool.startFrame)
{
if (fPool.startFrame + fPool.numFrames <= fMaxFrame)
{
needsRead = true;
setNeedsRead(framePos);
return false;
}

frameDiff = framePos + (fMaxFrame - fPool.startFrame);

if (frameDiff + frames >= fPool.numFrames)
{
needsRead = true;
setNeedsRead(framePos);
return false;
}
bool needsRead = false;
uint32_t needsReadFrame;
const bool ret = pool.tryPutData(out1, out2, framePos, frames, loopMode, isOffline, needsRead, needsReadFrame);


carla_copyFloats(out1, fPool.buffer[0] + frameDiff, frames);
carla_copyFloats(out2, fPool.buffer[1] + frameDiff, frames);
}
else
if (needsRead)
{ {
frameDiff = framePos - fPool.startFrame;

if (frameDiff + frames >= fPool.numFrames)
{
needsRead = true;
setNeedsRead(framePos);
return false;
}

carla_copyFloats(out1, fPool.buffer[0] + frameDiff, frames);
carla_copyFloats(out2, fPool.buffer[1] + frameDiff, frames);
needsIdleRequest = true;
setNeedsRead(needsReadFrame);
} }


if (frameDiff > numFramesNearEnd)
{
needsRead = true;
setNeedsRead(framePos + (isOffline ? 0 : frames));
#ifdef DEBUG_FILE_OPS
if (! ret) {
carla_stdout("tryPutData fail");
} }
return true;
#endif
return ret;
} }


void readFilePreview(const uint32_t previewDataSize, float* previewData) void readFilePreview(const uint32_t previewDataSize, float* previewData)
@@ -586,7 +609,7 @@ public:
{ {
const CarlaMutexLocker cml(fReaderMutex); const CarlaMutexLocker cml(fReaderMutex);


if (fMaxFrame == 0 || fFileNfo.channels == 0 || fFilePtr == nullptr)
if (fFileNfo.channels == 0 || fFilePtr == nullptr)
{ {
carla_debug("R: no song loaded"); carla_debug("R: no song loaded");
fNeedsFrame = 0; fNeedsFrame = 0;
@@ -602,13 +625,14 @@ public:
} }


uint64_t lastFrame = fNeedsFrame; uint64_t lastFrame = fNeedsFrame;
uint32_t maxFrame = fPool.maxFrame;
int64_t readFrameCheck; int64_t readFrameCheck;


if (lastFrame >= fMaxFrame)
if (lastFrame >= maxFrame)
{ {
if (fLoopingMode) if (fLoopingMode)
{ {
const uint64_t readFrameCheckLoop = lastFrame % fMaxFrame;
const uint64_t readFrameCheckLoop = lastFrame % maxFrame;
CARLA_SAFE_ASSERT_RETURN(readFrameCheckLoop < INT32_MAX,); CARLA_SAFE_ASSERT_RETURN(readFrameCheckLoop < INT32_MAX,);


carla_debug("R: transport out of bounds for loop"); carla_debug("R: transport out of bounds for loop");
@@ -662,7 +686,9 @@ public:
// see if we can read more // see if we can read more
if (readFrameReal + rv >= static_cast<ssize_t>(fFileNfo.frames) && urv < fPollTempSize) if (readFrameReal + rv >= static_cast<ssize_t>(fFileNfo.frames) && urv < fPollTempSize)
{ {
carla_debug("R: from start");
#ifdef DEBUG_FILE_OPS
carla_stdout("R: from start");
#endif
ad_seek(fFilePtr, 0); ad_seek(fFilePtr, 0);
j = ad_read(fFilePtr, fPollTempData+urv, fPollTempSize-urv); j = ad_read(fFilePtr, fPollTempData+urv, fPollTempSize-urv);


@@ -677,7 +703,9 @@ public:
rv += j; rv += j;
} }


carla_debug("R: reading %li frames at frame %lu", rv, readFrameCheck);
#ifdef DEBUG_FILE_OPS
carla_stdout("R: reading %li frames at frame %lu", rv, readFrameCheck);
#endif


// local copy // local copy
const uint32_t poolNumFrames = fPool.numFrames; const uint32_t poolNumFrames = fPool.numFrames;
@@ -727,12 +755,15 @@ public:
{ {
// full file read // full file read
j = 0; j = 0;
carla_debug("R: full file was read, filling buffers again");
#ifdef DEBUG_FILE_OPS
carla_stdout("R: full file was read, filling buffers again");
#endif
} }
else else
{ {
carla_debug("read break, not enough space");

#ifdef DEBUG_FILE_OPS
carla_stdout("read break, not enough space");
#endif
carla_zeroFloats(pbuffer0, poolNumFrames - i); carla_zeroFloats(pbuffer0, poolNumFrames - i);
carla_zeroFloats(pbuffer1, poolNumFrames - i); carla_zeroFloats(pbuffer1, poolNumFrames - i);
break; break;
@@ -741,11 +772,16 @@ public:
} while (i < poolNumFrames); } while (i < poolNumFrames);


// lock, and put data asap // lock, and put data asap
const CarlaMutexLocker cml(fPoolMutex);
const water::GenericScopedLock<water::SpinLock> gsl(fPool.mutex); const water::GenericScopedLock<water::SpinLock> gsl(fPool.mutex);


std::memcpy(fPool.buffer[0], pbuffer0, sizeof(float)*poolNumFrames); std::memcpy(fPool.buffer[0], pbuffer0, sizeof(float)*poolNumFrames);
std::memcpy(fPool.buffer[1], pbuffer1, sizeof(float)*poolNumFrames); std::memcpy(fPool.buffer[1], pbuffer1, sizeof(float)*poolNumFrames);
fPool.startFrame = static_cast<uint64_t>(readFrame); fPool.startFrame = static_cast<uint64_t>(readFrame);
fPoolReadyToSwap = true;
#ifdef DEBUG_FILE_OPS
carla_stdout("Reading done and internal pool is now full");
#endif
} }


fNeedsRead = false; fNeedsRead = false;
@@ -760,19 +796,59 @@ private:
void* fFilePtr; void* fFilePtr;
ADInfo fFileNfo; ADInfo fFileNfo;


uint32_t fMaxFrame;
double fResampleRatio;

float* fPollTempData; float* fPollTempData;
uint fPollTempSize; uint fPollTempSize;


double fResampleRatio;
float* fResampleTempData; float* fResampleTempData;
uint fResampleTempSize; uint fResampleTempSize;


AudioFilePool fPool; AudioFilePool fPool;
CarlaMutex fPoolMutex;
bool fPoolReadyToSwap;
Resampler fResampler; Resampler fResampler;
CarlaMutex fReaderMutex; CarlaMutex fReaderMutex;


// try a pool data swap if possible and relevant
// NOTE it is assumed that `pool` mutex is locked
void _tryPoolSwap(AudioFilePool& pool)
{
uint32_t tmp_u;
float* tmp_fp;

const CarlaMutexTryLocker cmtl(fPoolMutex);

if (! cmtl.wasLocked())
return;

const water::GenericScopedLock<water::SpinLock> gsl(fPool.mutex);

if (! fPoolReadyToSwap)
return;

tmp_u = pool.startFrame;
pool.startFrame = fPool.startFrame;
fPool.startFrame = tmp_u;

tmp_u = pool.numFrames;
pool.numFrames = fPool.numFrames;
fPool.numFrames = tmp_u;

tmp_fp = pool.buffer[0];
pool.buffer[0] = fPool.buffer[0];
fPool.buffer[0] = tmp_fp;

tmp_fp = pool.buffer[1];
pool.buffer[1] = fPool.buffer[1];
fPool.buffer[1] = tmp_fp;

fPoolReadyToSwap = false;

#ifdef DEBUG_FILE_OPS
carla_stdout("Pools have been swapped, internal one is now invalidated");
#endif
}

CARLA_DECLARE_NON_COPY_STRUCT(AudioFileReader) CARLA_DECLARE_NON_COPY_STRUCT(AudioFileReader)
}; };




+ 17
- 10
source/native-plugins/audio-file.cpp View File

@@ -1,6 +1,6 @@
/* /*
* Carla Native Plugins * Carla Native Plugins
* Copyright (C) 2013-2020 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2013-2021 Filipe Coelho <falktx@falktx.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
@@ -73,6 +73,7 @@ public:
fDoProcess(false), fDoProcess(false),
fWasPlayingBefore(false), fWasPlayingBefore(false),
fNeedsFileRead(false), fNeedsFileRead(false),
fEntireFileLoaded(false),
fMaxFrame(0), fMaxFrame(0),
fLastPosition(0), fLastPosition(0),
fPool(), fPool(),
@@ -248,11 +249,14 @@ protected:
const NativeMidiEvent*, uint32_t) override const NativeMidiEvent*, uint32_t) override
{ {
const NativeTimeInfo* const timePos(getTimeInfo()); const NativeTimeInfo* const timePos(getTimeInfo());
const bool loopMode = fLoopMode;


float* out1 = outBuffer[0]; float* out1 = outBuffer[0];
float* out2 = outBuffer[1]; float* out2 = outBuffer[1];
bool needsIdleRequest = false; bool needsIdleRequest = false;


const water::GenericScopedLock<water::SpinLock> gsl(fPool.mutex);

if (! fDoProcess) if (! fDoProcess)
{ {
// carla_stderr("P: no process"); // carla_stderr("P: no process");
@@ -280,7 +284,7 @@ protected:
} }


// out of reach // out of reach
if ((timePos->frame < fPool.startFrame || timePos->frame >= fMaxFrame) && !fLoopMode)
if ((timePos->frame < fPool.startFrame || timePos->frame >= fMaxFrame) && !loopMode)
{ {
if (timePos->frame < fPool.startFrame) if (timePos->frame < fPool.startFrame)
{ {
@@ -318,10 +322,10 @@ protected:
return; return;
} }


if (fReader.isEntireFileLoaded())
if (fEntireFileLoaded)
{ {
// NOTE: timePos->frame is always < fMaxFrame (or looping) // NOTE: timePos->frame is always < fMaxFrame (or looping)
uint32_t targetStartFrame = static_cast<uint32_t>(fLoopMode ? timePos->frame % fMaxFrame : timePos->frame);
uint32_t targetStartFrame = static_cast<uint32_t>(loopMode ? timePos->frame % fMaxFrame : timePos->frame);


for (uint32_t framesDone=0, framesToDo=frames, remainingFrames; framesDone < frames;) for (uint32_t framesDone=0, framesToDo=frames, remainingFrames; framesDone < frames;)
{ {
@@ -339,7 +343,7 @@ protected:
framesDone += remainingFrames; framesDone += remainingFrames;
framesToDo -= remainingFrames; framesToDo -= remainingFrames;


if (! fLoopMode)
if (! loopMode)
{ {
// not looping, stop here // not looping, stop here
if (framesToDo != 0) if (framesToDo != 0)
@@ -360,7 +364,7 @@ protected:
{ {
const bool offline = isOffline(); const bool offline = isOffline();


if (! fReader.tryPutData(out1, out2, timePos->frame, frames, offline, needsIdleRequest))
if (! fReader.tryPutData(fPool, out1, out2, timePos->frame, frames, loopMode, offline, needsIdleRequest))
{ {
carla_zeroFloats(out1, frames); carla_zeroFloats(out1, frames);
carla_zeroFloats(out2, frames); carla_zeroFloats(out2, frames);
@@ -375,7 +379,7 @@ protected:
needsIdleRequest = false; needsIdleRequest = false;
fReader.readPoll(); fReader.readPoll();


if (! fReader.tryPutData(out1, out2, timePos->frame, frames, offline, needsIdleRequest))
if (! fReader.tryPutData(fPool, out1, out2, timePos->frame, frames, loopMode, offline, needsIdleRequest))
{ {
carla_zeroFloats(out1, frames); carla_zeroFloats(out1, frames);
carla_zeroFloats(out2, frames); carla_zeroFloats(out2, frames);
@@ -571,6 +575,7 @@ private:
bool fWasPlayingBefore; bool fWasPlayingBefore;
volatile bool fNeedsFileRead; volatile bool fNeedsFileRead;


bool fEntireFileLoaded;
uint32_t fMaxFrame; uint32_t fMaxFrame;
float fLastPosition; float fLastPosition;


@@ -622,8 +627,8 @@ private:
carla_debug("AudioFilePlugin::loadFilename(\"%s\")", filename); carla_debug("AudioFilePlugin::loadFilename(\"%s\")", filename);


fDoProcess = false; fDoProcess = false;
fReader.destroy();
fPool.destroy(); fPool.destroy();
fReader.destroy();


if (filename == nullptr || *filename == '\0') if (filename == nullptr || *filename == '\0')
{ {
@@ -635,15 +640,16 @@ private:


if (fReader.loadFilename(filename, static_cast<uint32_t>(getSampleRate()), previewDataSize, fPreviewData)) if (fReader.loadFilename(filename, static_cast<uint32_t>(getSampleRate()), previewDataSize, fPreviewData))
{ {
fEntireFileLoaded = fReader.isEntireFileLoaded();
fMaxFrame = fReader.getMaxFrame(); fMaxFrame = fReader.getMaxFrame();


if (fReader.isEntireFileLoaded())
if (fEntireFileLoaded)
{ {
fReader.putAndSwapAllData(fPool); fReader.putAndSwapAllData(fPool);
} }
else else
{ {
fPool.create(fReader.getPoolNumFrames(), false);
fReader.createSwapablePool(fPool);
fReader.readPoll(); fReader.readPoll();
} }


@@ -652,6 +658,7 @@ private:
} }
else else
{ {
fEntireFileLoaded = false;
fMaxFrame = 0; fMaxFrame = 0;
} }
} }


Loading…
Cancel
Save