Browse Source

Rework of some latency and LADSPA code

tags/1.9.6
falkTX 10 years ago
parent
commit
5d10152aa8
13 changed files with 572 additions and 432 deletions
  1. +5
    -4
      source/backend/CarlaPlugin.hpp
  2. +16
    -4
      source/backend/engine/CarlaEngine.cpp
  3. +4
    -4
      source/backend/engine/CarlaEngineGraph.cpp
  4. +3
    -0
      source/backend/engine/CarlaEngineInternal.hpp
  5. +12
    -1
      source/backend/plugin/CarlaPlugin.cpp
  6. +10
    -0
      source/backend/plugin/CarlaPluginDSSI.cpp
  7. +69
    -65
      source/backend/plugin/CarlaPluginInternal.cpp
  8. +23
    -9
      source/backend/plugin/CarlaPluginInternal.hpp
  9. +410
    -339
      source/backend/plugin/CarlaPluginLADSPA.cpp
  10. +10
    -0
      source/backend/plugin/CarlaPluginLV2.cpp
  11. +4
    -0
      source/backend/plugin/CarlaPluginVST2.cpp
  12. +2
    -2
      source/native-plugins/bigmeter.cpp
  13. +4
    -4
      source/utils/CarlaMathUtils.hpp

+ 5
- 4
source/backend/CarlaPlugin.hpp View File

@@ -109,7 +109,7 @@ public:
/*!
* Get the plugin's options (currently in use).
*
* @see PluginOptions, getAvailableOptions() and setOption()
* @see PluginOptions, getOptionsAvailable() and setOption()
*/
uint getOptionsEnabled() const noexcept;

@@ -154,7 +154,7 @@ public:
/*!
* Get the plugin's latency, in sample frames.
*/
uint32_t getLatencyInFrames() const noexcept;
virtual uint32_t getLatencyInFrames() const noexcept;

// -------------------------------------------------------------------
// Information (count)
@@ -266,7 +266,7 @@ public:
* Get the complete plugin chunk data into @a dataPtr.
*
* @note Make sure to verify the plugin supports chunks before calling this function!
* \return The size of the chunk or 0 if invalid.
* @return The size of the chunk or 0 if invalid.
*
* @see setChunkData()
*/
@@ -326,6 +326,7 @@ public:

/*!
* Get the custom text of the parameter @a parameterId.
* @see PARAMETER_USES_CUSTOM_TEXT
*/
virtual void getParameterText(const uint32_t parameterId, char* const strBuf) const noexcept;

@@ -436,7 +437,7 @@ public:
/*!
* Set a plugin's option.
*
* @see getOptions() and getAvailableOptions()
* @see getOptions() and getOptionsAvailable()
*/
virtual void setOption(const uint option, const bool yesNo, const bool sendCallback);



+ 16
- 4
source/backend/engine/CarlaEngine.cpp View File

@@ -845,7 +845,7 @@ const char* CarlaEngine::getUniquePluginName(const char* const name) const
return sname.dup();
}

const size_t maxNameSize(carla_min<uint>(getMaxClientNameSize(), 0xff, 6) - 6); // 6 = strlen(" (10)") + 1
const std::size_t maxNameSize(carla_minWithBase<uint>(getMaxClientNameSize(), 0xff, 6U) - 6); // 6 = strlen(" (10)") + 1

if (maxNameSize == 0 || ! isRunning())
return sname.dup();
@@ -1454,7 +1454,11 @@ void CarlaEngine::bufferSizeChanged(const uint32_t newBufferSize)
carla_debug("CarlaEngine::bufferSizeChanged(%i)", newBufferSize);

#ifndef BUILD_BRIDGE
pData->graph.setBufferSize(newBufferSize);
if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK ||
pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
{
pData->graph.setBufferSize(newBufferSize);
}
#endif

for (uint i=0; i < pData->curPluginCount; ++i)
@@ -1473,7 +1477,11 @@ void CarlaEngine::sampleRateChanged(const double newSampleRate)
carla_debug("CarlaEngine::sampleRateChanged(%g)", newSampleRate);

#ifndef BUILD_BRIDGE
pData->graph.setSampleRate(newSampleRate);
if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK ||
pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
{
pData->graph.setSampleRate(newSampleRate);
}
#endif

for (uint i=0; i < pData->curPluginCount; ++i)
@@ -1492,7 +1500,11 @@ void CarlaEngine::offlineModeChanged(const bool isOfflineNow)
carla_debug("CarlaEngine::offlineModeChanged(%s)", bool2str(isOfflineNow));

#ifndef BUILD_BRIDGE
pData->graph.setOffline(isOfflineNow);
if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK ||
pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
{
pData->graph.setOffline(isOfflineNow);
}
#endif

for (uint i=0; i < pData->curPluginCount; ++i)


+ 4
- 4
source/backend/engine/CarlaEngineGraph.cpp View File

@@ -646,10 +646,10 @@ void RackGraph::process(CarlaEngine::ProtectedData* const data, const float* inB
if (oldAudioInCount > 0)
{
range = FloatVectorOperations::findMinAndMax(inBuf0, iframes);
pluginData.insPeak[0] = carla_max<float>(std::abs(range.getStart()), std::abs(range.getEnd()), 1.0f);
pluginData.insPeak[0] = carla_maxLimited<float>(std::abs(range.getStart()), std::abs(range.getEnd()), 1.0f);

range = FloatVectorOperations::findMinAndMax(inBuf1, iframes);
pluginData.insPeak[1] = carla_max<float>(std::abs(range.getStart()), std::abs(range.getEnd()), 1.0f);
pluginData.insPeak[1] = carla_maxLimited<float>(std::abs(range.getStart()), std::abs(range.getEnd()), 1.0f);
}
else
{
@@ -660,10 +660,10 @@ void RackGraph::process(CarlaEngine::ProtectedData* const data, const float* inB
if (plugin->getAudioOutCount() > 0)
{
range = FloatVectorOperations::findMinAndMax(outBuf[0], iframes);
pluginData.outsPeak[0] = carla_max<float>(std::abs(range.getStart()), std::abs(range.getEnd()), 1.0f);
pluginData.outsPeak[0] = carla_maxLimited<float>(std::abs(range.getStart()), std::abs(range.getEnd()), 1.0f);

range = FloatVectorOperations::findMinAndMax(outBuf[1], iframes);
pluginData.outsPeak[1] = carla_max<float>(std::abs(range.getStart()), std::abs(range.getEnd()), 1.0f);
pluginData.outsPeak[1] = carla_maxLimited<float>(std::abs(range.getStart()), std::abs(range.getEnd()), 1.0f);
}
else
{


+ 3
- 0
source/backend/engine/CarlaEngineInternal.hpp View File

@@ -33,6 +33,9 @@ CARLA_BACKEND_START_NAMESPACE
#define CARLA_SAFE_ASSERT_RETURN_ERR(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); setLastError(err); return false; }
#define CARLA_SAFE_ASSERT_RETURN_ERRN(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); setLastError(err); return nullptr; }

#define CARLA_SAFE_EXCEPTION_RETURN_ERR(excptMsg, errMsg) catch(...) { carla_safe_exception(excptMsg, __FILE__, __LINE__); setLastError(errMsg); return false; }
#define CARLA_SAFE_EXCEPTION_RETURN_ERRN(excptMsg, errMsg) catch(...) { carla_safe_exception(excptMsg, __FILE__, __LINE__); setLastError(errMsg); return nullptr; }

// -----------------------------------------------------------------------
// InternalEvents



+ 12
- 1
source/backend/plugin/CarlaPlugin.cpp View File

@@ -162,7 +162,7 @@ int64_t CarlaPlugin::getUniqueId() const noexcept

uint32_t CarlaPlugin::getLatencyInFrames() const noexcept
{
return pData->latency;
return 0;
}

// -------------------------------------------------------------------
@@ -1397,6 +1397,17 @@ void CarlaPlugin::idle()
#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
const bool sendOsc(pData->engine->isOscControlRegistered());
#endif
const uint32_t latency(getLatencyInFrames());

if (pData->latency.frames != latency)
{
carla_stdout("latency changed to %i", latency);

const ScopedSingleProcessLocker sspl(this, true);

pData->client->setLatency(latency);
pData->latency.recreateBuffers(pData->latency.channels, latency);
}

const CarlaMutexLocker sl(pData->postRtEvents.mutex);



+ 10
- 0
source/backend/plugin/CarlaPluginDSSI.cpp View File

@@ -681,6 +681,7 @@ public:
}
#endif

#if 0 // TODO
void idle() override
{
if (fLatencyChanged && fLatencyIndex != -1)
@@ -712,6 +713,7 @@ public:

CarlaPlugin::idle();
}
#endif

// -------------------------------------------------------------------
// Plugin state
@@ -1125,6 +1127,7 @@ public:
if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0))
pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;

#if 0 // TODO
// check latency
if (fLatencyIndex >= 0)
{
@@ -1193,6 +1196,7 @@ public:

fLatencyChanged = false;
}
#endif

bufferSizeChanged(pData->engine->getBufferSize());
reloadPrograms(true);
@@ -1389,11 +1393,13 @@ public:
}

#ifndef BUILD_BRIDGE
#if 0 // TODO
if (pData->latency > 0)
{
for (uint32_t i=0; i < pData->audioIn.count; ++i)
FloatVectorOperations::clear(pData->latencyBuffers[i], static_cast<int>(pData->latency));
}
#endif
#endif

pData->needsReset = false;
@@ -1775,6 +1781,7 @@ public:
} // End of Plugin processing (no events)

#ifndef BUILD_BRIDGE
#if 0 // TODO
// --------------------------------------------------------------------------------------------------------
// Latency, save values for next callback

@@ -1803,6 +1810,7 @@ public:
}
}
}
#endif

// --------------------------------------------------------------------------------------------------------
// Control Output
@@ -1943,11 +1951,13 @@ public:
{
for (uint32_t k=0; k < frames; ++k)
{
#if 0 // TODO
if (k < pData->latency)
bufValue = pData->latencyBuffers[isMono ? 0 : i][k];
else if (pData->latency < frames)
bufValue = fAudioInBuffers[isMono ? 0 : i][k-pData->latency];
else
#endif
bufValue = fAudioInBuffers[isMono ? 0 : i][k];

fAudioOutBuffers[i][k] = (fAudioOutBuffers[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet));


+ 69
- 65
source/backend/plugin/CarlaPluginInternal.cpp View File

@@ -384,6 +384,73 @@ void CarlaPlugin::ProtectedData::ExternalNotes::clear() noexcept
mutex.unlock();
}

// -----------------------------------------------------------------------
// ProtectedData::Latency

CarlaPlugin::ProtectedData::Latency::Latency() noexcept
: channels(0),
frames(0),
buffers(nullptr) {}

CarlaPlugin::ProtectedData::Latency::~Latency() noexcept
{
clearBuffers();
}

void CarlaPlugin::ProtectedData::Latency::clearBuffers() noexcept
{
if (buffers != nullptr)
{
for (uint32_t i=0; i < channels; ++i)
{
CARLA_SAFE_ASSERT_CONTINUE(buffers[i] != nullptr);

delete[] buffers[i];
buffers[i] = nullptr;
}

delete[] buffers;
buffers = nullptr;
}

channels = 0;
frames = 0;
}

void CarlaPlugin::ProtectedData::Latency::recreateBuffers(const uint32_t newChannels, const uint32_t newFrames)
{
CARLA_SAFE_ASSERT_RETURN(channels != newChannels || frames != newFrames,);

// delete old buffer
if (buffers != nullptr)
{
for (uint32_t i=0; i < channels; ++i)
{
CARLA_SAFE_ASSERT_CONTINUE(buffers[i] != nullptr);

delete[] buffers[i];
buffers[i] = nullptr;
}

delete[] buffers;
buffers = nullptr;
}

channels = newChannels;
frames = newFrames;

if (channels > 0 && frames > 0)
{
buffers = new float*[channels];

for (uint32_t i=0; i < channels; ++i)
{
buffers[i] = new float[frames];
FloatVectorOperations::clear(buffers[i], static_cast<int>(frames));
}
}
}

// -----------------------------------------------------------------------
// ProtectedData::PostRtEvents

@@ -476,10 +543,6 @@ CarlaPlugin::ProtectedData::ProtectedData(CarlaEngine* const eng, const uint idx
ctrlChannel(0),
extraHints(0x0),
transientTryCounter(0),
latency(0),
#ifndef BUILD_BRIDGE
latencyBuffers(nullptr),
#endif
name(nullptr),
filename(nullptr),
iconName(nullptr),
@@ -496,6 +559,7 @@ CarlaPlugin::ProtectedData::ProtectedData(CarlaEngine* const eng, const uint idx
singleMutex(),
stateSave(),
extNotes(),
latency(),
postRtEvents(),
postUiEvents(),
#ifndef BUILD_BRIDGE
@@ -598,75 +662,15 @@ CarlaPlugin::ProtectedData::~ProtectedData() noexcept

void CarlaPlugin::ProtectedData::clearBuffers() noexcept
{
#ifndef BUILD_BRIDGE
if (latencyBuffers != nullptr)
{
CARLA_SAFE_ASSERT(audioIn.count > 0);

for (uint32_t i=0; i < audioIn.count; ++i)
{
CARLA_SAFE_ASSERT_CONTINUE(latencyBuffers[i] != nullptr);

delete[] latencyBuffers[i];
latencyBuffers[i] = nullptr;
}

delete[] latencyBuffers;
latencyBuffers = nullptr;
latency = 0;
}
else
{
if (latency != 0)
{
carla_safe_assert_int("latency != 0", __FILE__, __LINE__, static_cast<int>(latency));
latency = 0;
}
}
#else
latency = 0;
#endif

audioIn.clear();
audioOut.clear();
cvIn.clear();
cvOut.clear();
param.clear();
event.clear();
latency.clearBuffers();
}

#ifndef BUILD_BRIDGE
void CarlaPlugin::ProtectedData::recreateLatencyBuffers()
{
if (latencyBuffers != nullptr)
{
CARLA_SAFE_ASSERT(audioIn.count > 0);

for (uint32_t i=0; i < audioIn.count; ++i)
{
CARLA_SAFE_ASSERT_CONTINUE(latencyBuffers[i] != nullptr);

delete[] latencyBuffers[i];
latencyBuffers[i] = nullptr;
}

delete[] latencyBuffers;
latencyBuffers = nullptr;
}

if (audioIn.count > 0 && latency > 0)
{
latencyBuffers = new float*[audioIn.count];

for (uint32_t i=0; i < audioIn.count; ++i)
{
latencyBuffers[i] = new float[latency];
FloatVectorOperations::clear(latencyBuffers[i], static_cast<int>(latency));
}
}
}
#endif

// -----------------------------------------------------------------------
// Post-poned events



+ 23
- 9
source/backend/plugin/CarlaPluginInternal.hpp View File

@@ -34,6 +34,15 @@ using juce::FloatVectorOperations;

CARLA_BACKEND_START_NAMESPACE

// -----------------------------------------------------------------------
// Engine helper macro, sets lastError and returns false/NULL

#define CARLA_SAFE_ASSERT_RETURN_ERR(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); pData->engine->setLastError(err); return false; }
#define CARLA_SAFE_ASSERT_RETURN_ERRN(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); pData->engine->setLastError(err); return nullptr; }

#define CARLA_SAFE_EXCEPTION_RETURN_ERR(excptMsg, errMsg) catch(...) { carla_safe_exception(excptMsg, __FILE__, __LINE__); pData->engine->setLastError(errMsg); return false; }
#define CARLA_SAFE_EXCEPTION_RETURN_ERRN(excptMsg, errMsg) catch(...) { carla_safe_exception(excptMsg, __FILE__, __LINE__); pData->engine->setLastError(errMsg); return nullptr; }

// -----------------------------------------------------------------------
// Maximum pre-allocated events for some plugin types

@@ -225,12 +234,6 @@ struct CarlaPlugin::ProtectedData {
uint extraHints;
uint transientTryCounter;

// latency
uint32_t latency;
#ifndef BUILD_BRIDGE
float** latencyBuffers;
#endif

// data 1
const char* name;
const char* filename;
@@ -266,6 +269,20 @@ struct CarlaPlugin::ProtectedData {

} extNotes;

struct Latency {
uint32_t channels;
uint32_t frames;
float** buffers;

Latency() noexcept;
~Latency() noexcept;
void clearBuffers() noexcept;
void recreateBuffers(const uint32_t newChannels, const uint32_t newFrames);

CARLA_DECLARE_NON_COPY_STRUCT(Latency)

} latency;

struct PostRtEvents {
CarlaMutex mutex;
RtLinkedList<PluginPostRtEvent>::Pool dataPool;
@@ -317,9 +334,6 @@ struct CarlaPlugin::ProtectedData {
// Buffer functions

void clearBuffers() noexcept;
#ifndef BUILD_BRIDGE
void recreateLatencyBuffers();
#endif

// -------------------------------------------------------------------
// Post-poned events


+ 410
- 339
source/backend/plugin/CarlaPluginLADSPA.cpp
File diff suppressed because it is too large
View File


+ 10
- 0
source/backend/plugin/CarlaPluginLV2.cpp View File

@@ -1432,6 +1432,7 @@ public:
}
}

#if 0 // TODO
void idle() override
{
if (fLatencyChanged && fLatencyIndex != -1)
@@ -1463,6 +1464,7 @@ public:

CarlaPlugin::idle();
}
#endif

void uiIdle() override
{
@@ -2361,6 +2363,7 @@ public:
pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
}

#if 0 // TODO
// check latency
if (fLatencyIndex >= 0)
{
@@ -2429,6 +2432,7 @@ public:

fLatencyChanged = false;
}
#endif

bufferSizeChanged(pData->engine->getBufferSize());
reloadPrograms(true);
@@ -2730,11 +2734,13 @@ public:
}

#ifndef BUILD_BRIDGE
#if 0 // TODO
if (pData->latency > 0)
{
for (uint32_t i=0; i < pData->audioIn.count; ++i)
FloatVectorOperations::clear(pData->latencyBuffers[i], static_cast<int>(pData->latency));
}
#endif
#endif

pData->needsReset = false;
@@ -3340,6 +3346,7 @@ public:
} // End of Plugin processing (no events)

#ifndef BUILD_BRIDGE
#if 0 // TODO
// --------------------------------------------------------------------------------------------------------
// Latency, save values for next callback

@@ -3368,6 +3375,7 @@ public:
}
}
}
#endif
#endif

// --------------------------------------------------------------------------------------------------------
@@ -3614,11 +3622,13 @@ public:
{
for (uint32_t k=0; k < frames; ++k)
{
#if 0 // TODO
if (k < pData->latency)
bufValue = pData->latencyBuffers[isMono ? 0 : i][k];
else if (pData->latency < frames)
bufValue = fAudioInBuffers[isMono ? 0 : i][k-pData->latency];
else
#endif
bufValue = fAudioInBuffers[isMono ? 0 : i][k];

fAudioOutBuffers[i][k] = (fAudioOutBuffers[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet));


+ 4
- 0
source/backend/plugin/CarlaPluginVST2.cpp View File

@@ -843,6 +843,7 @@ public:
deactivate();
}

#if 0 // TODO
// check latency
if (pData->hints & PLUGIN_CAN_DRYWET)
{
@@ -859,6 +860,7 @@ public:
pData->recreateLatencyBuffers();
#endif
}
#endif

// special plugin fixes
// 1. IL Harmless - disable threaded processing
@@ -1061,11 +1063,13 @@ public:
}

#ifndef BUILD_BRIDGE
#if 0 // TODO
if (pData->latency > 0)
{
for (uint32_t i=0; i < pData->audioIn.count; ++i)
FloatVectorOperations::clear(pData->latencyBuffers[i], static_cast<int>(pData->latency));
}
#endif
#endif

pData->needsReset = false;


+ 2
- 2
source/native-plugins/bigmeter.cpp View File

@@ -160,10 +160,10 @@ protected:
Range<float> range;

range = FloatVectorOperations::findMinAndMax(inputs[0], static_cast<int>(frames));
fOutLeft = carla_max(std::abs(range.getStart()), std::abs(range.getEnd()), 1.0f);
fOutLeft = carla_maxLimited(std::abs(range.getStart()), std::abs(range.getEnd()), 1.0f);

range = FloatVectorOperations::findMinAndMax(inputs[1], static_cast<int>(frames));
fOutRight = carla_max(std::abs(range.getStart()), std::abs(range.getEnd()), 1.0f);
fOutRight = carla_maxLimited(std::abs(range.getStart()), std::abs(range.getEnd()), 1.0f);
}

private:


+ 4
- 4
source/utils/CarlaMathUtils.hpp View File

@@ -27,11 +27,11 @@
// math functions (base)

/*
* Return the lower of 2 values, with 'min' as the minimum possible value.
* Return the lower of 2 values, with 'min' as the minimum possible value (ie, base).
*/
template<typename T>
static inline
const T& carla_min(const T& v1, const T& v2, const T& min) noexcept
const T& carla_minWithBase(const T& v1, const T& v2, const T& min) noexcept
{
return ((v1 <= min || v2 <= min) ? min : (v1 < v2 ? v1 : v2));
}
@@ -56,11 +56,11 @@ T carla_minPositive(const T& v1, const T& v2) noexcept
}

/*
* Return the higher of 2 values, with 'max' as the maximum possible value.
* Return the higher of 2 values, with 'max' as the maximum possible value (ie, limit).
*/
template<typename T>
static inline
const T& carla_max(const T& v1, const T& v2, const T& max) noexcept
const T& carla_maxLimited(const T& v1, const T& v2, const T& max) noexcept
{
return ((v1 >= max || v2 >= max) ? max : (v1 > v2 ? v1 : v2));
}


Loading…
Cancel
Save