Browse Source

audiofile: use host idle to read file, instead of custom thread

tags/v2.3.0-RC1
falkTX 3 years ago
parent
commit
c41f73f437
2 changed files with 74 additions and 81 deletions
  1. +38
    -64
      source/native-plugins/audio-base.hpp
  2. +36
    -17
      source/native-plugins/audio-file.cpp

+ 38
- 64
source/native-plugins/audio-base.hpp View File

@@ -99,16 +99,14 @@ struct AudioFilePool {
CARLA_DECLARE_NON_COPY_STRUCT(AudioFilePool)
};

class AudioFileThread : public CarlaThread
class AudioFileReader
{
public:
AudioFileThread()
: CarlaThread("AudioFileThread"),
fEntireFileLoaded(false),
AudioFileReader()
: fEntireFileLoaded(false),
fLoopingMode(true),
fNeedsFrame(0),
fNeedsRead(false),
fQuitNow(true),
fFilePtr(nullptr),
fFileNfo(),
fMaxFrame(0),
@@ -118,9 +116,9 @@ public:
fResampleTempData(nullptr),
fResampleTempSize(0),
fPool(),
fMutex(),
fSignal(),
fResampler()
fResampler(),
fPoolMutex(),
fReaderMutex()
{
static bool adInitiated = false;

@@ -133,11 +131,8 @@ public:
ad_clear_nfo(&fFileNfo);
}

~AudioFileThread() override
~AudioFileReader()
{
CARLA_ASSERT(fQuitNow);
CARLA_ASSERT(! isThreadRunning());

cleanup();
}

@@ -168,27 +163,14 @@ public:
fPool.destroy();
}

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

fNeedsFrame = 0;
fNeedsRead = false;
fQuitNow = false;
startThread();
}
const CarlaMutexLocker cml1(fPoolMutex);
const CarlaMutexLocker cml2(fReaderMutex);

void stopNow()
{
fNeedsFrame = 0;
fNeedsRead = false;
fQuitNow = true;

fSignal.signal();
stopThread(1000);

const CarlaMutexLocker cml(fMutex);
fPool.reset();
}

@@ -224,14 +206,14 @@ public:

fNeedsFrame = frame;
fNeedsRead = true;
fSignal.signal();
}

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

const CarlaMutexLocker cml(fReaderMutex);

cleanup();
ad_clear_nfo(&fFileNfo);

@@ -316,7 +298,7 @@ public:
? static_cast<uint32_t>(static_cast<double>(fileNumFrames) * fResampleRatio + 0.5)
: fileNumFrames;

readPoll();
fNeedsRead = true;
return true;
}
else
@@ -333,14 +315,14 @@ public:
{
CARLA_SAFE_ASSERT_RETURN(pool.numFrames == fPool.numFrames,);

const CarlaMutexLocker cml(fMutex);
const CarlaMutexLocker cml(fPoolMutex);

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(float* const out1, float* const out2, uint64_t framePos, const uint32_t frames)
bool tryPutData(float* const out1, float* const out2, uint64_t framePos, const uint32_t frames, bool& needsRead)
{
CARLA_SAFE_ASSERT_RETURN(fPool.numFrames != 0, false);

@@ -356,9 +338,9 @@ public:
const uint64_t numFramesNearEnd = fPool.numFrames*3/4;

#if 1
const CarlaMutexLocker cml(fMutex);
const CarlaMutexLocker cml(fPoolMutex);
#else
const CarlaMutexTryLocker cmtl(fMutex);
const CarlaMutexTryLocker cmtl(fPoolMutex);
if (! cmtl.wasLocked())
{
for (int i=0; i<5; ++i)
@@ -376,6 +358,7 @@ public:
{
if (fPool.startFrame + fPool.numFrames <= fMaxFrame)
{
needsRead = true;
setNeedsRead(framePos);
return false;
}
@@ -384,6 +367,7 @@ public:

if (frameDiff + frames >= fPool.numFrames)
{
needsRead = true;
setNeedsRead(framePos);
return false;
}
@@ -397,6 +381,7 @@ public:

if (frameDiff + frames >= fPool.numFrames)
{
needsRead = true;
setNeedsRead(framePos);
return false;
}
@@ -406,7 +391,10 @@ public:
}

if (frameDiff > numFramesNearEnd)
{
needsRead = true;
setNeedsRead(framePos + frames);
}

return true;
}
@@ -452,17 +440,16 @@ public:

{
// lock, and put data asap
const CarlaMutexLocker cml(fMutex);
const CarlaMutexLocker cml(fPoolMutex);

for (ssize_t i=0, j=0; j < rv; ++j)
if (numChannels == 1)
{
if (numChannels == 1)
{
fPool.buffer[0][i] = rbuffer[j];
fPool.buffer[1][i] = rbuffer[j];
++i;
}
else
for (ssize_t i=0, j=0; j < rv; ++i, ++j)
fPool.buffer[0][i] = fPool.buffer[1][i] = rbuffer[j];
}
else
{
for (ssize_t i=0, j=0; j < rv; ++j)
{
if (j % 2 == 0)
{
@@ -487,6 +474,8 @@ public:

void readPoll()
{
const CarlaMutexLocker cml(fReaderMutex);

if (fMaxFrame == 0 || fFileNfo.channels == 0 || fFilePtr == nullptr)
{
carla_debug("R: no song loaded");
@@ -589,7 +578,7 @@ public:
}

// lock, and put data asap
const CarlaMutexLocker cml(fMutex);
const CarlaMutexLocker cml(fPoolMutex);

do {
if (isMonoFile)
@@ -639,27 +628,11 @@ public:
fNeedsRead = false;
}

protected:
void run() override
{
while (! fQuitNow)
{
if (fNeedsRead)
readPoll();

if (fQuitNow)
break;

fSignal.wait();
}
}

private:
bool fEntireFileLoaded;
bool fLoopingMode;
volatile uint64_t fNeedsFrame;
volatile bool fNeedsRead;
volatile bool fQuitNow;

void* fFilePtr;
ADInfo fFileNfo;
@@ -674,11 +647,12 @@ private:
size_t fResampleTempSize;

AudioFilePool fPool;
CarlaMutex fMutex;
CarlaSignal fSignal;
Resampler fResampler;

CARLA_DECLARE_NON_COPY_STRUCT(AudioFileThread)
CarlaMutex fPoolMutex;
CarlaMutex fReaderMutex;

CARLA_DECLARE_NON_COPY_STRUCT(AudioFileReader)
};

#endif // AUDIO_BASE_HPP_INCLUDED

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

@@ -57,9 +57,10 @@ public:
fLoopMode(true),
fDoProcess(false),
fWasPlayingBefore(false),
fNeedsFileRead(false),
fMaxFrame(0),
fPool(),
fThread(),
fReader(),
fPrograms(hostGetFilePath("audio"), audiofilesWildcard)
#ifndef __MOD_DEVICES__
, fInlineDisplay()
@@ -69,7 +70,7 @@ public:

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

@@ -126,7 +127,7 @@ protected:
return;

fLoopMode = b;
fThread.setLoopingMode(b);
fReader.setLoopingMode(b);
}

void setCustomData(const char* const key, const char* const value) override
@@ -148,6 +149,7 @@ protected:

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

if (! fDoProcess)
{
@@ -162,7 +164,7 @@ protected:
{
// carla_stderr("P: not playing");
if (timePos->frame == 0 && fWasPlayingBefore)
fThread.setNeedsRead(timePos->frame);
fReader.setNeedsRead(timePos->frame);

carla_zeroFloats(out1, frames);
carla_zeroFloats(out2, frames);
@@ -178,7 +180,11 @@ protected:
if ((timePos->frame < fPool.startFrame || timePos->frame >= fMaxFrame) && !fLoopMode)
{
if (timePos->frame < fPool.startFrame)
fThread.setNeedsRead(timePos->frame);
{
needsIdleRequest = true;
fNeedsFileRead = true;
fReader.setNeedsRead(timePos->frame);
}

carla_zeroFloats(out1, frames);
carla_zeroFloats(out2, frames);
@@ -192,14 +198,18 @@ protected:
}
if (fInlineDisplay.pending == InlineDisplayNotPending)
{
needsIdleRequest = true;
fInlineDisplay.pending = InlineDisplayNeedRequest;
hostRequestIdle();
}
#endif

if (needsIdleRequest)
hostRequestIdle();

return;
}

if (fThread.isEntireFileLoaded())
if (fReader.isEntireFileLoaded())
{
// NOTE: timePos->frame is always < fMaxFrame (or looping)
uint32_t targetStartFrame = static_cast<uint32_t>(fLoopMode ? timePos->frame % fMaxFrame : timePos->frame);
@@ -237,11 +247,13 @@ protected:
}
else
{
if (! fThread.tryPutData(out1, out2, timePos->frame, frames))
if (! fReader.tryPutData(out1, out2, timePos->frame, frames, needsIdleRequest))
{
carla_zeroFloats(out1, frames);
carla_zeroFloats(out2, frames);
}
if (needsIdleRequest)
fNeedsFileRead = true;
}

#ifndef __MOD_DEVICES__
@@ -253,10 +265,13 @@ protected:
}
if (fInlineDisplay.pending == InlineDisplayNotPending)
{
needsIdleRequest = true;
fInlineDisplay.pending = InlineDisplayNeedRequest;
hostRequestIdle();
}
#endif

if (needsIdleRequest)
hostRequestIdle();
}

// -------------------------------------------------------------------
@@ -288,6 +303,9 @@ protected:
{
NativePluginWithMidiPrograms<FileAudio>::idle();

if (fNeedsFileRead)
fReader.readPoll();

#ifndef __MOD_DEVICES__
if (fInlineDisplay.pending == InlineDisplayNeedRequest)
{
@@ -415,11 +433,12 @@ private:
bool fLoopMode;
bool fDoProcess;
bool fWasPlayingBefore;
bool fNeedsFileRead;

uint32_t fMaxFrame;

AudioFilePool fPool;
AudioFileThread fThread;
AudioFileReader fReader;

NativeMidiPrograms fPrograms;

@@ -464,7 +483,7 @@ private:
CARLA_ASSERT(filename != nullptr);
carla_debug("AudioFilePlugin::loadFilename(\"%s\")", filename);

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

if (filename == nullptr || *filename == '\0')
@@ -474,15 +493,15 @@ private:
return;
}

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

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

fDoProcess = true;
}


Loading…
Cancel
Save