Browse Source

Testing sample-accurate wet/vol/balance controls in LADSPA

tags/1.9.4
falkTX 12 years ago
parent
commit
53be80f563
3 changed files with 95 additions and 61 deletions
  1. +4
    -0
      source/backend/plugin/CarlaPluginInternal.hpp
  2. +89
    -61
      source/backend/plugin/LadspaPlugin.cpp
  3. +2
    -0
      source/carla.py

+ 4
- 0
source/backend/plugin/CarlaPluginInternal.hpp View File

@@ -389,6 +389,7 @@ struct CarlaPluginProtectedData {

bool active;
bool activeBefore;
bool needsReset;
void* lib;

// misc
@@ -409,6 +410,8 @@ struct CarlaPluginProtectedData {
PluginMidiProgramData midiprog;
NonRtListNew<CustomData> custom;

CarlaMutex mutex;

struct ExternalNotes {
CarlaMutex mutex;
RtList<ExternalMidiNote>::Pool dataPool;
@@ -500,6 +503,7 @@ struct CarlaPluginProtectedData {
gui(nullptr),
active(false),
activeBefore(false),
needsReset(false),
lib(nullptr),
availOptions(0x0),
extraHints(0x0),


+ 89
- 61
source/backend/plugin/LadspaPlugin.cpp View File

@@ -686,7 +686,6 @@ public:

// always available if needed
kData->availOptions |= PLUGIN_OPTION_FIXED_BUFFER;
kData->availOptions |= PLUGIN_OPTION_SELF_AUTOMATION;

// check latency
if (fHints & PLUGIN_CAN_DRYWET)
@@ -779,7 +778,7 @@ public:
// --------------------------------------------------------------------------------------------------------
// Check if not active before

if (! kData->activeBefore)
if (kData->needsReset || ! kData->activeBefore)
{
if (kData->latency > 0)
{
@@ -787,6 +786,17 @@ public:
carla_zeroFloat(kData->latencyBuffers[i], kData->latency);
}

if (kData->activeBefore)
{
if (fDescriptor->deactivate != nullptr)
{
fDescriptor->deactivate(fHandle);

if (fHandle2 != nullptr)
fDescriptor->deactivate(fHandle2);
}
}

if (fDescriptor->activate != nullptr)
{
fDescriptor->activate(fHandle);
@@ -794,6 +804,8 @@ public:
if (fHandle2 != nullptr)
fDescriptor->activate(fHandle2);
}

kData->needsReset = false;
}

// --------------------------------------------------------------------------------------------------------
@@ -822,8 +834,8 @@ public:

if (time > timeOffset && sampleAccurate)
{
processSingle(inBuffer, outBuffer, time - timeOffset, timeOffset);
timeOffset = time;
if (processSingle(inBuffer, outBuffer, time - timeOffset, timeOffset))
timeOffset = time;
}

// Control change
@@ -1003,12 +1015,73 @@ public:

CARLA_PROCESS_CONTINUE_CHECK;

// --------------------------------------------------------------------------------------------------------
// Control Output

if (kData->event.portOut != nullptr)
{
float value;

for (k=0; k < kData->param.count; k++)
{
if (kData->param.data[k].type != PARAMETER_OUTPUT)
continue;

kData->param.ranges[k].fixValue(fParamBuffers[k]);

if (kData->param.data[k].midiCC > 0)
{
value = kData->param.ranges[k].normalizeValue(fParamBuffers[k]);
kData->event.portOut->writeControlEvent(0, kData->param.data[k].midiChannel, kEngineControlEventTypeParameter, kData->param.data[k].midiCC, value);
}
}

} // End of Control Output

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

kData->activeBefore = kData->active;
}

bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)
{
uint32_t i, k;

// --------------------------------------------------------------------------------------------------------
// Try lock, silence otherwise

if (! kData->mutex.tryLock())
{
for (i=0; i < kData->audioOut.count; i++)
{
for (k=0; k < frames; k++)
outBuffer[i][k+timeOffset] = 0.0f;
}

return false;
}

// --------------------------------------------------------------------------------------------------------
// Fill plugin buffers

for (i=0; i < kData->audioIn.count; i++)
carla_copyFloat(fAudioInBuffers[i], inBuffer[i]+timeOffset, frames);
for (i=0; i < kData->audioOut.count; i++)
carla_zeroFloat(fAudioOutBuffers[i], frames);

// --------------------------------------------------------------------------------------------------------
// Run plugin

fDescriptor->run(fHandle, frames);

if (fHandle2 != nullptr)
fDescriptor->run(fHandle2, frames);

// --------------------------------------------------------------------------------------------------------
// Post-processing (dry/wet, volume and balance)

{
const bool doDryWet = (fHints & PLUGIN_CAN_DRYWET) > 0 && kData->postProc.dryWet != 1.0f;
const bool doVolume = (fHints & PLUGIN_CAN_VOLUME) > 0 && kData->postProc.volume != 1.0f;
const bool doBalance = (fHints & PLUGIN_CAN_BALANCE) > 0 && (kData->postProc.balanceLeft != -1.0f || kData->postProc.balanceRight != 1.0f);

float bufValue, oldBufLeft[doBalance ? frames : 1];
@@ -1026,9 +1099,8 @@ public:
//else
// bufValue = (kData->audioIn.count == 1) ? inBuffer[0][k-m_latency] : inBuffer[i][k-m_latency];

bufValue = inBuffer[ (kData->audioIn.count == 1) ? 0 : i ][k];

outBuffer[i][k] = (outBuffer[i][k] * kData->postProc.dryWet) + (bufValue * (1.0f - kData->postProc.dryWet));
bufValue = fAudioInBuffers[(kData->audioIn.count == 1) ? 0 : i][k];
fAudioOutBuffers[i][k] = (fAudioOutBuffers[i][k] * kData->postProc.dryWet) + (bufValue * (1.0f - kData->postProc.dryWet));
}
}

@@ -1036,7 +1108,7 @@ public:
if (doBalance)
{
if (i % 2 == 0)
carla_copyFloat(oldBufLeft, outBuffer[i], frames);
carla_copyFloat(oldBufLeft, fAudioOutBuffers[i], frames);

float balRangeL = (kData->postProc.balanceLeft + 1.0f)/2.0f;
float balRangeR = (kData->postProc.balanceRight + 1.0f)/2.0f;
@@ -1046,23 +1118,22 @@ public:
if (i % 2 == 0)
{
// left
outBuffer[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
outBuffer[i][k] += outBuffer[i+1][k] * (1.0f - balRangeR);
fAudioOutBuffers[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
fAudioOutBuffers[i][k] += fAudioOutBuffers[i+1][k] * (1.0f - balRangeR);
}
else
{
// right
outBuffer[i][k] = outBuffer[i][k] * balRangeR;
outBuffer[i][k] += oldBufLeft[k] * balRangeL;
fAudioOutBuffers[i][k] = fAudioOutBuffers[i][k] * balRangeR;
fAudioOutBuffers[i][k] += oldBufLeft[k] * balRangeL;
}
}
}

// Volume
if (doVolume)
// Volume (and buffer copy)
{
for (k=0; k < frames; k++)
outBuffer[i][k] *= kData->postProc.volume;
outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k] * kData->postProc.volume;
}
}

@@ -1076,53 +1147,10 @@ public:
#endif
} // End of Post-processing

CARLA_PROCESS_CONTINUE_CHECK;

// --------------------------------------------------------------------------------------------------------
// Control Output

if (kData->event.portOut != nullptr)
{
float value;

for (k=0; k < kData->param.count; k++)
{
if (kData->param.data[k].type != PARAMETER_OUTPUT)
continue;

kData->param.ranges[k].fixValue(fParamBuffers[k]);

if (kData->param.data[k].midiCC > 0)
{
value = kData->param.ranges[k].normalizeValue(fParamBuffers[k]);
kData->event.portOut->writeControlEvent(0, kData->param.data[k].midiChannel, kEngineControlEventTypeParameter, kData->param.data[k].midiCC, value);
}
}

} // End of Control Output

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

kData->activeBefore = kData->active;
}

void processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)
{
for (uint32_t i=0; i < kData->audioIn.count; i++)
carla_copyFloat(fAudioInBuffers[i], inBuffer[i]+timeOffset, frames);
for (uint32_t i=0; i < kData->audioOut.count; i++)
carla_zeroFloat(fAudioOutBuffers[i], frames);

fDescriptor->run(fHandle, frames);

if (fHandle2 != nullptr)
fDescriptor->run(fHandle2, frames);

for (uint32_t i=0, k; i < kData->audioOut.count; i++)
{
for (k=0; k < frames; k++)
outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k];
}
kData->mutex.unlock();
return true;
}

void bufferSizeChanged(const uint32_t newBufferSize)


+ 2
- 0
source/carla.py View File

@@ -120,6 +120,8 @@ class CarlaSettingsW(QDialog):
#QTimer.singleShot(0, self, )
#self.slot_pluginPathTabChanged(self.tw_paths.currentIndex())

self.ui.lw_page.setCurrentCell(0, 0)

def loadSettings(self):
settings = QSettings()



Loading…
Cancel
Save