Browse Source

Vst fixing

tags/1.9.4
falkTX 12 years ago
parent
commit
fdcccb0f66
9 changed files with 242 additions and 295 deletions
  1. +1
    -1
      source/backend/CarlaEngine.hpp
  2. +0
    -1
      source/backend/plugin/BridgePlugin.cpp
  3. +10
    -4
      source/backend/plugin/CarlaPlugin.cpp
  4. +4
    -26
      source/backend/plugin/DssiPlugin.cpp
  5. +2
    -7
      source/backend/plugin/FluidSynthPlugin.cpp
  6. +2
    -22
      source/backend/plugin/LadspaPlugin.cpp
  7. +2
    -8
      source/backend/plugin/LinuxSamplerPlugin.cpp
  8. +14
    -26
      source/backend/plugin/NativePlugin.cpp
  9. +207
    -200
      source/backend/plugin/VstPlugin.cpp

+ 1
- 1
source/backend/CarlaEngine.hpp View File

@@ -323,7 +323,7 @@ struct EngineTimeInfo {


bool playing; bool playing;
uint32_t frame; uint32_t frame;
uint64_t time;
uint64_t time; // usecs
uint32_t valid; uint32_t valid;
EngineTimeInfoBBT bbt; EngineTimeInfoBBT bbt;




+ 0
- 1
source/backend/plugin/BridgePlugin.cpp View File

@@ -1007,7 +1007,6 @@ public:
for (i=0; i < kData->audioOut.count; i++) for (i=0; i < kData->audioOut.count; i++)
carla_zeroFloat(outBuffer[i], frames); carla_zeroFloat(outBuffer[i], frames);


//kData->activeBefore = kData->active;
return; return;
} }




+ 10
- 4
source/backend/plugin/CarlaPlugin.cpp View File

@@ -1005,13 +1005,19 @@ void CarlaPlugin::setEnabled(const bool yesNo)


void CarlaPlugin::setActive(const bool active, const bool sendOsc, const bool sendCallback) void CarlaPlugin::setActive(const bool active, const bool sendOsc, const bool sendCallback)
{ {
CARLA_ASSERT(sendOsc || sendCallback); // never call this from RT

if (kData->active == active) if (kData->active == active)
return; return;


if (active)
activate();
else
deactivate();
{
const ScopedSingleProcessLocker spl(this, true);

if (active)
activate();
else
deactivate();
}


kData->active = active; kData->active = active;




+ 4
- 26
source/backend/plugin/DssiPlugin.cpp View File

@@ -1028,11 +1028,9 @@ public:
{ {
while (midiEventCount < MAX_MIDI_EVENTS && ! kData->extNotes.data.isEmpty()) while (midiEventCount < MAX_MIDI_EVENTS && ! kData->extNotes.data.isEmpty())
{ {
const ExternalMidiNote& note = kData->extNotes.data.getFirst(true);
const ExternalMidiNote& note(kData->extNotes.data.getFirst(true));


CARLA_ASSERT(note.channel >= 0);

carla_zeroStruct<snd_seq_event_t>(fMidiEvents[midiEventCount]);
CARLA_ASSERT(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);


fMidiEvents[midiEventCount].type = (note.velo > 0) ? SND_SEQ_EVENT_NOTEON : SND_SEQ_EVENT_NOTEOFF; fMidiEvents[midiEventCount].type = (note.velo > 0) ? SND_SEQ_EVENT_NOTEON : SND_SEQ_EVENT_NOTEOFF;
fMidiEvents[midiEventCount].data.note.channel = note.channel; fMidiEvents[midiEventCount].data.note.channel = note.channel;
@@ -1219,22 +1217,6 @@ public:
allNotesOffSent = true; allNotesOffSent = true;
} }


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

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

if (fDescriptor->activate != nullptr)
{
fDescriptor->activate(fHandle);

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

postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 0.0f); postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 0.0f);
postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 1.0f); postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 1.0f);
} }
@@ -1420,10 +1402,6 @@ public:
} }


} // End of Control Output } // End of Control Output

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

//kData->activeBefore = kData->active;
} }


bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset, const unsigned long midiEventCount) bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset, const unsigned long midiEventCount)
@@ -1644,12 +1622,12 @@ public:
void sampleRateChanged(const double newSampleRate) void sampleRateChanged(const double newSampleRate)
{ {
CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate); CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
carla_debug("DssiPlugin::sampleRateChanged(%i) - start", newSampleRate);
carla_debug("DssiPlugin::sampleRateChanged(%g) - start", newSampleRate);


// TODO // TODO
(void)newSampleRate; (void)newSampleRate;


carla_debug("DssiPlugin::sampleRateChanged(%i) - end", newSampleRate);
carla_debug("DssiPlugin::sampleRateChanged(%g) - end", newSampleRate);
} }


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


+ 2
- 7
source/backend/plugin/FluidSynthPlugin.cpp View File

@@ -882,7 +882,6 @@ public:
for (i=0; i < kData->audioOut.count; i++) for (i=0; i < kData->audioOut.count; i++)
carla_zeroFloat(outBuffer[i], frames); carla_zeroFloat(outBuffer[i], frames);


//kData->activeBefore = kData->active;
return; return;
} }


@@ -920,9 +919,9 @@ public:
{ {
while (! kData->extNotes.data.isEmpty()) while (! kData->extNotes.data.isEmpty())
{ {
const ExternalMidiNote& note = kData->extNotes.data.getFirst(true);
const ExternalMidiNote& note(kData->extNotes.data.getFirst(true));


CARLA_ASSERT(note.channel >= 0);
CARLA_ASSERT(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);


if (note.velo > 0) if (note.velo > 0)
fluid_synth_noteon(fSynth, note.channel, note.note, note.velo); fluid_synth_noteon(fSynth, note.channel, note.note, note.velo);
@@ -1230,10 +1229,6 @@ public:
} }


} // End of Control Output } // End of Control Output

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

//kData->activeBefore = kData->active;
} }


bool processSingle(float** const outBuffer, const uint32_t frames, const uint32_t timeOffset) bool processSingle(float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)


+ 2
- 22
source/backend/plugin/LadspaPlugin.cpp View File

@@ -989,22 +989,6 @@ public:
case kEngineControlEventTypeAllSoundOff: case kEngineControlEventTypeAllSoundOff:
if (event.channel == kData->ctrlChannel) if (event.channel == kData->ctrlChannel)
{ {
if (fDescriptor->deactivate != nullptr)
{
fDescriptor->deactivate(fHandle);

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

if (fDescriptor->activate != nullptr)
{
fDescriptor->activate(fHandle);

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

postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 0.0f); postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 0.0f);
postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 1.0f); postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 1.0f);
} }
@@ -1067,10 +1051,6 @@ public:
} }


} // End of Control Output } // End of Control Output

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

//kData->activeBefore = kData->active;
} }


bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset) bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)
@@ -1273,12 +1253,12 @@ public:
void sampleRateChanged(const double newSampleRate) void sampleRateChanged(const double newSampleRate)
{ {
CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate); CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
carla_debug("LadspaPlugin::sampleRateChanged(%i) - start", newSampleRate);
carla_debug("LadspaPlugin::sampleRateChanged(%g) - start", newSampleRate);


// TODO // TODO
(void)newSampleRate; (void)newSampleRate;


carla_debug("LadspaPlugin::sampleRateChanged(%i) - end", newSampleRate);
carla_debug("LadspaPlugin::sampleRateChanged(%g) - end", newSampleRate);
} }


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


+ 2
- 8
source/backend/plugin/LinuxSamplerPlugin.cpp View File

@@ -467,8 +467,6 @@ public:


//if (kData->activeBefore) //if (kData->activeBefore)
// fAudioOutputDevice->Stop(); // fAudioOutputDevice->Stop();

//kData->activeBefore = kData->active;
return; return;
} }


@@ -506,9 +504,9 @@ public:
{ {
while (! kData->extNotes.data.isEmpty()) while (! kData->extNotes.data.isEmpty())
{ {
const ExternalMidiNote& note = kData->extNotes.data.getFirst(true);
const ExternalMidiNote& note(kData->extNotes.data.getFirst(true));


CARLA_ASSERT(note.channel >= 0);
CARLA_ASSERT(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);


if (note.velo > 0) if (note.velo > 0)
fMidiInputPort->DispatchNoteOn(note.note, note.velo, note.channel, 0); fMidiInputPort->DispatchNoteOn(note.note, note.velo, note.channel, 0);
@@ -801,10 +799,6 @@ public:
processSingle(outBuffer, frames, 0); processSingle(outBuffer, frames, 0);


} // End of Plugin processing (no events) } // End of Plugin processing (no events)

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

//kData->activeBefore = kData->active;
} }


bool processSingle(float** const outBuffer, const uint32_t frames, const uint32_t timeOffset) bool processSingle(float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)


+ 14
- 26
source/backend/plugin/NativePlugin.cpp View File

@@ -182,8 +182,12 @@ public:
{ {
carla_debug("NativePlugin::~NativePlugin()"); carla_debug("NativePlugin::~NativePlugin()");


if (fIsUiVisible && fDescriptor != nullptr && fDescriptor->ui_show != nullptr && fHandle != nullptr)
fDescriptor->ui_show(fHandle, false);
// close UI
if (fHints & PLUGIN_HAS_GUI)
{
if (fIsUiVisible && fDescriptor != nullptr && fDescriptor->ui_show != nullptr && fHandle != nullptr)
fDescriptor->ui_show(fHandle, false);
}


kData->singleMutex.lock(); kData->singleMutex.lock();
kData->masterMutex.lock(); kData->masterMutex.lock();
@@ -1183,9 +1187,11 @@ public:
{ {
fMidiEvents[k].data[0] = MIDI_STATUS_CONTROL_CHANGE + k; fMidiEvents[k].data[0] = MIDI_STATUS_CONTROL_CHANGE + k;
fMidiEvents[k].data[1] = MIDI_CONTROL_ALL_SOUND_OFF; fMidiEvents[k].data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
fMidiEvents[k].size = 2;


fMidiEvents[k+i].data[0] = MIDI_STATUS_CONTROL_CHANGE + k; fMidiEvents[k+i].data[0] = MIDI_STATUS_CONTROL_CHANGE + k;
fMidiEvents[k+i].data[1] = MIDI_CONTROL_ALL_NOTES_OFF; fMidiEvents[k+i].data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
fMidiEvents[k+i].size = 2;
} }


fMidiEventCount = MAX_MIDI_CHANNELS*2; fMidiEventCount = MAX_MIDI_CHANNELS*2;
@@ -1240,12 +1246,10 @@ public:
{ {
while (fMidiEventCount < MAX_MIDI_EVENTS*2 && ! kData->extNotes.data.isEmpty()) while (fMidiEventCount < MAX_MIDI_EVENTS*2 && ! kData->extNotes.data.isEmpty())
{ {
const ExternalMidiNote& note = kData->extNotes.data.getFirst(true);
const ExternalMidiNote& note(kData->extNotes.data.getFirst(true));


CARLA_ASSERT(note.channel >= 0);
CARLA_ASSERT(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);


fMidiEvents[fMidiEventCount].port = 0;
fMidiEvents[fMidiEventCount].time = 0;
fMidiEvents[fMidiEventCount].data[0] = (note.velo > 0) ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF; fMidiEvents[fMidiEventCount].data[0] = (note.velo > 0) ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF;
fMidiEvents[fMidiEventCount].data[0] += note.channel; fMidiEvents[fMidiEventCount].data[0] += note.channel;
fMidiEvents[fMidiEventCount].data[1] = note.note; fMidiEvents[fMidiEventCount].data[1] = note.note;
@@ -1437,22 +1441,6 @@ public:
allNotesOffSent = true; allNotesOffSent = true;
} }


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

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

if (fDescriptor->activate != nullptr)
{
fDescriptor->activate(fHandle);

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

postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 0.0f); postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 0.0f);
postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 1.0f); postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 1.0f);
} }
@@ -1467,6 +1455,8 @@ public:
fMidiEvents[fMidiEventCount].data[0] = MIDI_STATUS_CONTROL_CHANGE + event.channel; fMidiEvents[fMidiEventCount].data[0] = MIDI_STATUS_CONTROL_CHANGE + event.channel;
fMidiEvents[fMidiEventCount].data[1] = MIDI_CONTROL_ALL_SOUND_OFF; fMidiEvents[fMidiEventCount].data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
fMidiEvents[fMidiEventCount].data[2] = 0; fMidiEvents[fMidiEventCount].data[2] = 0;
fMidiEvents[fMidiEventCount].data[3] = 0;
fMidiEvents[fMidiEventCount].size = 2;


fMidiEventCount += 1; fMidiEventCount += 1;
} }
@@ -1493,6 +1483,8 @@ public:
fMidiEvents[fMidiEventCount].data[0] = MIDI_STATUS_CONTROL_CHANGE + event.channel; fMidiEvents[fMidiEventCount].data[0] = MIDI_STATUS_CONTROL_CHANGE + event.channel;
fMidiEvents[fMidiEventCount].data[1] = MIDI_CONTROL_ALL_NOTES_OFF; fMidiEvents[fMidiEventCount].data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
fMidiEvents[fMidiEventCount].data[2] = 0; fMidiEvents[fMidiEventCount].data[2] = 0;
fMidiEvents[fMidiEventCount].data[3] = 0;
fMidiEvents[fMidiEventCount].size = 2;


fMidiEventCount += 1; fMidiEventCount += 1;
} }
@@ -1603,10 +1595,6 @@ public:
} }


} // End of Control and MIDI Output } // End of Control and MIDI Output

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

//kData->activeBefore = kData->active;
} }


bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset) bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)


+ 207
- 200
source/backend/plugin/VstPlugin.cpp View File

@@ -28,6 +28,10 @@


CARLA_BACKEND_START_NAMESPACE CARLA_BACKEND_START_NAMESPACE


#if 0
}
#endif

/*! /*!
* @defgroup PluginHints Plugin Hints * @defgroup PluginHints Plugin Hints
* @{ * @{
@@ -42,10 +46,11 @@ class VstPlugin : public CarlaPlugin,
public CarlaPluginGui::Callback public CarlaPluginGui::Callback
{ {
public: public:
VstPlugin(CarlaEngine* const engine, const unsigned short id)
VstPlugin(CarlaEngine* const engine, const unsigned int id)
: CarlaPlugin(engine, id), : CarlaPlugin(engine, id),
fUnique1(1), fUnique1(1),
fEffect(nullptr), fEffect(nullptr),
fLastChunk(nullptr),
fMidiEventCount(0), fMidiEventCount(0),
fIsProcessing(false), fIsProcessing(false),
fNeedIdle(false), fNeedIdle(false),
@@ -53,10 +58,10 @@ public:
{ {
carla_debug("VstPlugin::VstPlugin(%p, %i)", engine, id); carla_debug("VstPlugin::VstPlugin(%p, %i)", engine, id);


carla_zeroMem(fMidiEvents, sizeof(VstMidiEvent)*MAX_MIDI_EVENTS*2);
carla_zeroStruct<VstMidiEvent>(fMidiEvents, MAX_MIDI_EVENTS*2);
carla_zeroStruct<VstTimeInfo_R>(fTimeInfo); carla_zeroStruct<VstTimeInfo_R>(fTimeInfo);


for (unsigned short i=0; i < MAX_MIDI_EVENTS*2; i++)
for (unsigned short i=0; i < MAX_MIDI_EVENTS*2; ++i)
fEvents.data[i] = (VstEvent*)&fMidiEvents[i]; fEvents.data[i] = (VstEvent*)&fMidiEvents[i];


kData->osc.thread.setMode(CarlaPluginThread::PLUGIN_THREAD_VST_GUI); kData->osc.thread.setMode(CarlaPluginThread::PLUGIN_THREAD_VST_GUI);
@@ -70,15 +75,6 @@ public:
{ {
carla_debug("VstPlugin::~VstPlugin()"); carla_debug("VstPlugin::~VstPlugin()");


kData->singleMutex.lock();
kData->masterMutex.lock();

// make plugin invalid
fUnique2 += 1;

if (fEffect == nullptr)
return;

// close UI // close UI
if (fHints & PLUGIN_HAS_GUI) if (fHints & PLUGIN_HAS_GUI)
{ {
@@ -93,20 +89,31 @@ public:
kData->osc.thread.terminate(); kData->osc.thread.terminate();
} }
} }
else
dispatcher(effEditClose, 0, 0, nullptr, 0.0f);
} }


kData->singleMutex.lock();
kData->masterMutex.lock();

if (kData->active) if (kData->active)
{ {
dispatcher(effStopProcess, 0, 0, nullptr, 0.0f);
dispatcher(effMainsChanged, 0, 0, nullptr, 0.0f);
deactivate();
kData->active = false; kData->active = false;
} }


dispatcher(effClose, 0, 0, nullptr, 0.0f);
if (fEffect != nullptr)
{
dispatcher(effClose, 0, 0, nullptr, 0.0f);
fEffect = nullptr;
}


fEffect = nullptr;
if (fLastChunk != nullptr)
{
delete[] fLastChunk;
fLastChunk = nullptr;
}

// make plugin invalid
fUnique2 += 1;
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -121,7 +128,6 @@ public:
{ {
CARLA_ASSERT(fEffect != nullptr); CARLA_ASSERT(fEffect != nullptr);


if (fEffect != nullptr)
{ {
const intptr_t category = dispatcher(effGetPlugCategory, 0, 0, nullptr, 0.0f); const intptr_t category = dispatcher(effGetPlugCategory, 0, 0, nullptr, 0.0f);


@@ -164,7 +170,7 @@ public:
CARLA_ASSERT(fEffect != nullptr); CARLA_ASSERT(fEffect != nullptr);
CARLA_ASSERT(dataPtr != nullptr); CARLA_ASSERT(dataPtr != nullptr);


return (fEffect != nullptr) ? dispatcher(effGetChunk, 0 /* bank */, 0, dataPtr, 0.0f) : 0;
return dispatcher(effGetChunk, 0 /* bank */, 0, dataPtr, 0.0f);
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -182,13 +188,10 @@ public:
options |= PLUGIN_OPTION_FIXED_BUFFER; options |= PLUGIN_OPTION_FIXED_BUFFER;
options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES; options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;


//if ((kData->audioIns.count() == 2 || kData->audioOuts.count() == 0) || (kData->audioIns.count() == 0 || kData->audioOuts.count() == 2))
// options |= PLUGIN_OPTION_FORCE_STEREO;

if (fEffect->flags & effFlagsProgramChunks) if (fEffect->flags & effFlagsProgramChunks)
options |= PLUGIN_OPTION_USE_CHUNKS; options |= PLUGIN_OPTION_USE_CHUNKS;


if (kData->extraHints & PLUGIN_HINT_HAS_MIDI_IN)
if (vstPluginCanDo(fEffect, "receiveVstEvents") || vstPluginCanDo(fEffect, "receiveVstMidiEvent") || (fEffect->flags & effFlagsIsSynth) > 0 || (fHints & PLUGIN_WANTS_MIDI_INPUT))
{ {
options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES; options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE; options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
@@ -205,47 +208,35 @@ public:
CARLA_ASSERT(fEffect != nullptr); CARLA_ASSERT(fEffect != nullptr);
CARLA_ASSERT(parameterId < kData->param.count); CARLA_ASSERT(parameterId < kData->param.count);


return (fEffect != nullptr) ? fEffect->getParameter(fEffect, parameterId) : 0;
return fEffect->getParameter(fEffect, parameterId);
} }


void getLabel(char* const strBuf) void getLabel(char* const strBuf)
{ {
CARLA_ASSERT(fEffect != nullptr); CARLA_ASSERT(fEffect != nullptr);


if (fEffect != nullptr)
dispatcher(effGetProductString, 0, 0, strBuf, 0.0f);
else
CarlaPlugin::getLabel(strBuf);
dispatcher(effGetProductString, 0, 0, strBuf, 0.0f);
} }


void getMaker(char* const strBuf) void getMaker(char* const strBuf)
{ {
CARLA_ASSERT(fEffect != nullptr); CARLA_ASSERT(fEffect != nullptr);


if (fEffect != nullptr)
dispatcher(effGetVendorString, 0, 0, strBuf, 0.0f);
else
CarlaPlugin::getMaker(strBuf);
dispatcher(effGetVendorString, 0, 0, strBuf, 0.0f);
} }


void getCopyright(char* const strBuf) void getCopyright(char* const strBuf)
{ {
CARLA_ASSERT(fEffect != nullptr); CARLA_ASSERT(fEffect != nullptr);


if (fEffect != nullptr)
dispatcher(effGetVendorString, 0, 0, strBuf, 0.0f);
else
CarlaPlugin::getCopyright(strBuf);
dispatcher(effGetVendorString, 0, 0, strBuf, 0.0f);
} }


void getRealName(char* const strBuf) void getRealName(char* const strBuf)
{ {
CARLA_ASSERT(fEffect != nullptr); CARLA_ASSERT(fEffect != nullptr);


if (fEffect != nullptr)
dispatcher(effGetEffectName, 0, 0, strBuf, 0.0f);
else
CarlaPlugin::getRealName(strBuf);
dispatcher(effGetEffectName, 0, 0, strBuf, 0.0f);
} }


void getParameterName(const uint32_t parameterId, char* const strBuf) void getParameterName(const uint32_t parameterId, char* const strBuf)
@@ -253,10 +244,7 @@ public:
CARLA_ASSERT(fEffect != nullptr); CARLA_ASSERT(fEffect != nullptr);
CARLA_ASSERT(parameterId < kData->param.count); CARLA_ASSERT(parameterId < kData->param.count);


if (fEffect != nullptr)
dispatcher(effGetParamName, parameterId, 0, strBuf, 0.0f);
else
CarlaPlugin::getParameterName(parameterId, strBuf);
dispatcher(effGetParamName, parameterId, 0, strBuf, 0.0f);
} }


void getParameterText(const uint32_t parameterId, char* const strBuf) void getParameterText(const uint32_t parameterId, char* const strBuf)
@@ -264,15 +252,10 @@ public:
CARLA_ASSERT(fEffect != nullptr); CARLA_ASSERT(fEffect != nullptr);
CARLA_ASSERT(parameterId < kData->param.count); CARLA_ASSERT(parameterId < kData->param.count);


if (fEffect != nullptr)
{
dispatcher(effGetParamDisplay, parameterId, 0, strBuf, 0.0f);
dispatcher(effGetParamDisplay, parameterId, 0, strBuf, 0.0f);


if (*strBuf == 0)
std::sprintf(strBuf, "%f", getParameterValue(parameterId));
}
else
CarlaPlugin::getParameterText(parameterId, strBuf);
if (*strBuf == 0)
std::sprintf(strBuf, "%f", getParameterValue(parameterId));
} }


void getParameterUnit(const uint32_t parameterId, char* const strBuf) void getParameterUnit(const uint32_t parameterId, char* const strBuf)
@@ -280,10 +263,7 @@ public:
CARLA_ASSERT(fEffect != nullptr); CARLA_ASSERT(fEffect != nullptr);
CARLA_ASSERT(parameterId < kData->param.count); CARLA_ASSERT(parameterId < kData->param.count);


if (fEffect != nullptr)
dispatcher(effGetParamLabel, parameterId, 0, strBuf, 0.0f);
else
CarlaPlugin::getParameterUnit(parameterId, strBuf);
dispatcher(effGetParamLabel, parameterId, 0, strBuf, 0.0f);
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -296,24 +276,33 @@ public:


const float fixedValue = kData->param.fixValue(parameterId, value); const float fixedValue = kData->param.fixValue(parameterId, value);


if (fEffect != nullptr)
fEffect->setParameter(fEffect, parameterId, fixedValue);
fEffect->setParameter(fEffect, parameterId, fixedValue);


CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback); CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
} }


void setChunkData(const char* const stringData) void setChunkData(const char* const stringData)
{ {
CARLA_ASSERT(fEffect != nullptr);
CARLA_ASSERT(fOptions & PLUGIN_OPTION_USE_CHUNKS); CARLA_ASSERT(fOptions & PLUGIN_OPTION_USE_CHUNKS);
CARLA_ASSERT(fEffect != nullptr);
CARLA_ASSERT(stringData != nullptr); CARLA_ASSERT(stringData != nullptr);


// FIXME
fChunk = QByteArray::fromBase64(QByteArray(stringData));
//fChunk.toBase64();
if (fLastChunk != nullptr)
{
delete[] fLastChunk;
fLastChunk = nullptr;
}

const size_t size(CarlaString(stringData).exportAsBase64Binary(&fLastChunk));

CARLA_ASSERT(size > 0);
CARLA_ASSERT(fLastChunk != nullptr);


const ScopedSingleProcessLocker spl(this, true);
dispatcher(effSetChunk, 0 /* bank */, fChunk.size(), fChunk.data(), 0.0f);
if (size > 0 && fLastChunk != nullptr)
{
const ScopedSingleProcessLocker spl(this, true);
dispatcher(effSetChunk, 0 /* bank */, size, fLastChunk, 0.0f);
}
} }


void setProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) void setProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback)
@@ -326,7 +315,7 @@ public:
else if (index > static_cast<int32_t>(kData->prog.count)) else if (index > static_cast<int32_t>(kData->prog.count))
return; return;


if (fEffect != nullptr && index >= 0)
if (index >= 0)
{ {
const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback)); const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback));


@@ -469,7 +458,10 @@ public:
// Safely disable plugin for reload // Safely disable plugin for reload
const ScopedDisabler sd(this); const ScopedDisabler sd(this);


kData->clearBuffers();
if (kData->active)
deactivate();

clearBuffers();


uint32_t aIns, aOuts, mIns, mOuts, params, j; uint32_t aIns, aOuts, mIns, mOuts, params, j;


@@ -517,7 +509,7 @@ public:
CarlaString portName; CarlaString portName;


// Audio Ins // Audio Ins
for (j=0; j < aIns; j++)
for (j=0; j < aIns; ++j)
{ {
portName.clear(); portName.clear();


@@ -534,6 +526,7 @@ public:
} }
else else
portName += "input"; portName += "input";

portName.truncate(portNameSize); portName.truncate(portNameSize);


kData->audioIn.ports[j].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, true); kData->audioIn.ports[j].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, true);
@@ -541,7 +534,7 @@ public:
} }


// Audio Outs // Audio Outs
for (j=0; j < aOuts; j++)
for (j=0; j < aOuts; ++j)
{ {
portName.clear(); portName.clear();


@@ -558,13 +551,14 @@ public:
} }
else else
portName += "output"; portName += "output";

portName.truncate(portNameSize); portName.truncate(portNameSize);


kData->audioOut.ports[j].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, false); kData->audioOut.ports[j].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, false);
kData->audioOut.ports[j].rindex = j; kData->audioOut.ports[j].rindex = j;
} }


for (j=0; j < params; j++)
for (j=0; j < params; ++j)
{ {
kData->param.data[j].type = PARAMETER_INPUT; kData->param.data[j].type = PARAMETER_INPUT;
kData->param.data[j].index = j; kData->param.data[j].index = j;
@@ -716,7 +710,7 @@ public:
portName += ":"; portName += ":";
} }


portName += "event-in";
portName += "events-in";
portName.truncate(portNameSize); portName.truncate(portNameSize);


kData->event.portIn = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, true); kData->event.portIn = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, true);
@@ -732,7 +726,7 @@ public:
portName += ":"; portName += ":";
} }


portName += "event-out";
portName += "events-out";
portName.truncate(portNameSize); portName.truncate(portNameSize);


kData->event.portOut = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, false); kData->event.portOut = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, false);
@@ -787,33 +781,10 @@ public:
if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0)) if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0))
kData->extraHints |= PLUGIN_HINT_CAN_RUN_RACK; kData->extraHints |= PLUGIN_HINT_CAN_RUN_RACK;


// plugin options
fOptions = 0x0;

fOptions |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;

if (fEffect->flags & effFlagsProgramChunks)
fOptions |= PLUGIN_OPTION_USE_CHUNKS;

#ifdef CARLA_OS_WIN
// Most Windows plugins have issues with this
fOptions |= PLUGIN_OPTION_FIXED_BUFFER;
#endif

if (mIns > 0)
// dummy pre-start to get latency and wantEvents() on old plugins
{ {
fOptions |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
fOptions |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
fOptions |= PLUGIN_OPTION_SEND_PITCHBEND;
fOptions |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
}

// dummy pre-start to catch latency and possible wantEvents() call on old plugins
{
dispatcher(effMainsChanged, 0, 1, nullptr, 0.0f);
dispatcher(effStartProcess, 0, 0, nullptr, 0.0f);
dispatcher(effStopProcess, 0, 0, nullptr, 0.0f);
dispatcher(effMainsChanged, 0, 0, nullptr, 0.0f);
activate();
deactivate();
} }


// check latency // check latency
@@ -847,9 +818,8 @@ public:
bufferSizeChanged(kData->engine->getBufferSize()); bufferSizeChanged(kData->engine->getBufferSize());
reloadPrograms(true); reloadPrograms(true);


// always enabled, FIXME
dispatcher(effMainsChanged, 0, 1, nullptr, 0.0f);
dispatcher(effStartProcess, 0, 0, nullptr, 0.0f);
if (kData->active)
activate();


carla_debug("VstPlugin::reload() - end"); carla_debug("VstPlugin::reload() - end");
} }
@@ -871,7 +841,7 @@ public:
kData->prog.createNew(count); kData->prog.createNew(count);


// Update names // Update names
for (i=0; i < count; i++)
for (i=0; i < count; ++i)
{ {
char strBuf[STR_MAX+1] = { 0 }; char strBuf[STR_MAX+1] = { 0 };
if (dispatcher(effGetProgramNameIndexed, i, 0, strBuf, 0.0f) != 1) if (dispatcher(effGetProgramNameIndexed, i, 0, strBuf, 0.0f) != 1)
@@ -890,7 +860,7 @@ public:
{ {
kData->engine->osc_send_control_set_program_count(fId, count); kData->engine->osc_send_control_set_program_count(fId, count);


for (i=0; i < count; i++)
for (i=0; i < count; ++i)
kData->engine->osc_send_control_set_program_name(fId, i, kData->prog.names[i]); kData->engine->osc_send_control_set_program_name(fId, i, kData->prog.names[i]);
} }
#endif #endif
@@ -953,6 +923,18 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Plugin processing // Plugin processing


void activate()
{
dispatcher(effMainsChanged, 0, 1, nullptr, 0.0f);
dispatcher(effStartProcess, 0, 0, nullptr, 0.0f);
}

void deactivate()
{
dispatcher(effStopProcess, 0, 0, nullptr, 0.0f);
dispatcher(effMainsChanged, 0, 0, nullptr, 0.0f);
}

void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) void process(float** const inBuffer, float** const outBuffer, const uint32_t frames)
{ {
uint32_t i, k; uint32_t i, k;
@@ -963,55 +945,57 @@ public:
if (! kData->active) if (! kData->active)
{ {
// disable any output sound // disable any output sound
for (i=0; i < kData->audioOut.count; i++)
for (i=0; i < kData->audioOut.count; ++i)
carla_zeroFloat(outBuffer[i], frames); carla_zeroFloat(outBuffer[i], frames);


//kData->activeBefore = kData->active;
return; return;
} }


fMidiEventCount = 0; fMidiEventCount = 0;
carla_zeroMem(fMidiEvents, sizeof(VstMidiEvent)*MAX_MIDI_EVENTS*2);
carla_zeroStruct<VstMidiEvent>(fMidiEvents, MAX_MIDI_EVENTS*2);


// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Check if not active before
// Check if needs reset


if (kData->needsReset /*|| ! kData->activeBefore*/)
if (kData->needsReset)
{ {
// TODO!
if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF) if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
{ {
for (unsigned char j=0, l=MAX_MIDI_CHANNELS; j < MAX_MIDI_CHANNELS; j++)
for (k=0, i=MAX_MIDI_CHANNELS; k < MAX_MIDI_CHANNELS; ++k)
{ {
carla_zeroStruct<VstMidiEvent>(fMidiEvents[j]);
carla_zeroStruct<VstMidiEvent>(fMidiEvents[j+l]);

fMidiEvents[j].type = kVstMidiType;
fMidiEvents[j].byteSize = sizeof(VstMidiEvent);
fMidiEvents[j].midiData[0] = MIDI_STATUS_CONTROL_CHANGE + j;
fMidiEvents[j].midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;

fMidiEvents[j+l].type = kVstMidiType;
fMidiEvents[j+l].byteSize = sizeof(VstMidiEvent);
fMidiEvents[j+l].midiData[0] = MIDI_STATUS_CONTROL_CHANGE + j;
fMidiEvents[j+l].midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
fMidiEvents[k].type = kVstMidiType;
fMidiEvents[k].byteSize = sizeof(VstMidiEvent);
fMidiEvents[k].midiData[0] = MIDI_STATUS_CONTROL_CHANGE + k;
fMidiEvents[k].midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;

fMidiEvents[k+i].type = kVstMidiType;
fMidiEvents[k+i].byteSize = sizeof(VstMidiEvent);
fMidiEvents[k+i].midiData[0] = MIDI_STATUS_CONTROL_CHANGE + k;
fMidiEvents[k+i].midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
} }


fMidiEventCount = MAX_MIDI_CHANNELS*2; fMidiEventCount = MAX_MIDI_CHANNELS*2;
} }
else
{
}


if (kData->latency > 0) if (kData->latency > 0)
{ {
for (i=0; i < kData->audioIn.count; i++)
for (i=0; i < kData->audioIn.count; ++i)
carla_zeroFloat(kData->latencyBuffers[i], kData->latency); carla_zeroFloat(kData->latencyBuffers[i], kData->latency);
} }


kData->needsReset = false; kData->needsReset = false;
} }


CARLA_PROCESS_CONTINUE_CHECK;

// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Set TimeInfo // Set TimeInfo


const EngineTimeInfo& timeInfo = kData->engine->getTimeInfo();
const EngineTimeInfo& timeInfo(kData->engine->getTimeInfo());


fTimeInfo.flags = kVstTransportChanged; fTimeInfo.flags = kVstTransportChanged;


@@ -1021,7 +1005,7 @@ public:
fTimeInfo.samplePos = timeInfo.frame; fTimeInfo.samplePos = timeInfo.frame;
fTimeInfo.sampleRate = kData->engine->getSampleRate(); fTimeInfo.sampleRate = kData->engine->getSampleRate();


fTimeInfo.nanoSeconds = timeInfo.time*1000;
fTimeInfo.nanoSeconds = timeInfo.time/1000;
fTimeInfo.flags |= kVstNanosValid; fTimeInfo.flags |= kVstNanosValid;


if (timeInfo.valid & EngineTimeInfo::ValidBBT) if (timeInfo.valid & EngineTimeInfo::ValidBBT)
@@ -1063,10 +1047,12 @@ public:
fTimeInfo.barStartPos = 0.0; fTimeInfo.barStartPos = 0.0;
} }


CARLA_PROCESS_CONTINUE_CHECK;

// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Event Input and Processing // Event Input and Processing


if (kData->event.portIn != nullptr /*&& kData->activeBefore*/)
if (kData->event.portIn != nullptr)
{ {
// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
// MIDI Input (External) // MIDI Input (External)
@@ -1075,9 +1061,9 @@ public:
{ {
while (fMidiEventCount < MAX_MIDI_EVENTS*2 && ! kData->extNotes.data.isEmpty()) while (fMidiEventCount < MAX_MIDI_EVENTS*2 && ! kData->extNotes.data.isEmpty())
{ {
const ExternalMidiNote& note = kData->extNotes.data.getFirst(true);
const ExternalMidiNote& note(kData->extNotes.data.getFirst(true));


carla_zeroStruct<VstMidiEvent>(fMidiEvents[fMidiEventCount]);
CARLA_ASSERT(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);


fMidiEvents[fMidiEventCount].type = kVstMidiType; fMidiEvents[fMidiEventCount].type = kVstMidiType;
fMidiEvents[fMidiEventCount].byteSize = sizeof(VstMidiEvent); fMidiEvents[fMidiEventCount].byteSize = sizeof(VstMidiEvent);
@@ -1103,7 +1089,7 @@ public:
uint32_t startTime = 0; uint32_t startTime = 0;
uint32_t timeOffset = 0; uint32_t timeOffset = 0;


for (i=0; i < nEvents; i++)
for (i=0; i < nEvents; ++i)
{ {
const EngineEvent& event = kData->event.portIn->getEvent(i); const EngineEvent& event = kData->event.portIn->getEvent(i);


@@ -1123,7 +1109,7 @@ public:


if (fMidiEventCount > 0) if (fMidiEventCount > 0)
{ {
//carla_zeroMem(fMidiEvents, sizeof(::MidiEvent)*fMidiEventCount);
carla_zeroStruct<VstMidiEvent>(fMidiEvents, fMidiEventCount);
fMidiEventCount = 0; fMidiEventCount = 0;
} }
} }
@@ -1151,7 +1137,7 @@ public:
// Control backend stuff // Control backend stuff
if (event.channel == kData->ctrlChannel) if (event.channel == kData->ctrlChannel)
{ {
double value;
float value;


if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (fHints & PLUGIN_CAN_DRYWET) > 0) if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (fHints & PLUGIN_CAN_DRYWET) > 0)
{ {
@@ -1163,7 +1149,7 @@ public:


if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (fHints & PLUGIN_CAN_VOLUME) > 0) if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (fHints & PLUGIN_CAN_VOLUME) > 0)
{ {
value = ctrlEvent.value*127/100;
value = ctrlEvent.value*127.0f/100.0f;
setVolume(value, false, false); setVolume(value, false, false);
postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value); postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value);
continue; continue;
@@ -1171,23 +1157,23 @@ public:


if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (fHints & PLUGIN_CAN_BALANCE) > 0) if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (fHints & PLUGIN_CAN_BALANCE) > 0)
{ {
double left, right;
value = ctrlEvent.value/0.5 - 1.0;
float left, right;
value = ctrlEvent.value/0.5f - 1.0f;


if (value < 0.0)
if (value < 0.0f)
{ {
left = -1.0;
right = (value*2)+1.0;
left = -1.0f;
right = (value*2.0f)+1.0f;
} }
else if (value > 0.0)
else if (value > 0.0f)
{ {
left = (value*2)-1.0;
right = 1.0;
left = (value*2.0f)-1.0f;
right = 1.0f;
} }
else else
{ {
left = -1.0;
right = 1.0;
left = -1.0f;
right = 1.0f;
} }


setBalanceLeft(left, false, false); setBalanceLeft(left, false, false);
@@ -1199,7 +1185,7 @@ public:
} }


// Control plugin parameters // Control plugin parameters
for (k=0; k < kData->param.count; k++)
for (k=0; k < kData->param.count; ++k)
{ {
if (kData->param.data[k].midiChannel != event.channel) if (kData->param.data[k].midiChannel != event.channel)
continue; continue;
@@ -1210,7 +1196,7 @@ public:
if ((kData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0) if ((kData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0)
continue; continue;


double value;
float value;


if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN) if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
{ {
@@ -1251,8 +1237,8 @@ public:
{ {
if (! allNotesOffSent) if (! allNotesOffSent)
{ {
allNotesOffSent = true;
sendMidiAllNotesOff(); sendMidiAllNotesOff();
allNotesOffSent = true;
} }


postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 0.0f); postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 0.0f);
@@ -1377,7 +1363,7 @@ public:
if (kData->event.portOut != nullptr) if (kData->event.portOut != nullptr)
{ {
// reverse lookup MIDI events // reverse lookup MIDI events
for (k = (MAX_MIDI_EVENTS*2)-1; k >= fMidiEventCount; k--)
for (k = (MAX_MIDI_EVENTS*2)-1; k >= fMidiEventCount; --k)
{ {
if (fMidiEvents[k].type == 0) if (fMidiEvents[k].type == 0)
break; break;
@@ -1393,10 +1379,6 @@ public:
} }


} // End of Control and MIDI Output } // End of Control and MIDI Output

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

//kData->activeBefore = kData->active;
} }


bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset) bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)
@@ -1430,9 +1412,9 @@ public:
} }
else if (! kData->singleMutex.tryLock()) else if (! kData->singleMutex.tryLock())
{ {
for (i=0; i < kData->audioOut.count; i++)
for (i=0; i < kData->audioOut.count; ++i)
{ {
for (k=0; k < frames; k++)
for (k=0; k < frames; ++k)
outBuffer[i][k+timeOffset] = 0.0f; outBuffer[i][k+timeOffset] = 0.0f;
} }


@@ -1440,7 +1422,18 @@ public:
} }


// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Run plugin
// Set audio buffers

float* vstInBuffer[kData->audioIn.count];
float* vstOutBuffer[kData->audioOut.count];

for (i=0; i < kData->audioIn.count; ++i)
vstInBuffer[i] = inBuffer[i]+timeOffset;
for (i=0; i < kData->audioOut.count; ++i)
vstOutBuffer[i] = outBuffer[i]+timeOffset;

// --------------------------------------------------------------------------------------------------------
// Set MIDI events


if (fMidiEventCount > 0) if (fMidiEventCount > 0)
{ {
@@ -1449,19 +1442,13 @@ public:
dispatcher(effProcessEvents, 0, 0, &fEvents, 0.0f); dispatcher(effProcessEvents, 0, 0, &fEvents, 0.0f);
} }


float* vstInBuffer[kData->audioIn.count];
float* vstOutBuffer[kData->audioOut.count];

for (i=0; i < kData->audioIn.count; i++)
vstInBuffer[i] = inBuffer[i]+timeOffset;
for (i=0; i < kData->audioOut.count; i++)
vstOutBuffer[i] = outBuffer[i]+timeOffset;
// --------------------------------------------------------------------------------------------------------
// Run plugin


fIsProcessing = true; fIsProcessing = true;


if (fHints & PLUGIN_CAN_PROCESS_REPLACING) if (fHints & PLUGIN_CAN_PROCESS_REPLACING)
{ {

fEffect->processReplacing(fEffect, fEffect->processReplacing(fEffect,
(kData->audioIn.count > 0) ? vstInBuffer : nullptr, (kData->audioIn.count > 0) ? vstInBuffer : nullptr,
(kData->audioOut.count > 0) ? vstOutBuffer : nullptr, (kData->audioOut.count > 0) ? vstOutBuffer : nullptr,
@@ -1469,7 +1456,7 @@ public:
} }
else else
{ {
for (i=0; i < kData->audioOut.count; i++)
for (i=0; i < kData->audioOut.count; ++i)
carla_zeroFloat(vstOutBuffer[i], frames); carla_zeroFloat(vstOutBuffer[i], frames);


#if ! VST_FORCE_DEPRECATED #if ! VST_FORCE_DEPRECATED
@@ -1487,18 +1474,19 @@ public:
// Post-processing (dry/wet, volume and balance) // Post-processing (dry/wet, volume and balance)


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


bool isPair;
float bufValue, oldBufLeft[doBalance ? frames : 1]; float bufValue, oldBufLeft[doBalance ? frames : 1];


for (i=0; i < kData->audioOut.count; i++)
for (i=0; i < kData->audioOut.count; ++i)
{ {
// Dry/Wet // Dry/Wet
if (doDryWet) if (doDryWet)
{ {
for (k=0; k < frames; k++)
for (k=0; k < frames; ++k)
{ {
bufValue = inBuffer[(kData->audioIn.count == 1) ? 0 : i][k+timeOffset]; bufValue = inBuffer[(kData->audioIn.count == 1) ? 0 : i][k+timeOffset];
outBuffer[i][k+timeOffset] = (outBuffer[i][k+timeOffset] * kData->postProc.dryWet) + (bufValue * (1.0f - kData->postProc.dryWet)); outBuffer[i][k+timeOffset] = (outBuffer[i][k+timeOffset] * kData->postProc.dryWet) + (bufValue * (1.0f - kData->postProc.dryWet));
@@ -1508,15 +1496,20 @@ public:
// Balance // Balance
if (doBalance) if (doBalance)
{ {
if (i % 2 == 0)
isPair = (i % 2 == 0);

if (isPair)
{
CARLA_ASSERT(i+1 < kData->audioOut.count);
carla_copyFloat(oldBufLeft, outBuffer[i]+timeOffset, frames); carla_copyFloat(oldBufLeft, outBuffer[i]+timeOffset, frames);
}


float balRangeL = (kData->postProc.balanceLeft + 1.0f)/2.0f; float balRangeL = (kData->postProc.balanceLeft + 1.0f)/2.0f;
float balRangeR = (kData->postProc.balanceRight + 1.0f)/2.0f; float balRangeR = (kData->postProc.balanceRight + 1.0f)/2.0f;


for (k=0; k < frames; k++)
for (k=0; k < frames; ++k)
{ {
if (i % 2 == 0)
if (isPair)
{ {
// left // left
outBuffer[i][k+timeOffset] = oldBufLeft[k] * (1.0f - balRangeL); outBuffer[i][k+timeOffset] = oldBufLeft[k] * (1.0f - balRangeL);
@@ -1534,7 +1527,7 @@ public:
// Volume // Volume
if (doVolume) if (doVolume)
{ {
for (k=0; k < frames; k++)
for (k=0; k < frames; ++k)
outBuffer[i][k+timeOffset] *= kData->postProc.volume; outBuffer[i][k+timeOffset] *= kData->postProc.volume;
} }
} }
@@ -1549,11 +1542,11 @@ public:


void bufferSizeChanged(const uint32_t newBufferSize) void bufferSizeChanged(const uint32_t newBufferSize)
{ {
CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
carla_debug("VstPlugin::bufferSizeChanged(%i)", newBufferSize);

if (kData->active) if (kData->active)
{
dispatcher(effStopProcess, 0, 0, nullptr, 0.0f);
dispatcher(effMainsChanged, 0, 0, nullptr, 0.0f);
}
deactivate();


#if ! VST_FORCE_DEPRECATED #if ! VST_FORCE_DEPRECATED
dispatcher(effSetBlockSizeAndSampleRate, 0, newBufferSize, nullptr, kData->engine->getSampleRate()); dispatcher(effSetBlockSizeAndSampleRate, 0, newBufferSize, nullptr, kData->engine->getSampleRate());
@@ -1561,19 +1554,16 @@ public:
dispatcher(effSetBlockSize, 0, newBufferSize, nullptr, 0.0f); dispatcher(effSetBlockSize, 0, newBufferSize, nullptr, 0.0f);


if (kData->active) if (kData->active)
{
dispatcher(effMainsChanged, 0, 1, nullptr, 0.0f);
dispatcher(effStartProcess, 0, 0, nullptr, 0.0f);
}
activate();
} }


void sampleRateChanged(const double newSampleRate) void sampleRateChanged(const double newSampleRate)
{ {
CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
carla_debug("VstPlugin::sampleRateChanged(%g)", newSampleRate);

if (kData->active) if (kData->active)
{
dispatcher(effStopProcess, 0, 0, nullptr, 0.0f);
dispatcher(effMainsChanged, 0, 0, nullptr, 0.0f);
}
deactivate();


#if ! VST_FORCE_DEPRECATED #if ! VST_FORCE_DEPRECATED
dispatcher(effSetBlockSizeAndSampleRate, 0, kData->engine->getBufferSize(), nullptr, newSampleRate); dispatcher(effSetBlockSizeAndSampleRate, 0, kData->engine->getBufferSize(), nullptr, newSampleRate);
@@ -1581,10 +1571,7 @@ public:
dispatcher(effSetSampleRate, 0, 0, nullptr, newSampleRate); dispatcher(effSetSampleRate, 0, 0, nullptr, newSampleRate);


if (kData->active) if (kData->active)
{
dispatcher(effMainsChanged, 0, 1, nullptr, 0.0f);
dispatcher(effStartProcess, 0, 0, nullptr, 0.0f);
}
activate();
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -1810,7 +1797,7 @@ protected:
return 0; return 0;
} }


for (int32_t i=0; i < vstEvents->numEvents && events.numEvents < MAX_MIDI_EVENTS*2; i++)
for (int32_t i=0; i < vstEvents->numEvents && events.numEvents < MAX_MIDI_EVENTS*2; ++i)
{ {
if (! vstEvents->events[i]) if (! vstEvents->events[i])
break; break;
@@ -2059,13 +2046,6 @@ protected:
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------


// FIXME
#ifdef _WIN32
# define OS_SEP '\\'
#else
# define OS_SEP '/'
#endif

bool init(const char* const filename, const char* const name) bool init(const char* const filename, const char* const name)
{ {
CARLA_ASSERT(kData->engine != nullptr); CARLA_ASSERT(kData->engine != nullptr);
@@ -2153,16 +2133,16 @@ public:
} }
else else
{ {
char strBuf[STR_MAX+1] = { 0 };
char strBuf[STR_MAX+1] = { '\0' };
dispatcher(effGetEffectName, 0, 0, strBuf, 0.0f); dispatcher(effGetEffectName, 0, 0, strBuf, 0.0f);


if (strBuf[0] != 0)
if (strBuf[0] != '\0')
{ {
fName = kData->engine->getNewUniquePluginName(strBuf); fName = kData->engine->getNewUniquePluginName(strBuf);
} }
else else
{ {
const char* const label = strrchr(filename, OS_SEP)+1;
const char* const label = std::strrchr(filename, OS_SEP)+1;
fName = kData->engine->getNewUniquePluginName(label); fName = kData->engine->getNewUniquePluginName(label);
} }
} }
@@ -2223,6 +2203,35 @@ public:
} }
} }


// ---------------------------------------------------------------
// load plugin settings

{
// set default options
fOptions = 0x0;

fOptions |= PLUGIN_OPTION_FIXED_BUFFER;
fOptions |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;

if (fEffect->flags & effFlagsProgramChunks)
fOptions |= PLUGIN_OPTION_USE_CHUNKS;

//if (mIns > 0)
{
fOptions |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
fOptions |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
fOptions |= PLUGIN_OPTION_SEND_PITCHBEND;
fOptions |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
}

// load settings
kData->idStr = "VST/";
kData->idStr += std::strrchr(filename, OS_SEP)+1;
kData->idStr += "/";
kData->idStr += CarlaString(uniqueId());
fOptions = kData->loadSettings(fOptions, availableOptions());
}

return true; return true;
} }


@@ -2230,7 +2239,7 @@ private:
int fUnique1; int fUnique1;
AEffect* fEffect; AEffect* fEffect;


QByteArray fChunk;
uint8_t* fLastChunk;
uint32_t fMidiEventCount; uint32_t fMidiEventCount;
VstMidiEvent fMidiEvents[MAX_MIDI_EVENTS*2]; VstMidiEvent fMidiEvents[MAX_MIDI_EVENTS*2];
VstTimeInfo_R fTimeInfo; VstTimeInfo_R fTimeInfo;
@@ -2240,12 +2249,10 @@ private:
intptr_t reserved; intptr_t reserved;
VstEvent* data[MAX_MIDI_EVENTS*2]; VstEvent* data[MAX_MIDI_EVENTS*2];


#ifndef QTCREATOR_TEST // missing proper C++11 support
FixedVstEvents() FixedVstEvents()
: numEvents(0), : numEvents(0),
reserved(0), reserved(0),
data{0} {} data{0} {}
#endif
} fEvents; } fEvents;


struct GuiInfo { struct GuiInfo {


Loading…
Cancel
Save