Browse Source

Finish resampling details, seems to work nicely

tags/v2.3.0-RC1
falkTX 3 years ago
parent
commit
53717dd434
1 changed files with 36 additions and 28 deletions
  1. +36
    -28
      source/native-plugins/audio-base.hpp

+ 36
- 28
source/native-plugins/audio-base.hpp View File

@@ -111,7 +111,8 @@ public:
fQuitNow(true),
fFilePtr(nullptr),
fFileNfo(),
fNumFileFrames(0),
fMaxFrame(0),
fResampleRatio(1.0),
fPollTempData(nullptr),
fPollTempSize(0),
fResampleTempData(nullptr),
@@ -198,7 +199,7 @@ public:

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

uint64_t getPoolStartFrame() const noexcept
@@ -259,21 +260,21 @@ public:
if (fFileNfo.sample_rate != sampleRate)
{
fResampler.setup(fFileNfo.sample_rate, sampleRate, fFileNfo.channels, 32);
fResampleRatio = static_cast<double>(sampleRate) / static_cast<double>(fFileNfo.sample_rate);
resampleNumFrames = static_cast<uint32_t>(
static_cast<double>(std::min(fileNumFrames, poolNumFrames)) * (
static_cast<double>(sampleRate) / static_cast<double>(fFileNfo.sample_rate)
) + 0.5);
static_cast<double>(std::min(fileNumFrames, poolNumFrames)) * fResampleRatio + 0.5);
}
else
{
fResampler.clear();
fResampleRatio = 1.0;
resampleNumFrames = 0;
}

if (fileNumFrames <= poolNumFrames)
{
// entire file fits in a small pool, lets read it now
fPool.create(poolNumFrames);
fPool.create(resampleNumFrames != 0 ? resampleNumFrames : fileNumFrames);
readEntireFileIntoPool(resampleNumFrames != 0);
ad_close(fFilePtr);
fFilePtr = nullptr;
@@ -311,7 +312,9 @@ public:
fResampleTempSize = resampleTempSize;
}

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

readPoll();
return true;
@@ -341,10 +344,10 @@ public:
{
CARLA_SAFE_ASSERT_RETURN(fPool.numFrames != 0, false);

if (framePos >= fNumFileFrames)
if (framePos >= fMaxFrame)
{
if (fLoopingMode)
framePos %= fNumFileFrames;
framePos %= fMaxFrame;
else
return false;
}
@@ -371,13 +374,13 @@ public:

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

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

if (frameDiff + frames >= fPool.numFrames)
{
@@ -413,33 +416,34 @@ public:
CARLA_SAFE_ASSERT_RETURN(fPool.numFrames > 0,);

const uint numChannels = fFileNfo.channels;
const size_t numFrames = fFileNfo.frames;
const size_t bufferSize = fFileNfo.frames * numChannels;

float* const buffer = (float*)std::malloc(numFrames*sizeof(float));
float* const buffer = (float*)std::malloc(bufferSize*sizeof(float));
CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,);
carla_zeroFloats(buffer, numFrames);
carla_zeroFloats(buffer, bufferSize);

ad_seek(fFilePtr, 0);
ssize_t rv = ad_read(fFilePtr, buffer, numFrames);
CARLA_SAFE_ASSERT_INT2_RETURN(rv == static_cast<ssize_t>(numFrames),
ssize_t rv = ad_read(fFilePtr, buffer, bufferSize);
CARLA_SAFE_ASSERT_INT2_RETURN(rv == static_cast<ssize_t>(bufferSize),
static_cast<int>(rv),
static_cast<int>(numFrames),
static_cast<int>(bufferSize),
std::free(buffer));

float* rbuffer;

if (needsResample)
{
rv = fPool.numFrames;
rbuffer = (float*)std::malloc(fPool.numFrames*sizeof(float));
rv = fPool.numFrames * numChannels;
rbuffer = (float*)std::malloc(rv*sizeof(float));
CARLA_SAFE_ASSERT_RETURN(rbuffer != nullptr, std::free(buffer););
carla_zeroFloats(rbuffer, fPool.numFrames);
carla_zeroFloats(rbuffer, rv);

fResampler.inp_count = numFrames / numChannels;
fResampler.out_count = fPool.numFrames / numChannels;
fResampler.inp_count = bufferSize / numChannels;
fResampler.out_count = fPool.numFrames;
fResampler.inp_data = buffer;
fResampler.out_data = rbuffer;
fResampler.process();
CARLA_ASSERT_INT(fResampler.inp_count == 0, fResampler.inp_count);
}
else
{
@@ -483,7 +487,7 @@ public:

void readPoll()
{
if (fNumFileFrames == 0 || fFileNfo.channels == 0 || fFilePtr == nullptr)
if (fMaxFrame == 0 || fFileNfo.channels == 0 || fFilePtr == nullptr)
{
carla_debug("R: no song loaded");
fNeedsFrame = 0;
@@ -501,11 +505,11 @@ public:
uint64_t lastFrame = fNeedsFrame;
int64_t readFrameCheck;

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

carla_debug("R: transport out of bounds for loop");
@@ -537,7 +541,9 @@ public:
readFrame, readFrame/sampleRate/60, (readFrame/sampleRate) % 60, lastFrame);
#endif

ad_seek(fFilePtr, readFrame);
const int64_t readFrameReal = fResampleRatio != 1.0 ? readFrame / fResampleRatio : readFrame;

ad_seek(fFilePtr, readFrameReal);
size_t i = 0;
ssize_t j = 0;
ssize_t rv = ad_read(fFilePtr, fPollTempData, fPollTempSize);
@@ -553,7 +559,7 @@ public:
const size_t urv = static_cast<size_t>(rv);

// see if we can read more
if (readFrame + 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");
ad_seek(fFilePtr, 0);
@@ -579,6 +585,7 @@ public:
fResampler.inp_data = fPollTempData;
fResampler.out_data = fResampleTempData;
fResampler.process();
CARLA_ASSERT_INT(fResampler.inp_count == 0, fResampler.inp_count);
}

// lock, and put data asap
@@ -657,7 +664,8 @@ private:
void* fFilePtr;
ADInfo fFileNfo;

uint32_t fNumFileFrames;
uint32_t fMaxFrame;
double fResampleRatio;

float* fPollTempData;
size_t fPollTempSize;


Loading…
Cancel
Save