Browse Source

Rework audio file plugin, finally actually works properly

tags/v2.1-rc1
falkTX 6 years ago
parent
commit
90304c8693
2 changed files with 268 additions and 150 deletions
  1. +185
    -104
      source/native-plugins/audio-base.hpp
  2. +83
    -46
      source/native-plugins/audio-file.cpp

+ 185
- 104
source/native-plugins/audio-base.hpp View File

@@ -1,6 +1,6 @@
/* /*
* Carla Native Plugins * Carla Native Plugins
* Copyright (C) 2013-2018 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2013-2019 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
@@ -29,21 +29,18 @@ typedef struct adinfo ADInfo;


struct AudioFilePool { struct AudioFilePool {
float* buffer[2]; float* buffer[2];
uint64_t startFrame;
uint32_t sampleRate;
uint32_t size;
uint32_t numFrames;
volatile uint64_t startFrame;


#ifdef CARLA_PROPER_CPP11_SUPPORT #ifdef CARLA_PROPER_CPP11_SUPPORT
AudioFilePool()
AudioFilePool() noexcept
: buffer{nullptr}, : buffer{nullptr},
startFrame(0),
sampleRate(0),
size(0) {}
numFrames(0),
startFrame(0) {}
#else #else
AudioFilePool()
: startFrame(0),
sampleRate(0),
size(0)
AudioFilePool() noexcept
: numFrames(0),
startFrame(0)
{ {
buffer[0] = buffer[1] = nullptr; buffer[0] = buffer[1] = nullptr;
} }
@@ -51,34 +48,25 @@ struct AudioFilePool {


~AudioFilePool() ~AudioFilePool()
{ {
CARLA_ASSERT(buffer[0] == nullptr);
CARLA_ASSERT(buffer[1] == nullptr);
CARLA_ASSERT(startFrame == 0);
CARLA_ASSERT(size == 0);
destroy();
} }


void create(const uint32_t srate)
void create(const uint32_t desiredNumFrames)
{ {
CARLA_ASSERT(buffer[0] == nullptr); CARLA_ASSERT(buffer[0] == nullptr);
CARLA_ASSERT(buffer[1] == nullptr); CARLA_ASSERT(buffer[1] == nullptr);
CARLA_ASSERT(startFrame == 0); CARLA_ASSERT(startFrame == 0);
CARLA_ASSERT(size == 0);
CARLA_ASSERT(numFrames == 0);


size = srate * 60; // buffer of 60 secs
sampleRate = srate;

buffer[0] = new float[size];
buffer[1] = new float[size];
numFrames = desiredNumFrames;
buffer[0] = new float[numFrames];
buffer[1] = new float[numFrames];


reset(); reset();
} }


void destroy()
void destroy() noexcept
{ {
CARLA_ASSERT(buffer[0] != nullptr);
CARLA_ASSERT(buffer[1] != nullptr);
CARLA_ASSERT(size != 0);

if (buffer[0] != nullptr) if (buffer[0] != nullptr)
{ {
delete[] buffer[0]; delete[] buffer[0];
@@ -92,16 +80,18 @@ struct AudioFilePool {
} }


startFrame = 0; startFrame = 0;
size = 0;
numFrames = 0;
} }


void reset()
void reset() noexcept
{ {
startFrame = 0; startFrame = 0;
CARLA_SAFE_ASSERT_RETURN(size != 0,);


carla_zeroFloats(buffer[0], size);
carla_zeroFloats(buffer[1], size);
if (numFrames != 0)
{
carla_zeroFloats(buffer[0], numFrames);
carla_zeroFloats(buffer[1], numFrames);
}
} }


CARLA_DECLARE_NON_COPY_STRUCT(AudioFilePool) CARLA_DECLARE_NON_COPY_STRUCT(AudioFilePool)
@@ -117,15 +107,16 @@ public:
class AudioFileThread : public CarlaThread class AudioFileThread : public CarlaThread
{ {
public: public:
AudioFileThread(AbstractAudioPlayer* const player, const uint32_t sampleRate)
AudioFileThread(AbstractAudioPlayer* const player)
: CarlaThread("AudioFileThread"), : CarlaThread("AudioFileThread"),
kPlayer(player), kPlayer(player),
fEntireFileLoaded(false),
fLoopingMode(true), fLoopingMode(true),
fNeedsRead(false), fNeedsRead(false),
fQuitNow(true), fQuitNow(true),
fFilePtr(nullptr), fFilePtr(nullptr),
fFileNfo(), fFileNfo(),
fMaxPlayerFrame(0),
fNumFileFrames(0),
fPollTempData(nullptr), fPollTempData(nullptr),
fPollTempSize(0), fPollTempSize(0),
fPool(), fPool(),
@@ -142,8 +133,6 @@ public:
} }


ad_clear_nfo(&fFileNfo); ad_clear_nfo(&fFileNfo);

fPool.create(sampleRate);
} }


~AudioFileThread() override ~AudioFileThread() override
@@ -151,6 +140,13 @@ public:
CARLA_ASSERT(fQuitNow); CARLA_ASSERT(fQuitNow);
CARLA_ASSERT(! isThreadRunning()); CARLA_ASSERT(! isThreadRunning());


cleanup();
}

void cleanup()
{
fEntireFileLoaded = false;

if (fFilePtr != nullptr) if (fFilePtr != nullptr)
{ {
ad_close(fFilePtr); ad_close(fFilePtr);
@@ -169,6 +165,9 @@ public:


void startNow() void startNow()
{ {
if (fPollTempData == nullptr)
return;

fNeedsRead = true; fNeedsRead = true;
fQuitNow = false; fQuitNow = false;
startThread(); startThread();
@@ -185,9 +184,24 @@ public:
fPool.reset(); fPool.reset();
} }


bool isEntireFileLoaded() const noexcept
{
return fEntireFileLoaded;
}

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

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

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


void setLoopingMode(const bool on) noexcept void setLoopingMode(const bool on) noexcept
@@ -200,27 +214,12 @@ public:
fNeedsRead = true; fNeedsRead = true;
} }


bool loadFilename(const char* const filename)
bool loadFilename(const char* const filename, const uint32_t sampleRate)
{ {
CARLA_SAFE_ASSERT_RETURN(! isThreadRunning(), false); CARLA_SAFE_ASSERT_RETURN(! isThreadRunning(), false);
CARLA_SAFE_ASSERT_RETURN(filename != nullptr && *filename != '\0', false); CARLA_SAFE_ASSERT_RETURN(filename != nullptr && *filename != '\0', false);


fPool.startFrame = 0;

// clear old data
if (fFilePtr != nullptr)
{
ad_close(fFilePtr);
fFilePtr = nullptr;
}
if (fPollTempData != nullptr)
{
delete[] fPollTempData;
fPollTempData = nullptr;
fPollTempSize = 0;
fMaxPlayerFrame = 0;
}

cleanup();
ad_clear_nfo(&fFileNfo); ad_clear_nfo(&fFileNfo);


// open new // open new
@@ -241,19 +240,36 @@ public:
if ((fFileNfo.channels == 1 || fFileNfo.channels == 2) && fFileNfo.frames > 0) if ((fFileNfo.channels == 1 || fFileNfo.channels == 2) && fFileNfo.frames > 0)
{ {
// valid // valid
const size_t pollTempSize = std::min(static_cast<uint>(fFileNfo.frames),
fPool.size * fFileNfo.channels);
const uint32_t fileNumFrames = static_cast<uint32_t>(fFileNfo.frames);
const uint32_t poolNumFrames = sampleRate * 5;


try {
fPollTempData = new float[pollTempSize];
} catch (...) {
if (fileNumFrames <= poolNumFrames)
{
// entire file fits in a small pool, lets read it now
fPool.create(fileNumFrames);
readEntireFileIntoPool();
ad_close(fFilePtr); ad_close(fFilePtr);
fFilePtr = nullptr; fFilePtr = nullptr;
return false;
}
else
{
// file is too big for our audio pool, we need an extra buffer
fPool.create(poolNumFrames);

const size_t pollTempSize = poolNumFrames * fFileNfo.channels;

try {
fPollTempData = new float[pollTempSize];
} catch (...) {
ad_close(fFilePtr);
fFilePtr = nullptr;
return false;
}

fPollTempSize = pollTempSize;
} }


fMaxPlayerFrame = static_cast<uint32_t>(fFileNfo.frames/fFileNfo.channels);
fPollTempSize = pollTempSize;
fNumFileFrames = fileNumFrames;


readPoll(); readPoll();
return true; return true;
@@ -268,60 +284,120 @@ public:
} }
} }


bool tryPutData(AudioFilePool& pool, const uint32_t framePos, const uint32_t frames)
void putAllData(AudioFilePool& pool)
{ {
CARLA_SAFE_ASSERT_RETURN(pool.size == fPool.size, false);
CARLA_SAFE_ASSERT_RETURN(pool.numFrames == fPool.numFrames,);


if (! fMutex.tryLock())
const CarlaMutexLocker cml(fMutex);

pool.startFrame = fPool.startFrame;
carla_copyFloats(pool.buffer[0], fPool.buffer[0], fPool.numFrames);
carla_copyFloats(pool.buffer[1], fPool.buffer[1], fPool.numFrames);
}

bool tryPutData(AudioFilePool& pool, const uint64_t framePos, const uint32_t frames)
{
CARLA_SAFE_ASSERT_RETURN(pool.numFrames == fPool.numFrames, false);

if (framePos >= fPool.numFrames)
return false; return false;


//if (pool.startFrame != fPool.startFrame || pool.buffer[0] != fPool.buffer[0] || pool.buffer[1] != fPool.buffer[1])
const CarlaMutexLocker cml(fMutex);
/*
const CarlaMutexTryLocker cmtl(fMutex);
if (! cmtl.wasLocked())
return false;
*/

pool.startFrame = fPool.startFrame;

carla_copyFloats(pool.buffer[0] + framePos, fPool.buffer[0] + framePos, frames);
carla_copyFloats(pool.buffer[1] + framePos, fPool.buffer[1] + framePos, frames);

return true;
}

void readEntireFileIntoPool()
{
CARLA_SAFE_ASSERT_RETURN(fPool.numFrames > 0,);

const uint numChannels = fFileNfo.channels;
const size_t bufferSize = fPool.numFrames * numChannels;
float* const buffer = (float*)std::malloc(bufferSize*sizeof(float));
CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,);

carla_zeroFloats(buffer, bufferSize);

ad_seek(fFilePtr, 0);
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>(bufferSize),
std::free(buffer));

{ {
pool.startFrame = fPool.startFrame;
// lock, and put data asap
const CarlaMutexLocker cml(fMutex);


if (frames == 0)
for (ssize_t i=0, j=0; j < rv; ++j)
{ {
carla_copyFloats(pool.buffer[0], fPool.buffer[0], fPool.size);
carla_copyFloats(pool.buffer[1], fPool.buffer[1], fPool.size);
}
else
{
CARLA_SAFE_ASSERT_UINT2_RETURN(framePos + frames < fPool.size, framePos, fPool.size, false);

carla_copyFloats(pool.buffer[0] + framePos, fPool.buffer[0] + framePos, frames);
carla_copyFloats(pool.buffer[1] + framePos, fPool.buffer[1] + framePos, frames);
if (numChannels == 1)
{
fPool.buffer[0][i] = buffer[j];
fPool.buffer[1][i] = buffer[j];
++i;
}
else
{
if (j % 2 == 0)
{
fPool.buffer[0][i] = buffer[j];
}
else
{
fPool.buffer[1][i] = buffer[j];
++i;
}
}
} }
} }


fMutex.unlock();
return true;
std::free(buffer);

fEntireFileLoaded = true;
} }


void readPoll() void readPoll()
{ {
if (fFileNfo.frames <= 0 || fFilePtr == nullptr)
if (fNumFileFrames == 0 || fFileNfo.channels == 0 || fFilePtr == nullptr)
{
carla_debug("R: no song loaded");
fNeedsRead = false;
return;
}
if (fPollTempData == nullptr)
{ {
carla_stderr("R: no song loaded");
carla_debug("R: nothing to poll");
fNeedsRead = false; fNeedsRead = false;
return; return;
} }


const uint64_t lastFrame = kPlayer->getLastFrame();
int32_t readFrameCheck;
uint64_t lastFrame = kPlayer->getLastFrame();
int64_t readFrameCheck;


if (lastFrame >= static_cast<uint64_t>(fFileNfo.frames))
if (lastFrame >= fNumFileFrames)
{ {
if (fLoopingMode) if (fLoopingMode)
{ {
const uint64_t readFrameCheckLoop = lastFrame % fMaxPlayerFrame;
const uint64_t readFrameCheckLoop = lastFrame % fNumFileFrames;
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");
readFrameCheck = static_cast<int32_t>(readFrameCheckLoop);
readFrameCheck = static_cast<int64_t>(readFrameCheckLoop);
} }
else else
{ {
carla_stderr("R: transport out of bounds");
carla_debug("R: transport out of bounds");
fNeedsRead = false; fNeedsRead = false;
return; return;
} }
@@ -329,18 +405,20 @@ public:
else else
{ {
CARLA_SAFE_ASSERT_RETURN(lastFrame < INT32_MAX,); CARLA_SAFE_ASSERT_RETURN(lastFrame < INT32_MAX,);
readFrameCheck = static_cast<int32_t>(lastFrame);
readFrameCheck = static_cast<int64_t>(lastFrame);
} }


const int32_t readFrame = readFrameCheck;
const int64_t readFrame = readFrameCheck;


// temp data buffer // temp data buffer
carla_zeroFloats(fPollTempData, fPollTempSize); carla_zeroFloats(fPollTempData, fPollTempSize);


{ {
carla_debug("R: poll data - reading at %li:%02li",
readFrame/static_cast<int32_t>(fPool.sampleRate)/60,
(readFrame/static_cast<int32_t>(fPool.sampleRate)) % 60);
#if 0
const int32_t sampleRate = 44100;
carla_debug("R: poll data - reading at frame %li, time %li:%02li, lastFrame %li",
readFrame, readFrame/sampleRate/60, (readFrame/sampleRate) % 60, lastFrame);
#endif


ad_seek(fFilePtr, readFrame); ad_seek(fFilePtr, readFrame);
size_t i = 0; size_t i = 0;
@@ -368,7 +446,7 @@ public:
const CarlaMutexLocker cml(fMutex); const CarlaMutexLocker cml(fMutex);


do { do {
for (; i < fPool.size && j < rv; ++j)
for (; i < fPool.numFrames && j < rv; ++j)
{ {
if (fFileNfo.channels == 1) if (fFileNfo.channels == 1)
{ {
@@ -390,7 +468,7 @@ public:
} }
} }


if (i >= fPool.size)
if (i >= fPool.numFrames)
break; break;


if (rv == fFileNfo.frames) if (rv == fFileNfo.frames)
@@ -403,12 +481,12 @@ public:
{ {
carla_debug("read break, not enough space"); carla_debug("read break, not enough space");


carla_zeroFloats(fPool.buffer[0] + i, fPool.size - i);
carla_zeroFloats(fPool.buffer[1] + i, fPool.size - i);
carla_zeroFloats(fPool.buffer[0] + i, fPool.numFrames - i);
carla_zeroFloats(fPool.buffer[1] + i, fPool.numFrames - i);
break; break;
} }


} while (i < fPool.size);
} while (i < fPool.numFrames);


fPool.startFrame = lastFrame; fPool.startFrame = lastFrame;
} }
@@ -419,12 +497,14 @@ public:
protected: protected:
void run() override void run() override
{ {
const uint64_t numFramesNearEnd = fPool.numFrames*3/4;
uint64_t lastFrame;

while (! fQuitNow) while (! fQuitNow)
{ {
const uint64_t lastFrame = kPlayer->getLastFrame();
const uint64_t loopedFrame = fLoopingMode ? lastFrame % fMaxPlayerFrame : lastFrame;
lastFrame = kPlayer->getLastFrame();


if (fNeedsRead || lastFrame < fPool.startFrame || (lastFrame - fPool.startFrame >= fPool.size*3/4 && loopedFrame < fMaxPlayerFrame))
if (fNeedsRead || lastFrame < fPool.startFrame || lastFrame - fPool.startFrame >= numFramesNearEnd)
readPoll(); readPoll();


carla_msleep(50); carla_msleep(50);
@@ -434,14 +514,15 @@ protected:
private: private:
AbstractAudioPlayer* const kPlayer; AbstractAudioPlayer* const kPlayer;


bool fEntireFileLoaded;
bool fLoopingMode; bool fLoopingMode;
bool fNeedsRead;
bool fQuitNow;
volatile bool fNeedsRead;
volatile bool fQuitNow;


void* fFilePtr; void* fFilePtr;
ADInfo fFileNfo; ADInfo fFileNfo;


uint32_t fMaxPlayerFrame;
uint32_t fNumFileFrames;


float* fPollTempData; float* fPollTempData;
size_t fPollTempSize; size_t fPollTempSize;


+ 83
- 46
source/native-plugins/audio-file.cpp View File

@@ -34,16 +34,13 @@ public:
fLastFrame(0), fLastFrame(0),
fMaxFrame(0), fMaxFrame(0),
fPool(), fPool(),
fThread(this, static_cast<uint32_t>(getSampleRate())),
fInlineDisplay()
{
fPool.create(static_cast<uint32_t>(getSampleRate()));
}
fThread(this),
fInlineDisplay() {}


~AudioFilePlugin() override ~AudioFilePlugin() override
{ {
fPool.destroy();
fThread.stopNow(); fThread.stopNow();
fPool.destroy();
} }


uint64_t getLastFrame() const override uint64_t getLastFrame() const override
@@ -140,58 +137,29 @@ protected:
if (! timePos->playing) if (! timePos->playing)
{ {
//carla_stderr("P: not playing"); //carla_stderr("P: not playing");
fLastFrame = timePos->frame;

if (timePos->frame == 0 && fLastFrame > 0) if (timePos->frame == 0 && fLastFrame > 0)
fThread.setNeedsRead(); fThread.setNeedsRead();


fLastFrame = timePos->frame;
carla_zeroFloats(out1, frames); carla_zeroFloats(out1, frames);
carla_zeroFloats(out2, frames); carla_zeroFloats(out2, frames);
return; return;
} }


// out of reach // out of reach
if (timePos->frame + frames < fPool.startFrame || (timePos->frame >= fMaxFrame && !fLoopMode))
if ((timePos->frame < fPool.startFrame || timePos->frame >= fMaxFrame) && !fLoopMode)
{ {
if (fLoopMode) {
carla_stderr("P: out of reach");
}

fLastFrame = timePos->frame;

if (timePos->frame + frames < fPool.startFrame)
if (timePos->frame < fPool.startFrame)
fThread.setNeedsRead(); fThread.setNeedsRead();


fLastFrame = timePos->frame;
carla_zeroFloats(out1, frames); carla_zeroFloats(out1, frames);
carla_zeroFloats(out2, frames); carla_zeroFloats(out2, frames);
return;
}

const uint32_t poolSize = fPool.size;
float* const bufferL = fPool.buffer[0];
float* const bufferR = fPool.buffer[1];

int64_t poolFrame = static_cast<int64_t>(timePos->frame - fPool.startFrame);

if (poolFrame >= 0 && poolFrame < poolSize && fThread.tryPutData(fPool, static_cast<uint32_t>(poolFrame), frames))
{
const uint32_t framesToCopy = std::min(frames, static_cast<uint32_t>(poolSize - poolFrame));
carla_copyFloats(out1, bufferL + poolFrame, framesToCopy);
carla_copyFloats(out2, bufferR + poolFrame, framesToCopy);

if (const uint32_t remainingFrames = frames - framesToCopy)
{
carla_zeroFloats(out1 + framesToCopy, remainingFrames);
carla_zeroFloats(out2 + framesToCopy, remainingFrames);
}

carla_zeroFloats(bufferL + poolFrame, framesToCopy);
carla_zeroFloats(bufferR + poolFrame, framesToCopy);


if (fInlineDisplay.writtenValues < 32) if (fInlineDisplay.writtenValues < 32)
{ {
fInlineDisplay.lastValuesL[fInlineDisplay.writtenValues] = carla_findMaxNormalizedFloat(out1, frames);
fInlineDisplay.lastValuesR[fInlineDisplay.writtenValues] = carla_findMaxNormalizedFloat(out2, frames);
fInlineDisplay.lastValuesL[fInlineDisplay.writtenValues] = 0.0f;
fInlineDisplay.lastValuesR[fInlineDisplay.writtenValues] = 0.0f;
++fInlineDisplay.writtenValues; ++fInlineDisplay.writtenValues;
} }


@@ -200,11 +168,73 @@ protected:
fInlineDisplay.pending = true; fInlineDisplay.pending = true;
hostQueueDrawInlineDisplay(); hostQueueDrawInlineDisplay();
} }
return;
}

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

for (uint32_t framesDone=0, framesToDo=frames, remainingFrames; framesDone < frames;)
{
if (targetStartFrame + framesToDo <= fMaxFrame)
{
// everything fits together
carla_copyFloats(out1+framesDone, fPool.buffer[0]+targetStartFrame, framesToDo);
carla_copyFloats(out2+framesDone, fPool.buffer[1]+targetStartFrame, framesToDo);
break;
}

remainingFrames = std::min(fMaxFrame - targetStartFrame, framesToDo);
carla_copyFloats(out1+framesDone, fPool.buffer[0]+targetStartFrame, remainingFrames);
carla_copyFloats(out2+framesDone, fPool.buffer[1]+targetStartFrame, remainingFrames);
framesDone += remainingFrames;
framesToDo -= remainingFrames;

if (! fLoopMode)
{
// not looping, stop here
if (framesToDo != 0)
{
carla_zeroFloats(out1+framesDone, framesToDo);
carla_zeroFloats(out2+framesDone, framesToDo);
}
break;
}

// reset for next loop
targetStartFrame = 0;
}
} }
else else
{ {
carla_zeroFloats(out1, frames);
carla_zeroFloats(out2, frames);
// NOTE: timePos->frame is always >= fPool.startFrame
const uint64_t poolStartFrame = timePos->frame - fThread.getPoolStartFrame();

if (fThread.tryPutData(fPool, poolStartFrame, frames))
{
carla_copyFloats(out1, fPool.buffer[0]+poolStartFrame, frames);
carla_copyFloats(out2, fPool.buffer[1]+poolStartFrame, frames);
}
else
{
carla_zeroFloats(out1, frames);
carla_zeroFloats(out2, frames);
}
}

if (fInlineDisplay.writtenValues < 32)
{
fInlineDisplay.lastValuesL[fInlineDisplay.writtenValues] = carla_findMaxNormalizedFloat(out1, frames);
fInlineDisplay.lastValuesR[fInlineDisplay.writtenValues] = carla_findMaxNormalizedFloat(out2, frames);
++fInlineDisplay.writtenValues;
}

if (! fInlineDisplay.pending)
{
fInlineDisplay.pending = true;
hostQueueDrawInlineDisplay();
} }


fLastFrame = timePos->frame; fLastFrame = timePos->frame;
@@ -338,7 +368,7 @@ private:
bool fLoopMode; bool fLoopMode;
bool fDoProcess; bool fDoProcess;


uint64_t fLastFrame;
volatile uint64_t fLastFrame;
uint32_t fMaxFrame; uint32_t fMaxFrame;


AudioFilePool fPool; AudioFilePool fPool;
@@ -384,6 +414,7 @@ private:
carla_debug("AudioFilePlugin::loadFilename(\"%s\")", filename); carla_debug("AudioFilePlugin::loadFilename(\"%s\")", filename);


fThread.stopNow(); fThread.stopNow();
fPool.destroy();


if (filename == nullptr || *filename == '\0') if (filename == nullptr || *filename == '\0')
{ {
@@ -392,10 +423,16 @@ private:
return; return;
} }


if (fThread.loadFilename(filename))
if (fThread.loadFilename(filename, static_cast<uint32_t>(getSampleRate())))
{ {
fThread.startNow();
fPool.create(fThread.getPoolNumFrames());
fMaxFrame = fThread.getMaxFrame(); fMaxFrame = fThread.getMaxFrame();

if (fThread.isEntireFileLoaded())
fThread.putAllData(fPool);
else
fThread.startNow();

fDoProcess = true; fDoProcess = true;
} }
else else


Loading…
Cancel
Save