Browse Source

Smaller pool for audio file, but load full if < 10s; use mlock

Signed-off-by: falkTX <falktx@falktx.com>
tags/v2.3.0-RC1
falkTX 3 years ago
parent
commit
99cda3bb20
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
1 changed files with 34 additions and 17 deletions
  1. +34
    -17
      source/native-plugins/audio-base.hpp

+ 34
- 17
source/native-plugins/audio-base.hpp View File

@@ -28,7 +28,6 @@ extern "C" {
#include "water/threads/ScopedLock.h" #include "water/threads/ScopedLock.h"
#include "water/threads/SpinLock.h" #include "water/threads/SpinLock.h"



#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
# pragma GCC diagnostic push # pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Weffc++" # pragma GCC diagnostic ignored "-Weffc++"
@@ -40,6 +39,14 @@ extern "C" {
# pragma GCC diagnostic pop # pragma GCC diagnostic pop
#endif #endif


#ifdef CARLA_OS_WIN
# include <windows.h>
# define CARLA_MLOCK(ptr, size) VirtualLock((ptr), (size))
#else
# include <sys/mman.h>
# define CARLA_MLOCK(ptr, size) mlock((ptr), (size))
#endif

typedef struct adinfo ADInfo; typedef struct adinfo ADInfo;


struct AudioFilePool { struct AudioFilePool {
@@ -81,11 +88,15 @@ struct AudioFilePool {
numFrames = desiredNumFrames; numFrames = desiredNumFrames;
buffer[0] = new float[numFrames]; buffer[0] = new float[numFrames];
buffer[1] = new float[numFrames]; buffer[1] = new float[numFrames];
CARLA_MLOCK(buffer[0], sizeof(float)*numFrames);
CARLA_MLOCK(buffer[1], sizeof(float)*numFrames);


if (withTempBuffers) if (withTempBuffers)
{ {
tmpbuf[0] = new float[numFrames]; tmpbuf[0] = new float[numFrames];
tmpbuf[1] = new float[numFrames]; tmpbuf[1] = new float[numFrames];
CARLA_MLOCK(tmpbuf[0], sizeof(float)*numFrames);
CARLA_MLOCK(tmpbuf[1], sizeof(float)*numFrames);
} }


reset(); reset();
@@ -282,10 +293,10 @@ public:
{ {
// valid // valid
const uint32_t fileNumFrames = static_cast<uint32_t>(fFileNfo.frames); const uint32_t fileNumFrames = static_cast<uint32_t>(fFileNfo.frames);
const uint32_t poolNumFrames = sampleRate * 5;
uint32_t resampleNumFrames;
const uint32_t maxPoolNumFrames = sampleRate * 10;
const bool needsResample = fFileNfo.sample_rate != sampleRate;


if (fFileNfo.sample_rate != sampleRate)
if (needsResample)
{ {
if (! fResampler.setup(fFileNfo.sample_rate, sampleRate, fFileNfo.channels, 32)) if (! fResampler.setup(fFileNfo.sample_rate, sampleRate, fFileNfo.channels, 32))
{ {
@@ -297,31 +308,30 @@ public:
} }


fResampleRatio = static_cast<double>(sampleRate) / static_cast<double>(fFileNfo.sample_rate); fResampleRatio = static_cast<double>(sampleRate) / static_cast<double>(fFileNfo.sample_rate);
resampleNumFrames = static_cast<uint32_t>(
static_cast<double>(std::min(fileNumFrames, poolNumFrames)) * fResampleRatio + 0.5);
} }
else else
{ {
fResampler.clear(); fResampler.clear();
fResampleRatio = 0.0; fResampleRatio = 0.0;
resampleNumFrames = 0;
} }


if (fileNumFrames <= poolNumFrames)
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(resampleNumFrames != 0 ? resampleNumFrames : fileNumFrames, false);
readEntireFileIntoPool(resampleNumFrames != 0);
fPool.create(needsResample ? static_cast<uint32_t>(static_cast<double>(fileNumFrames) * fResampleRatio + 0.5)
: fileNumFrames, false);
readEntireFileIntoPool(needsResample);
ad_close(fFilePtr); ad_close(fFilePtr);
fFilePtr = nullptr; fFilePtr = nullptr;
} }
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
fPool.create(poolNumFrames, true);

const uint32_t poolNumFrames = sampleRate * 1;
const uint pollTempSize = poolNumFrames * fFileNfo.channels; const uint pollTempSize = poolNumFrames * fFileNfo.channels;
const uint resampleTempSize = resampleNumFrames * fFileNfo.channels;
uint resampleTempSize = 0;

fPool.create(poolNumFrames, true);


try { try {
fPollTempData = new float[pollTempSize]; fPollTempData = new float[pollTempSize];
@@ -333,8 +343,13 @@ public:
return false; return false;
} }


if (resampleTempSize)
CARLA_MLOCK(fPollTempData, sizeof(float)*pollTempSize);

if (needsResample)
{ {
resampleTempSize = static_cast<uint32_t>(static_cast<double>(poolNumFrames) * fResampleRatio + 0.5);
resampleTempSize *= fFileNfo.channels;

try { try {
fResampleTempData = new float[resampleTempSize]; fResampleTempData = new float[resampleTempSize];
} catch (...) { } catch (...) {
@@ -346,6 +361,8 @@ public:
carla_stderr2("loadFilename error, out of memory"); carla_stderr2("loadFilename error, out of memory");
return false; return false;
} }

CARLA_MLOCK(fResampleTempData, sizeof(float)*resampleTempSize);
} }


fPollTempSize = pollTempSize; fPollTempSize = pollTempSize;
@@ -398,7 +415,7 @@ public:
} }


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


const water::GenericScopedLock<water::SpinLock> gsl(fPoolMutex); const water::GenericScopedLock<water::SpinLock> gsl(fPoolMutex);


@@ -684,8 +701,8 @@ public:
// lock, and put data asap // lock, and put data asap
const water::GenericScopedLock<water::SpinLock> gsl(fPoolMutex); const water::GenericScopedLock<water::SpinLock> gsl(fPoolMutex);


carla_copyFloats(fPool.buffer[0], pbuffer0, poolNumFrames);
carla_copyFloats(fPool.buffer[1], pbuffer1, poolNumFrames);
std::memcpy(fPool.buffer[0], pbuffer0, 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);
} }




Loading…
Cancel
Save