Browse Source

Start rework of audiofile buffering code

Signed-off-by: falkTX <falktx@falktx.com>
fix-audiofile-buffering
falkTX 1 year ago
parent
commit
779d4e3b3e
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
2 changed files with 1081 additions and 973 deletions
  1. +706
    -653
      source/native-plugins/audio-base.hpp
  2. +375
    -320
      source/native-plugins/audio-file.cpp

+ 706
- 653
source/native-plugins/audio-base.hpp
File diff suppressed because it is too large
View File


+ 375
- 320
source/native-plugins/audio-file.cpp View File

@@ -1,6 +1,6 @@
/*
* Carla Native Plugins
* Copyright (C) 2013-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2013-2023 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -20,37 +20,37 @@

#include "audio-base.hpp"

static const char* const audiofilesWildcard =
#ifdef HAVE_SNDFILE
"*.aif;*.aifc;*.aiff;*.au;*.bwf;*.flac;*.htk;*.iff;*.mat4;*.mat5;*.oga;*.ogg;*.opus;"
"*.paf;*.pvf;*.pvf5;*.sd2;*.sf;*.snd;*.svx;*.vcc;*.w64;*.wav;*.xi;"
#endif
#ifdef HAVE_FFMPEG
"*.3g2;*.3gp;*.aac;*.ac3;*.amr;*.ape;*.mp2;*.mp3;*.mpc;*.wma;"
# ifndef HAVE_SNDFILE
"*.flac;*.oga;*.ogg;*.w64;*.wav;"
# endif
#else
"*.mp3;"
#endif
;

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

#ifndef __MOD_DEVICES__
class AudioFilePlugin : public NativePluginWithMidiPrograms<FileAudio>
#else
class AudioFilePlugin : public NativePluginClass
#endif
{
public:
#ifndef __MOD_DEVICES__
typedef enum _PendingInlineDisplay
# ifdef CARLA_PROPER_CPP11_SUPPORT
: uint8_t
# endif
{
#ifndef __MOD_DEVICES__
static constexpr const char* const audiofilesWildcard =
#ifdef HAVE_SNDFILE
"*.aif;*.aifc;*.aiff;*.au;*.bwf;*.flac;*.htk;*.iff;*.mat4;*.mat5;*.oga;*.ogg;*.opus;"
"*.paf;*.pvf;*.pvf5;*.sd2;*.sf;*.snd;*.svx;*.vcc;*.w64;*.wav;*.xi;"
#endif
#ifdef HAVE_FFMPEG
"*.3g2;*.3gp;*.aac;*.ac3;*.amr;*.ape;*.mp2;*.mp3;*.mpc;*.wma;"
#ifndef HAVE_SNDFILE
"*.flac;*.oga;*.ogg;*.w64;*.wav;"
#endif
#else
"*.mp3;"
#endif
;

enum PendingInlineDisplay : uint8_t {
InlineDisplayNotPending,
InlineDisplayNeedRequest,
InlineDisplayRequesting
} PendingInlineDisplay;
#endif
};
#endif

enum Parameters {
kParameterLooping,
@@ -68,42 +68,35 @@ public:
};

AudioFilePlugin(const NativeHostDescriptor* const host)
: NativePluginWithMidiPrograms<FileAudio>(host, fPrograms, 2),
fLoopMode(true),
#ifdef __MOD_DEVICES__
fHostSync(false),
#else
fHostSync(true),
#endif
fEnabled(true),
fDoProcess(false),
fWasPlayingBefore(false),
fNeedsFileRead(false),
fEntireFileLoaded(false),
fMaxFrame(0),
fInternalTransportFrame(0),
fLastPosition(0.0f),
fLastPoolFill(0.0f),
fVolume(1.0f),
fPool(),
fReader(),
fFilename(),
fPrograms(hostGetFilePath("audio"), audiofilesWildcard),
fPreviewData()
#ifndef __MOD_DEVICES__
, fInlineDisplay()
#endif
#ifndef __MOD_DEVICES__
: NativePluginWithMidiPrograms<FileAudio>(host, fPrograms, 3),
fPrograms(hostGetFilePath("audio"), audiofilesWildcard)
#else
: NativePluginClass(host)
#endif
// fWasPlayingBefore(false),
// fNeedsFileRead(false),
// fEntireFileLoaded(false),
// fMaxFrame(0),
// fLastPoolFill(0.0f),
// fPool(),
// fReader(),
// fFilename(),
// fPreviewData()
// #ifndef __MOD_DEVICES__
// , fInlineDisplay()
// #endif
{
}

~AudioFilePlugin() override
{
fReader.destroy();
fPool.destroy();
// fReader.destroy();
// fPool.destroy();
}

protected:
// -------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------------------
// Plugin parameter calls

uint32_t getParameterCount() const override
@@ -139,11 +132,11 @@ protected:
param.hints = static_cast<NativeParameterHints>(NATIVE_PARAMETER_IS_AUTOMATABLE|
NATIVE_PARAMETER_IS_ENABLED|
NATIVE_PARAMETER_IS_BOOLEAN);
#ifdef __MOD_DEVICES__
#ifdef __MOD_DEVICES__
param.ranges.def = 0.0f;
#else
#else
param.ranges.def = 1.0f;
#endif
#endif
param.ranges.min = 0.0f;
param.ranges.max = 1.0f;
break;
@@ -253,15 +246,15 @@ protected:
case kParameterLooping:
return fLoopMode ? 1.0f : 0.0f;
case kParameterHostSync:
return fHostSync ? 1.0f : 0.0f;
return fHostSync ? 1.f : 0.f;
case kParameterEnabled:
return fEnabled ? 1.0f : 0.0f;
return fEnabled ? 1.f : 0.f;
case kParameterVolume:
return fVolume * 100.0f;
return fVolume * 100.f;
case kParameterInfoPosition:
return fLastPosition;
case kParameterInfoPoolFill:
return fLastPoolFill;
// case kParameterInfoPoolFill:
// return fLastPoolFill;
case kParameterInfoBitRate:
return static_cast<float>(fReader.getCurrentBitRate());
}
@@ -277,24 +270,21 @@ protected:
case kParameterInfoSampleRate:
return static_cast<float>(nfo.sample_rate);
case kParameterInfoLength:
return static_cast<float>(nfo.length)/1000.0f;
default:
return 0.0f;
return static_cast<float>(nfo.length)/1000.f;
}
}

// -------------------------------------------------------------------
// Plugin state calls
return 0.f;
}

void setParameterValue(const uint32_t index, const float value) override
{
if (index == kParameterVolume)
{
fVolume = value / 100.0f;
fVolume = value / 100.f;
return;
}

const bool b = (value > 0.5f);
const bool b = value > 0.5f;

switch (index)
{
@@ -302,7 +292,7 @@ protected:
if (fLoopMode != b)
{
fLoopMode = b;
fReader.setLoopingMode(b);
// fReader.setLoopingMode(b);
}
break;
case kParameterHostSync:
@@ -324,51 +314,69 @@ protected:
}
}

// ----------------------------------------------------------------------------------------------------------------
// Plugin state calls

void setCustomData(const char* const key, const char* const value) override
{
if (std::strcmp(key, "file") != 0)
return;

#ifndef __MOD_DEVICES__
invalidateNextFilename();
#endif
loadFilename(value);
}

// -------------------------------------------------------------------
#ifndef __MOD_DEVICES__
void setStateFromFile(const char* const filename) override
{
loadFilename(filename);
}
#endif

// ----------------------------------------------------------------------------------------------------------------
// Plugin process calls

#ifndef __MOD_DEVICES__
void process2(const float* const*, float** const outBuffer, const uint32_t frames,
const NativeMidiEvent*, uint32_t) override
#else
void process(const float* const*, float** const outBuffer, const uint32_t frames,
const NativeMidiEvent*, uint32_t) override
#endif
{
float* const out1 = outBuffer[0];
float* const out2 = outBuffer[1];
float* const playCV = outBuffer[2];

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

if (! fDoProcess)
{
// carla_stderr("P: no process");
carla_zeroFloats(out1, frames);
carla_zeroFloats(out2, frames);
carla_zeroFloats(playCV, frames);
fLastPosition = 0.0f;
return;
}

const bool loopMode = fLoopMode;
const float volume = fVolume;
// const bool loopMode = fLoopMode;
bool needsIdleRequest = false;
bool playing;
uint64_t frame;
uint64_t framePos;

if (fHostSync)
{
const NativeTimeInfo* const timePos = getTimeInfo();
playing = fEnabled && timePos->playing;
frame = timePos->frame;
framePos = timePos->frame;
}
else
{
playing = fEnabled;
frame = fInternalTransportFrame;
framePos = fInternalTransportFrame;

if (playing)
fInternalTransportFrame += frames;
@@ -377,143 +385,161 @@ protected:
// not playing
if (! playing)
{
// carla_stderr("P: not playing");
if (frame == 0 && fWasPlayingBefore)
fReader.setNeedsRead(frame);
// // carla_stderr("P: not playing");
// if (framePos == 0 && fWasPlayingBefore)
// fReader.setNeedsRead(framePos);

carla_zeroFloats(out1, frames);
carla_zeroFloats(out2, frames);
fWasPlayingBefore = false;
carla_zeroFloats(playCV, frames);
// fWasPlayingBefore = false;
return;
}
else
{
fWasPlayingBefore = true;
}

// out of reach
if ((frame < fPool.startFrame || frame >= fMaxFrame) && !loopMode)
{
if (frame < fPool.startFrame)
{
needsIdleRequest = true;
fNeedsFileRead = true;
fReader.setNeedsRead(frame);
}

carla_zeroFloats(out1, frames);
carla_zeroFloats(out2, frames);

#ifndef __MOD_DEVICES__
if (fInlineDisplay.writtenValues < 32)
{
fInlineDisplay.lastValuesL[fInlineDisplay.writtenValues] = 0.0f;
fInlineDisplay.lastValuesR[fInlineDisplay.writtenValues] = 0.0f;
++fInlineDisplay.writtenValues;
}
if (fInlineDisplay.pending == InlineDisplayNotPending)
{
needsIdleRequest = true;
fInlineDisplay.pending = InlineDisplayNeedRequest;
}
#endif

if (needsIdleRequest)
hostRequestIdle();

if (frame == 0)
fLastPosition = 0.0f;
else if (frame >= fMaxFrame)
fLastPosition = 100.0f;
else
fLastPosition = static_cast<float>(frame) / static_cast<float>(fMaxFrame) * 100.0f;
return;
}

if (fEntireFileLoaded)
{
// NOTE: frame is always < fMaxFrame (or looping)
uint32_t targetStartFrame = static_cast<uint32_t>(loopMode ? frame % fMaxFrame : 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 (! loopMode)
{
// not looping, stop here
if (framesToDo != 0)
{
carla_zeroFloats(out1+framesDone, framesToDo);
carla_zeroFloats(out2+framesDone, framesToDo);
}
break;
}

// reset for next loop
targetStartFrame = 0;
}

fLastPosition = static_cast<float>(targetStartFrame) / static_cast<float>(fMaxFrame) * 100.0f;
}
else
{
const bool offline = isOffline();

if (! fReader.tryPutData(fPool, out1, out2, frame, frames, loopMode, offline, needsIdleRequest))
{
carla_zeroFloats(out1, frames);
carla_zeroFloats(out2, frames);
}

if (needsIdleRequest)
{
fNeedsFileRead = true;
// else
// {
// fWasPlayingBefore = true;
// }

fLastPosition = fReader.tickFrames(outBuffer, 0, frames, framePos, fLoopMode, isOffline()) * 100.f;

// // out of reach
// if ((frame < fPool.startFrame || frame >= fMaxFrame) && !loopMode)
// {
// if (frame < fPool.startFrame)
// {
// needsIdleRequest = true;
// fNeedsFileRead = true;
// fReader.setNeedsRead(frame);
// }
//
// carla_zeroFloats(out1, frames);
// carla_zeroFloats(out2, frames);
// carla_zeroFloats(playCV, frames);
//
// #ifndef __MOD_DEVICES__
// if (fInlineDisplay.writtenValues < 32)
// {
// fInlineDisplay.lastValuesL[fInlineDisplay.writtenValues] = 0.0f;
// fInlineDisplay.lastValuesR[fInlineDisplay.writtenValues] = 0.0f;
// ++fInlineDisplay.writtenValues;
// }
// if (fInlineDisplay.pending == InlineDisplayNotPending)
// {
// needsIdleRequest = true;
// fInlineDisplay.pending = InlineDisplayNeedRequest;
// }
// #endif

// if (needsIdleRequest)
// hostRequestIdle();
//
// if (frame == 0)
// fLastPosition = 0.0f;
// else if (frame >= fMaxFrame)
// fLastPosition = 100.0f;
// else
// fLastPosition = static_cast<float>(frame) / static_cast<float>(fMaxFrame) * 100.0f;
// return;
// }

// if (fEntireFileLoaded)
// {
// // NOTE: frame is always < fMaxFrame (or looping)
// uint32_t targetStartFrame = static_cast<uint32_t>(loopMode ? frame % fMaxFrame : 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);
// carla_fillFloatsWithSingleValue(playCV+framesDone, 10.f, 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);
// carla_fillFloatsWithSingleValue(playCV+framesDone, 10.f, remainingFrames);
// framesDone += remainingFrames;
// framesToDo -= remainingFrames;
//
// if (! loopMode)
// {
// // not looping, stop here
// if (framesToDo != 0)
// {
// carla_zeroFloats(out1+framesDone, framesToDo);
// carla_zeroFloats(out2+framesDone, framesToDo);
// carla_zeroFloats(playCV+framesDone, framesToDo);
// }
// break;
// }
//
// // reset for next loop
// targetStartFrame = 0;
// }

// fLastPosition = static_cast<float>(targetStartFrame) / static_cast<float>(fMaxFrame) * 100.0f;
// }
// else
// {
// const bool offline = isOffline();

// if (fReader.tryPutData(fPool, out1, out2, frame, frames, loopMode, offline, needsIdleRequest))
// {
// carla_fillFloatsWithSingleValue(playCV, 10.f, frames);
// }
// else
// {
// carla_zeroFloats(out1, frames);
// carla_zeroFloats(out2, frames);
// carla_zeroFloats(playCV, frames);
// }
//
// if (needsIdleRequest)
// {
// fNeedsFileRead = true;
//
// if (isOffline())
// {
// needsIdleRequest = false;
// fReader.readPoll();
//
// if (fReader.tryPutData(fPool, out1, out2, frame, frames, loopMode, offline, needsIdleRequest))
// {
// carla_fillFloatsWithSingleValue(playCV, 10.f, frames);
// }
// else
// {
// carla_zeroFloats(out1, frames);
// carla_zeroFloats(out2, frames);
// carla_zeroFloats(playCV, frames);
// }
//
// if (needsIdleRequest)
// fNeedsFileRead = true;
// }
// }
//
// const uint32_t modframe = static_cast<uint32_t>(frame % fMaxFrame);
// fLastPosition = static_cast<float>(modframe) / static_cast<float>(fMaxFrame) * 100.0f;
//
// if (modframe > fPool.startFrame)
// fLastPoolFill = static_cast<float>(modframe - fPool.startFrame) / static_cast<float>(fPool.numFrames) * 100.0f;
// else
// fLastPoolFill = 100.0f;
// }

if (isOffline())
{
needsIdleRequest = false;
fReader.readPoll();

if (! fReader.tryPutData(fPool, out1, out2, frame, frames, loopMode, offline, needsIdleRequest))
{
carla_zeroFloats(out1, frames);
carla_zeroFloats(out2, frames);
}

if (needsIdleRequest)
fNeedsFileRead = true;
}
}

const uint32_t modframe = static_cast<uint32_t>(frame % fMaxFrame);
fLastPosition = static_cast<float>(modframe) / static_cast<float>(fMaxFrame) * 100.0f;

if (modframe > fPool.startFrame)
fLastPoolFill = static_cast<float>(modframe - fPool.startFrame) / static_cast<float>(fPool.numFrames) * 100.0f;
else
fLastPoolFill = 100.0f;
}

if (carla_isNotZero(volume-1.0f))
const float volume = fVolume;
if (carla_isNotEqual(volume, 1.0f))
{
carla_multiply(out1, volume, frames);
carla_multiply(out2, volume, frames);
}

#ifndef __MOD_DEVICES__
#ifndef __MOD_DEVICES__
if (fInlineDisplay.writtenValues < 32)
{
fInlineDisplay.lastValuesL[fInlineDisplay.writtenValues] = carla_findMaxNormalizedFloat(out1, frames);
@@ -525,13 +551,13 @@ protected:
needsIdleRequest = true;
fInlineDisplay.pending = InlineDisplayNeedRequest;
}
#endif
#endif

if (needsIdleRequest)
hostRequestIdle();
}

// -------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------------------
// Plugin UI calls

void uiShow(const bool show) override
@@ -545,37 +571,38 @@ protected:
uiClosed();
}

// -------------------------------------------------------------------
// Plugin state calls

void setStateFromFile(const char* const filename) override
{
loadFilename(filename);
}

// -------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------------------
// Plugin dispatcher calls

void idle() override
{
#ifndef __MOD_DEVICES__
NativePluginWithMidiPrograms<FileAudio>::idle();

if (fNeedsFileRead)
{
fReader.readPoll();
fNeedsFileRead = false;
}

#ifndef __MOD_DEVICES__
if (fInlineDisplay.pending == InlineDisplayNeedRequest)
{
fInlineDisplay.pending = InlineDisplayRequesting;
hostQueueDrawInlineDisplay();
}
#endif
#endif

// if (fNeedsFileRead)
// {
// fReader.readPoll();
// fNeedsFileRead = false;
// }
}

#ifndef __MOD_DEVICES__
void sampleRateChanged(double) override
{
if (char* const filename = fFilename.releaseBufferPointer())
{
loadFilename(filename);
std::free(filename);
}
}

#ifndef __MOD_DEVICES__
const NativeInlineDisplayImageSurface* renderInlineDisplay(const uint32_t rwidth, const uint32_t height) override
{
CARLA_SAFE_ASSERT_RETURN(height > 4, nullptr);
@@ -685,62 +712,46 @@ protected:
fInlineDisplay.pending = InlineDisplayNotPending;
return (NativeInlineDisplayImageSurface*)(NativeInlineDisplayImageSurfaceCompat*)&fInlineDisplay;
}
#endif

void sampleRateChanged(double) override
{
if (char* const filename = fFilename.releaseBufferPointer())
{
loadFilename(filename);
std::free(filename);
}
}
#endif

// -------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------------------

private:
bool fLoopMode;
bool fHostSync;
bool fEnabled;
bool fDoProcess;
bool fWasPlayingBefore;
volatile bool fNeedsFileRead;

bool fEntireFileLoaded;
uint32_t fMaxFrame;
uint32_t fInternalTransportFrame;
float fLastPosition;
float fLastPoolFill;
float fVolume;

AudioFilePool fPool;
bool fLoopMode = true;
#ifdef __MOD_DEVICES__
bool fHostSync = false;
#else
bool fHostSync = true;
#endif
bool fEnabled = true;
bool fDoProcess = false;
// bool fWasPlayingBefore;
// volatile bool fNeedsFileRead;
//
// bool fEntireFileLoaded;
// uint32_t fMaxFrame;
uint32_t fInternalTransportFrame = 0;
float fLastPosition = 0.f;
// float fLastPoolFill;
float fVolume = 1.f;

// AudioFilePool fPool;
AudioFileReader fReader;
CarlaString fFilename;

float fPreviewData[108] = {};

#ifndef __MOD_DEVICES__
NativeMidiPrograms fPrograms;
float fPreviewData[108];

#ifndef __MOD_DEVICES__
struct InlineDisplay : NativeInlineDisplayImageSurfaceCompat {
float lastValuesL[32];
float lastValuesR[32];
volatile PendingInlineDisplay pending;
volatile uint8_t writtenValues;
float lastValuesL[32] = {};
float lastValuesR[32] = {};
volatile PendingInlineDisplay pending = InlineDisplayNotPending;
volatile uint8_t writtenValues = 0;

InlineDisplay()
: NativeInlineDisplayImageSurfaceCompat(),
# ifdef CARLA_PROPER_CPP11_SUPPORT
lastValuesL{0.0f},
lastValuesR{0.0f},
# endif
pending(InlineDisplayNotPending),
writtenValues(0)
{
# ifndef CARLA_PROPER_CPP11_SUPPORT
carla_zeroFloats(lastValuesL, 32);
carla_zeroFloats(lastValuesR, 32);
# endif
}
: NativeInlineDisplayImageSurfaceCompat() {}

~InlineDisplay()
{
@@ -754,86 +765,78 @@ private:
CARLA_DECLARE_NON_COPYABLE(InlineDisplay)
CARLA_PREVENT_HEAP_ALLOCATION
} fInlineDisplay;
#endif
#endif

void loadFilename(const char* const filename)
{
CARLA_ASSERT(filename != nullptr);
carla_debug("AudioFilePlugin::loadFilename(\"%s\")", filename);
carla_stdout("AudioFilePlugin::loadFilename(\"%s\")", filename);

fDoProcess = false;
fLastPoolFill = 0.0f;
fInternalTransportFrame = 0;
fPool.destroy();
// fLastPoolFill = 0.0f;
// fPool.destroy();
fReader.destroy();
fFilename.clear();

if (filename == nullptr || *filename == '\0')
{
fMaxFrame = 0;
// fMaxFrame = 0;
return;
}

const uint32_t previewDataSize = sizeof(fPreviewData)/sizeof(float);
constexpr uint32_t kPreviewDataLen = sizeof(fPreviewData)/sizeof(float);

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

if (fEntireFileLoaded)
{
fReader.putAndSwapAllData(fPool);
fLastPoolFill = 100.0f;
}
else
{
fReader.createSwapablePool(fPool);
fReader.readPoll();
}

// fEntireFileLoaded = fReader.isEntireFileLoaded();
// fMaxFrame = fReader.getMaxFrame();
//
// if (fEntireFileLoaded)
// {
// fReader.putAndSwapAllData(fPool);
// fLastPoolFill = 100.0f;
// }
// else
// {
// fReader.createSwapablePool(fPool);
// fReader.readPoll();
// }

fInternalTransportFrame = 0;
fDoProcess = true;
fFilename = filename;
hostSendPreviewBufferData('f', previewDataSize, fPreviewData);
hostSendPreviewBufferData('f', kPreviewDataLen, fPreviewData);
}
else
{
fEntireFileLoaded = false;
fMaxFrame = 0;
// fEntireFileLoaded = false;
// fMaxFrame = 0;
}
}

PluginClassEND(AudioFilePlugin)
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AudioFilePlugin)
};

// -----------------------------------------------------------------------
static const char* _get_buffer_port_name(NativePluginHandle, const uint32_t index, const bool isOutput)
{
if (!isOutput || index != 2)
return nullptr;

static const NativePluginDescriptor audiofileDesc = {
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
/* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_RTSAFE
|NATIVE_PLUGIN_HAS_UI
#ifndef __MOD_DEVICES__
|NATIVE_PLUGIN_HAS_INLINE_DISPLAY
#endif
|NATIVE_PLUGIN_REQUESTS_IDLE
|NATIVE_PLUGIN_NEEDS_UI_OPEN_SAVE
|NATIVE_PLUGIN_USES_TIME),
/* supports */ NATIVE_PLUGIN_SUPPORTS_NOTHING,
/* audioIns */ 0,
/* audioOuts */ 2,
/* midiIns */ 0,
/* midiOuts */ 0,
/* paramIns */ 1,
/* paramOuts */ 0,
/* name */ "Audio File",
/* label */ "audiofile",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
PluginDescriptorFILL(AudioFilePlugin)
return "Play status";
}

static const NativePortRange* _get_buffer_port_range(NativePluginHandle, const uint32_t index, const bool isOutput)
{
if (!isOutput || index != 2)
return nullptr;

static NativePortRange npr = { 0.f, 10.f };
return &npr;
}

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AudioFilePlugin)
};

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

CARLA_API_EXPORT
void carla_register_native_plugin_audiofile();
@@ -841,7 +844,59 @@ void carla_register_native_plugin_audiofile();
CARLA_API_EXPORT
void carla_register_native_plugin_audiofile()
{
static const NativePluginDescriptor audiofileDesc = {
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
/* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_RTSAFE
#ifndef __MOD_DEVICES__
|NATIVE_PLUGIN_HAS_INLINE_DISPLAY
#endif
|NATIVE_PLUGIN_HAS_UI
|NATIVE_PLUGIN_NEEDS_UI_OPEN_SAVE
|NATIVE_PLUGIN_REQUESTS_IDLE
|NATIVE_PLUGIN_USES_CONTROL_VOLTAGE
|NATIVE_PLUGIN_USES_TIME),
/* supports */ NATIVE_PLUGIN_SUPPORTS_NOTHING,
/* audioIns */ 0,
/* audioOuts */ 2,
/* midiIns */ 0,
/* midiOuts */ 0,
/* paramIns */ 1,
/* paramOuts */ 0,
/* name */ "Audio File",
/* label */ "audiofile",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
AudioFilePlugin::_instantiate,
AudioFilePlugin::_cleanup,
AudioFilePlugin::_get_parameter_count,
AudioFilePlugin::_get_parameter_info,
AudioFilePlugin::_get_parameter_value,
AudioFilePlugin::_get_midi_program_count,
AudioFilePlugin::_get_midi_program_info,
AudioFilePlugin::_set_parameter_value,
AudioFilePlugin::_set_midi_program,
AudioFilePlugin::_set_custom_data,
AudioFilePlugin::_ui_show,
AudioFilePlugin::_ui_idle,
AudioFilePlugin::_ui_set_parameter_value,
AudioFilePlugin::_ui_set_midi_program,
AudioFilePlugin::_ui_set_custom_data,
AudioFilePlugin::_activate,
AudioFilePlugin::_deactivate,
AudioFilePlugin::_process,
AudioFilePlugin::_get_state,
AudioFilePlugin::_set_state,
AudioFilePlugin::_dispatcher,
AudioFilePlugin::_render_inline_display,
/* cvIns */ 0,
/* cvOuts */ 1,
AudioFilePlugin::_get_buffer_port_name,
AudioFilePlugin::_get_buffer_port_range,
/* ui_width */ 0,
/* ui_height */ 0
};

carla_register_native_plugin(&audiofileDesc);
}

// -----------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------

Loading…
Cancel
Save