Browse Source

Internal carla-rack plugin kinda works, but without UI

tags/1.9.4
falkTX 11 years ago
parent
commit
d327b08f35
9 changed files with 355 additions and 184 deletions
  1. +3
    -3
      source/backend/CarlaEngine.hpp
  2. +3
    -6
      source/backend/engine/CarlaEngine.cpp
  3. +3
    -3
      source/backend/engine/CarlaEngineJack.cpp
  4. +313
    -153
      source/backend/engine/CarlaEngineNative.cpp
  5. +3
    -3
      source/backend/engine/CarlaEngineRtAudio.cpp
  6. +7
    -0
      source/backend/plugin/CarlaPluginInternal.hpp
  7. +10
    -0
      source/backend/plugin/NativePlugin.cpp
  8. +5
    -5
      source/carla_rack.py
  9. +8
    -11
      source/modules/CarlaNative.hpp

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

@@ -185,8 +185,8 @@ struct EngineMidiEvent {
* If size > kDataSize, dataExt is used. * If size > kDataSize, dataExt is used.
*/ */
union { union {
uint8_t data[kDataSize];
uint8_t* dataExt;
uint8_t data[kDataSize];
const uint8_t* dataExt;
}; };
}; };


@@ -206,7 +206,7 @@ struct EngineEvent {
EngineMidiEvent midi; EngineMidiEvent midi;
}; };


void fillFromMidiData(const uint8_t size, uint8_t* const data);
void fillFromMidiData(const uint8_t size, const uint8_t* const data);
}; };


/*! /*!


+ 3
- 6
source/backend/engine/CarlaEngine.cpp View File

@@ -100,7 +100,7 @@ void EngineControlEvent::dumpToMidiData(const uint8_t channel, uint8_t& size, ui
} }
} }


void EngineEvent::fillFromMidiData(const uint8_t size, uint8_t* const data)
void EngineEvent::fillFromMidiData(const uint8_t size, const uint8_t* const data)
{ {
// get channel // get channel
channel = MIDI_GET_CHANNEL_FROM_DATA(data); channel = MIDI_GET_CHANNEL_FROM_DATA(data);
@@ -108,9 +108,6 @@ void EngineEvent::fillFromMidiData(const uint8_t size, uint8_t* const data)
// get status // get status
const uint8_t midiStatus(MIDI_GET_STATUS_FROM_DATA(data)); const uint8_t midiStatus(MIDI_GET_STATUS_FROM_DATA(data));


// remove channel bit from data
data[0] = midiStatus;

if (midiStatus == MIDI_STATUS_CONTROL_CHANGE) if (midiStatus == MIDI_STATUS_CONTROL_CHANGE)
{ {
type = kEngineEventTypeControl; type = kEngineEventTypeControl;
@@ -1448,7 +1445,7 @@ bool CarlaEngine::loadProject(const char* const filename)


if (addPlugin(getPluginTypeFromString(saveState.type), saveState.binary, saveState.name, saveState.label, extraStuff)) if (addPlugin(getPluginTypeFromString(saveState.type), saveState.binary, saveState.name, saveState.label, extraStuff))
{ {
if (CarlaPlugin* plugin = getPlugin(pData->curPluginCount-1))
if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1))
plugin->loadSaveState(saveState); plugin->loadSaveState(saveState);
} }
} }
@@ -1480,7 +1477,7 @@ bool CarlaEngine::saveProject(const char* const filename)


for (unsigned int i=0; i < pData->curPluginCount; ++i) for (unsigned int i=0; i < pData->curPluginCount; ++i)
{ {
CarlaPlugin* const plugin = pData->plugins[i].plugin;
CarlaPlugin* const plugin(pData->plugins[i].plugin);


if (plugin != nullptr && plugin->isEnabled()) if (plugin != nullptr && plugin->isEnabled())
{ {


+ 3
- 3
source/backend/engine/CarlaEngineJack.cpp View File

@@ -1143,9 +1143,9 @@ protected:
{ {
const EngineEvent& engineEvent(pData->bufEvents.out[i]); const EngineEvent& engineEvent(pData->bufEvents.out[i]);


uint8_t size = 0;
uint8_t data[3] = { 0, 0, 0 };
uint8_t* dataPtr = data;
uint8_t size = 0;
uint8_t data[3] = { 0, 0, 0 };
const uint8_t* dataPtr = data;


switch (engineEvent.type) switch (engineEvent.type)
{ {


+ 313
- 153
source/backend/engine/CarlaEngineNative.cpp View File

@@ -24,12 +24,14 @@


#include "CarlaNative.hpp" #include "CarlaNative.hpp"


#include <QtCore/QProcess>
#include <QtCore/QTextStream>

CARLA_BACKEND_START_NAMESPACE CARLA_BACKEND_START_NAMESPACE


#if 0
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


class CarlaEngineNativeThread : public QThread
class CarlaEngineNativeThread : public CarlaThread
{ {
public: public:
enum UiState { enum UiState {
@@ -40,17 +42,16 @@ public:
}; };


CarlaEngineNativeThread(CarlaEngine* const engine) CarlaEngineNativeThread(CarlaEngine* const engine)
: kEngine(engine),
fBinary("carla-control"),
fProcess(nullptr),
fUiState(UiNone)
: fEngine(engine),
fProcess(nullptr)/*,*/
//fUiState(UiNone)
{ {
carla_debug("CarlaEngineNativeThread::CarlaEngineNativeThread(engine:\"%s\")", engine->getName());
carla_debug("CarlaEngineNativeThread::CarlaEngineNativeThread(%p)", engine);
} }


~CarlaEngineNativeThread()
~CarlaEngineNativeThread() override
{ {
CARLA_ASSERT_INT(fUiState == UiNone, fUiState);
//CARLA_ASSERT_INT(fUiState == UiNone, fUiState);
carla_debug("CarlaEngineNativeThread::~CarlaEngineNativeThread()"); carla_debug("CarlaEngineNativeThread::~CarlaEngineNativeThread()");


if (fProcess != nullptr) if (fProcess != nullptr)
@@ -60,6 +61,7 @@ public:
} }
} }


#if 0
void setOscData(const char* const binary) void setOscData(const char* const binary)
{ {
fBinary = binary; fBinary = binary;
@@ -82,12 +84,14 @@ public:
fProcess->kill(); fProcess->kill();
//fProcess->close(); //fProcess->close();
} }
#endif


protected: protected:
void run()
void run() override
{ {
carla_debug("CarlaEngineNativeThread::run() - binary:\"%s\"", (const char*)fBinary); carla_debug("CarlaEngineNativeThread::run() - binary:\"%s\"", (const char*)fBinary);


#if 0
if (fProcess == nullptr) if (fProcess == nullptr)
{ {
fProcess = new QProcess(nullptr); fProcess = new QProcess(nullptr);
@@ -126,32 +130,32 @@ protected:
fUiState = UiCrashed; fUiState = UiCrashed;
carla_stderr("CarlaEngineNativeThread::run() - GUI crashed while running"); carla_stderr("CarlaEngineNativeThread::run() - GUI crashed while running");
} }
#endif
} }


private: private:
CarlaEngine* const kEngine;
CarlaEngine* const fEngine;


CarlaString fBinary; CarlaString fBinary;
QProcess* fProcess; QProcess* fProcess;


UiState fUiState;
// UiState fUiState;


CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineNativeThread) CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineNativeThread)
}; };


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
#endif


class CarlaEngineNative : public NativePluginClass,
public CarlaEngine
class CarlaEngineNative : public CarlaEngine
{ {
public: public:
CarlaEngineNative(const NativeHostDescriptor* const host, const bool isPatchbay) CarlaEngineNative(const NativeHostDescriptor* const host, const bool isPatchbay)
: NativePluginClass(host),
CarlaEngine(),
fIsPatchbay(isPatchbay)
/*fIsRunning(true),
fThread(this)*/
: CarlaEngine(),
pHost(host),
fIsPatchbay(isPatchbay),
fIsActive(false),
fIsRunning(false),
fThread(this)
{ {
carla_debug("CarlaEngineNative::CarlaEngineNative()"); carla_debug("CarlaEngineNative::CarlaEngineNative()");


@@ -175,6 +179,10 @@ public:
init("Carla-Rack"); init("Carla-Rack");
} }


// TESTING
//if (! addPlugin(PLUGIN_INTERNAL, nullptr, "Ping Pong Pan", "PingPongPan"))
// carla_stdout("TESTING PLUG3 ERROR:\n%s", getLastError());

#if 0 #if 0
// set control thread binary // set control thread binary
CarlaString threadBinary(getResourceDir()); CarlaString threadBinary(getResourceDir());
@@ -183,7 +191,6 @@ public:


fThread.setOscData(threadBinary); fThread.setOscData(threadBinary);


// TESTING
// if (! addPlugin(PLUGIN_INTERNAL, nullptr, "MIDI Transpose", "midiTranspose")) // if (! addPlugin(PLUGIN_INTERNAL, nullptr, "MIDI Transpose", "midiTranspose"))
// carla_stdout("TESTING PLUG1 ERROR:\n%s", getLastError()); // carla_stdout("TESTING PLUG1 ERROR:\n%s", getLastError());
// if (! addPlugin(PLUGIN_INTERNAL, nullptr, "ZynAddSubFX", "zynaddsubfx")) // if (! addPlugin(PLUGIN_INTERNAL, nullptr, "ZynAddSubFX", "zynaddsubfx"))
@@ -195,12 +202,14 @@ public:


~CarlaEngineNative() override ~CarlaEngineNative() override
{ {
CARLA_ASSERT(! fIsActive);
carla_debug("CarlaEngineNative::~CarlaEngineNative()"); carla_debug("CarlaEngineNative::~CarlaEngineNative()");


//fIsRunning = false;
pData->aboutToClose = true;
fIsRunning = false;


setAboutToClose();
removeAllPlugins(); removeAllPlugins();
runPendingRtEvents();
close(); close();
} }


@@ -212,29 +221,22 @@ protected:
{ {
carla_debug("CarlaEngineNative::init(\"%s\")", clientName); carla_debug("CarlaEngineNative::init(\"%s\")", clientName);


pData->bufferSize = NativePluginClass::getBufferSize();
pData->sampleRate = NativePluginClass::getSampleRate();
pData->bufferSize = pHost->get_buffer_size(pHost->handle);
pData->sampleRate = pHost->get_sample_rate(pHost->handle);


fIsRunning = true;
CarlaEngine::init(clientName); CarlaEngine::init(clientName);
return true; return true;
} }


bool close() override
{
carla_debug("CarlaEngineNative::close()");

runPendingRtEvents();
return CarlaEngine::close();
}

bool isRunning() const noexcept override bool isRunning() const noexcept override
{ {
return false; //fIsRunning;
return fIsRunning;
} }


bool isOffline() const noexcept override bool isOffline() const noexcept override
{ {
return false;
return pHost->is_offline(pHost->handle);
} }


EngineType getType() const noexcept override EngineType getType() const noexcept override
@@ -247,10 +249,24 @@ protected:
return "Plugin"; return "Plugin";
} }


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

void bufferSizeChanged(const uint32_t newBufferSize)
{
pData->bufferSize = newBufferSize;
CarlaEngine::bufferSizeChanged(newBufferSize);
}

void sampleRateChanged(const double newSampleRate)
{
pData->sampleRate = newSampleRate;
CarlaEngine::sampleRateChanged(newSampleRate);
}

// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Plugin parameter calls // Plugin parameter calls


uint32_t getParameterCount() const override
uint32_t getParameterCount() const
{ {
if (CarlaPlugin* const plugin = _getFirstPlugin()) if (CarlaPlugin* const plugin = _getFirstPlugin())
return plugin->getParameterCount(); return plugin->getParameterCount();
@@ -258,11 +274,11 @@ protected:
return 0; return 0;
} }


const NativeParameter* getParameterInfo(const uint32_t index) const override
const NativeParameter* getParameterInfo(const uint32_t index) const
{ {
if (CarlaPlugin* const plugin = _getFirstPlugin()) if (CarlaPlugin* const plugin = _getFirstPlugin())
{ {
if (plugin->getParameterCount() < index)
if (index < plugin->getParameterCount())
{ {
static NativeParameter param; static NativeParameter param;
static char strBufName[STR_MAX+1]; static char strBufName[STR_MAX+1];
@@ -318,22 +334,22 @@ protected:
return nullptr; return nullptr;
} }


float getParameterValue(const uint32_t index) const override
float getParameterValue(const uint32_t index) const
{ {
if (CarlaPlugin* const plugin = _getFirstPlugin()) if (CarlaPlugin* const plugin = _getFirstPlugin())
{ {
if (plugin->getParameterCount() < index)
if (index < plugin->getParameterCount())
return plugin->getParameterValue(index); return plugin->getParameterValue(index);
} }


return 0.0f; return 0.0f;
} }


const char* getParameterText(const uint32_t index, const float value) const override
const char* getParameterText(const uint32_t index, const float value) const
{ {
if (CarlaPlugin* const plugin = _getFirstPlugin()) if (CarlaPlugin* const plugin = _getFirstPlugin())
{ {
if (plugin->getParameterCount() < index)
if (index < plugin->getParameterCount())
{ {
static char strBuf[STR_MAX+1]; static char strBuf[STR_MAX+1];
carla_zeroChar(strBuf, STR_MAX+1); carla_zeroChar(strBuf, STR_MAX+1);
@@ -350,19 +366,19 @@ protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Plugin midi-program calls // Plugin midi-program calls


uint32_t getMidiProgramCount() const override
uint32_t getMidiProgramCount() const
{ {
if (CarlaPlugin* const plugin = _getFirstPlugin()) if (CarlaPlugin* const plugin = _getFirstPlugin())
return plugin->getMidiProgramCount();
return plugin->getMidiProgramCount();


return 0; return 0;
} }


const NativeMidiProgram* getMidiProgramInfo(const uint32_t index) const override
const NativeMidiProgram* getMidiProgramInfo(const uint32_t index) const
{ {
if (CarlaPlugin* const plugin = _getFirstPlugin()) if (CarlaPlugin* const plugin = _getFirstPlugin())
{ {
if (plugin->getMidiProgramCount() < index)
if (index < plugin->getMidiProgramCount())
{ {
static NativeMidiProgram midiProg; static NativeMidiProgram midiProg;


@@ -384,33 +400,25 @@ protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Plugin state calls // Plugin state calls


void setParameterValue(const uint32_t index, const float value) override
void setParameterValue(const uint32_t index, const float value)
{ {
if (CarlaPlugin* const plugin = _getFirstPlugin()) if (CarlaPlugin* const plugin = _getFirstPlugin())
{ {
if (plugin->getParameterCount() < index)
if (index < plugin->getParameterCount())
plugin->setParameterValue(index, value, false, false, false); plugin->setParameterValue(index, value, false, false, false);
} }
} }


void setMidiProgram(const uint8_t, const uint32_t bank, const uint32_t program) override
void setMidiProgram(const uint8_t, const uint32_t bank, const uint32_t program)
{ {
if (CarlaPlugin* const plugin = _getFirstPlugin()) if (CarlaPlugin* const plugin = _getFirstPlugin())
plugin->setMidiProgramById(bank, program, false, false, false); plugin->setMidiProgramById(bank, program, false, false, false);
} }


void setCustomData(const char* const key, const char* const value) override
{
CARLA_SAFE_ASSERT_RETURN(key != nullptr,);
CARLA_SAFE_ASSERT_RETURN(value != nullptr,);

// TODO
}

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


void activate() override
void activate()
{ {
#if 0 #if 0
for (uint32_t i=0; i < pData->curPluginCount; ++i) for (uint32_t i=0; i < pData->curPluginCount; ++i)
@@ -423,10 +431,12 @@ protected:
plugin->setActive(true, true, false); plugin->setActive(true, true, false);
} }
#endif #endif
fIsActive = true;
} }


void deactivate() override
void deactivate()
{ {
fIsActive = false;
#if 0 #if 0
for (uint32_t i=0; i < pData->curPluginCount; ++i) for (uint32_t i=0; i < pData->curPluginCount; ++i)
{ {
@@ -443,7 +453,7 @@ protected:
runPendingRtEvents(); runPendingRtEvents();
} }


void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount) override
void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount)
{ {
if (pData->curPluginCount == 0 && ! fIsPatchbay) if (pData->curPluginCount == 0 && ! fIsPatchbay)
{ {
@@ -456,7 +466,7 @@ protected:
// --------------------------------------------------------------- // ---------------------------------------------------------------
// Time Info // Time Info


const NativeTimeInfo* const timeInfo(NativePluginClass::getTimeInfo());
const NativeTimeInfo* const timeInfo(pHost->get_time_info(pHost->handle));


pData->timeInfo.playing = timeInfo->playing; pData->timeInfo.playing = timeInfo->playing;
pData->timeInfo.frame = timeInfo->frame; pData->timeInfo.frame = timeInfo->frame;
@@ -479,85 +489,105 @@ protected:
pData->timeInfo.bbt.beatsPerMinute = timeInfo->bbt.beatsPerMinute; pData->timeInfo.bbt.beatsPerMinute = timeInfo->bbt.beatsPerMinute;
} }


#if 0
// --------------------------------------------------------------- // ---------------------------------------------------------------
// initialize input events
// initialize events

carla_zeroStruct<EngineEvent>(pData->bufEvents.in, kEngineMaxInternalEventCount);
carla_zeroStruct<EngineEvent>(pData->bufEvents.out, kEngineMaxInternalEventCount);

// ---------------------------------------------------------------
// events input (before processing)


carla_zeroStruct<EngineEvent>(pData->bufEvents.in, INTERNAL_EVENT_COUNT);
{ {
uint32_t engineEventIndex = 0; uint32_t engineEventIndex = 0;


for (uint32_t i=0; i < midiEventCount && engineEventIndex < INTERNAL_EVENT_COUNT; ++i)
for (uint32_t i=0; i < midiEventCount && engineEventIndex < kEngineMaxInternalEventCount; ++i)
{ {
const ::MidiEvent& midiEvent(midiEvents[i]);
const NativeMidiEvent& midiEvent(midiEvents[i]);
EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]);


if (midiEvent.size > 4)
continue;
engineEvent.time = midiEvent.time;
engineEvent.fillFromMidiData(midiEvent.size, midiEvent.data);


const uint8_t status = MIDI_GET_STATUS_FROM_DATA(midiEvent.data);
const uint8_t channel = MIDI_GET_CHANNEL_FROM_DATA(midiEvent.data);
if (engineEventIndex >= kEngineMaxInternalEventCount)
break;
}
}


// we don't want some events
if (status == MIDI_STATUS_PROGRAM_CHANGE)
continue;
if (fIsPatchbay)
{
// -----------------------------------------------------------
// create audio buffers


// handle note/sound off properly
if (status == MIDI_STATUS_CONTROL_CHANGE)
{
const uint8_t control = midiEvent.data[1];
float* inBuf[2] = { inBuffer[0], inBuffer[1] };
float* outBuf[2] = { outBuffer[0], outBuffer[1] };
uint32_t bufCount[2] = { 2, 2 };


if (MIDI_IS_CONTROL_BANK_SELECT(control))
continue;
// -----------------------------------------------------------
// process


if (control == MIDI_CONTROL_ALL_SOUND_OFF || control == MIDI_CONTROL_ALL_NOTES_OFF)
{
EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]);
engineEvent.clear();
processPatchbay(inBuf, outBuf, bufCount, frames);
}
else
{
// -----------------------------------------------------------
// create audio buffers


engineEvent.type = kEngineEventTypeControl;
engineEvent.time = midiEvent.time;
engineEvent.channel = channel;
float* inBuf[2] = { inBuffer[0], inBuffer[1] };
float* outBuf[2] = { outBuffer[0], outBuffer[1] };


engineEvent.ctrl.type = (control == MIDI_CONTROL_ALL_SOUND_OFF) ? kEngineControlEventTypeAllSoundOff : kEngineControlEventTypeAllNotesOff;
engineEvent.ctrl.param = 0;
engineEvent.ctrl.value = 0.0f;
// -----------------------------------------------------------
// process


continue;
}
}
processRack(inBuf, outBuf, frames);
}


EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]);
engineEvent.clear();
// ---------------------------------------------------------------
// events output (after processing)


engineEvent.type = kEngineEventTypeMidi;
engineEvent.time = midiEvent.time;
engineEvent.channel = channel;
carla_zeroStruct<EngineEvent>(pData->bufEvents.in, kEngineMaxInternalEventCount);


engineEvent.midi.data[0] = MIDI_GET_STATUS_FROM_DATA(midiEvent.data);
engineEvent.midi.data[1] = midiEvent.data[1];
engineEvent.midi.data[2] = midiEvent.data[2];
engineEvent.midi.data[3] = midiEvent.data[3];
engineEvent.midi.size = midiEvent.size;
}
}
{
NativeMidiEvent midiEvent;


// ---------------------------------------------------------------
// create audio buffers
for (uint32_t i=0; i < kEngineMaxInternalEventCount; ++i)
{
const EngineEvent& engineEvent(pData->bufEvents.out[i]);


float* inBuf[2] = { inBuffer[0], inBuffer[1] };
float* outBuf[2] = { outBuffer[0], outBuffer[1] };
if (engineEvent.type == kEngineEventTypeNull)
break;


// ---------------------------------------------------------------
// process
midiEvent.time = engineEvent.time;


processRack(inBuf, outBuf, frames);
#endif
runPendingRtEvents();
return;
if (engineEvent.type == CarlaBackend::kEngineEventTypeControl)
{
midiEvent.port = 0;
engineEvent.ctrl.dumpToMidiData(engineEvent.channel, midiEvent.size, midiEvent.data);
}
else if (engineEvent.type == kEngineEventTypeMidi)
{
if (engineEvent.midi.size > 4 || engineEvent.midi.dataExt != nullptr)
continue;


// TODO
(void)midiEvents;
(void)midiEventCount;
midiEvent.port = engineEvent.midi.port;
midiEvent.size = engineEvent.midi.size;

midiEvent.data[0] = static_cast<uint8_t>(engineEvent.midi.data[0] + engineEvent.channel);

for (uint8_t j=1; j < midiEvent.size; ++j)
midiEvent.data[j] = engineEvent.midi.data[j];
}
else
{
carla_stderr("Unknown event type...");
continue;
}

pHost->write_midi_event(pHost->handle, &midiEvent);
}
}

runPendingRtEvents();
} }


#if 0 #if 0
@@ -632,33 +662,18 @@ protected:
(void)bank; (void)bank;
(void)program; (void)program;
} }

void uiSetCustomData(const char* const key, const char* const value) override
{
CARLA_ASSERT(key != nullptr);
CARLA_ASSERT(value != nullptr);
return;

// TODO

// unused
(void)key;
(void)value;
}
#endif #endif


#if 0
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Plugin state calls // Plugin state calls


char* getState() const override
char* getState() const
{ {
QString string; QString string;
QTextStream out(&string); QTextStream out(&string);

out << "<?xml version='1.0' encoding='UTF-8'?>\n"; out << "<?xml version='1.0' encoding='UTF-8'?>\n";
out << "<!DOCTYPE CARLA-PROJECT>\n"; out << "<!DOCTYPE CARLA-PROJECT>\n";
out << "<CARLA-PROJECT VERSION='1.0'>\n";
out << "<CARLA-PROJECT VERSION='2.0'>\n";


bool firstPlugin = true; bool firstPlugin = true;
char strBuf[STR_MAX+1]; char strBuf[STR_MAX+1];
@@ -672,9 +687,11 @@ protected:
if (! firstPlugin) if (! firstPlugin)
out << "\n"; out << "\n";


strBuf[0] = '\0';

plugin->getRealName(strBuf); plugin->getRealName(strBuf);


if (*strBuf != 0)
if (strBuf[0] != '\0')
out << QString(" <!-- %1 -->\n").arg(xmlSafeString(strBuf, true)); out << QString(" <!-- %1 -->\n").arg(xmlSafeString(strBuf, true));


QString content; QString content;
@@ -693,24 +710,24 @@ protected:
return strdup(string.toUtf8().constData()); return strdup(string.toUtf8().constData());
} }


void setState(const char* const data) override
void setState(const char* const data)
{ {
QDomDocument xml; QDomDocument xml;
xml.setContent(QString(data)); xml.setContent(QString(data));


QDomNode xmlNode(xml.documentElement()); QDomNode xmlNode(xml.documentElement());


if (xmlNode.toElement().tagName() != "CARLA-PROJECT")
if (xmlNode.toElement().tagName().compare("carla-project", Qt::CaseInsensitive) != 0)
{ {
carla_stderr2("Not a valid Carla project"); carla_stderr2("Not a valid Carla project");
return; return;
} }


QDomNode node(xmlNode.firstChild());
bool pluginsAdded = false;


while (! node.isNull())
for (QDomNode node = xmlNode.firstChild(); ! node.isNull(); node = node.nextSibling())
{ {
if (node.toElement().tagName() == "Plugin")
if (node.toElement().tagName().compare("plugin", Qt::CaseInsensitive) == 0)
{ {
SaveState saveState; SaveState saveState;
fillSaveStateFromXmlNode(saveState, node); fillSaveStateFromXmlNode(saveState, node);
@@ -719,26 +736,36 @@ protected:


const void* extraStuff = nullptr; const void* extraStuff = nullptr;


// FIXME
//if (std::strcmp(saveState.type, "DSSI") == 0)
// extraStuff = findDSSIGUI(saveState.binary, saveState.label);
// check if using GIG, SF2 or SFZ 16outs
static const char kUse16OutsSuffix[] = " (16 outs)";

if (CarlaString(saveState.label).endsWith(kUse16OutsSuffix))
{
if (std::strcmp(saveState.type, "GIG") == 0 || std::strcmp(saveState.type, "SF2") == 0 || std::strcmp(saveState.type, "SFZ") == 0)
extraStuff = (void*)0x1; // non-null
}


// TODO - proper find&load plugins // TODO - proper find&load plugins

if (addPlugin(getPluginTypeFromString(saveState.type), saveState.binary, saveState.name, saveState.label, extraStuff)) if (addPlugin(getPluginTypeFromString(saveState.type), saveState.binary, saveState.name, saveState.label, extraStuff))
{ {
if (CarlaPlugin* plugin = getPlugin(pData->curPluginCount-1))
if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1))
plugin->loadSaveState(saveState); plugin->loadSaveState(saveState);
} }
}


node = node.nextSibling();
pluginsAdded = true;
}
} }

if (pluginsAdded)
pHost->dispatcher(pHost->handle, HOST_OPCODE_RELOAD_ALL, 0, 0, nullptr, 0.0f);
} }
#endif


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


public: public:
#define handlePtr ((CarlaEngineNative*)handle)

static NativePluginHandle _instantiateRack(const NativeHostDescriptor* host) static NativePluginHandle _instantiateRack(const NativeHostDescriptor* host)
{ {
return new CarlaEngineNative(host, false); return new CarlaEngineNative(host, false);
@@ -753,15 +780,110 @@ public:


static void _cleanup(NativePluginHandle handle) static void _cleanup(NativePluginHandle handle)
{ {
delete (CarlaEngineNative*)handle;
delete handlePtr;
}

static uint32_t _get_parameter_count(NativePluginHandle handle)
{
return handlePtr->getParameterCount();
}

static const NativeParameter* _get_parameter_info(NativePluginHandle handle, uint32_t index)
{
return handlePtr->getParameterInfo(index);
}

static float _get_parameter_value(NativePluginHandle handle, uint32_t index)
{
return handlePtr->getParameterValue(index);
}

static const char* _get_parameter_text(NativePluginHandle handle, uint32_t index, float value)
{
return handlePtr->getParameterText(index, value);
}

static uint32_t _get_midi_program_count(NativePluginHandle handle)
{
return handlePtr->getMidiProgramCount();
}

static const NativeMidiProgram* _get_midi_program_info(NativePluginHandle handle, uint32_t index)
{
return handlePtr->getMidiProgramInfo(index);
}

static void _set_parameter_value(NativePluginHandle handle, uint32_t index, float value)
{
handlePtr->setParameterValue(index, value);
}

static void _set_midi_program(NativePluginHandle handle, uint8_t channel, uint32_t bank, uint32_t program)
{
handlePtr->setMidiProgram(channel, bank, program);
}

static void _activate(NativePluginHandle handle)
{
handlePtr->activate();
}

static void _deactivate(NativePluginHandle handle)
{
handlePtr->deactivate();
}

static void _process(NativePluginHandle handle, float** inBuffer, float** outBuffer, const uint32_t frames, const NativeMidiEvent* midiEvents, uint32_t midiEventCount)
{
handlePtr->process(inBuffer, outBuffer, frames, midiEvents, midiEventCount);
}

static char* _get_state(NativePluginHandle handle)
{
return handlePtr->getState();
}

static void _set_state(NativePluginHandle handle, const char* data)
{
handlePtr->setState(data);
}

static intptr_t _dispatcher(NativePluginHandle handle, NativePluginDispatcherOpcode opcode, int32_t index, intptr_t value, void* ptr, float opt)
{
switch(opcode)
{
case PLUGIN_OPCODE_NULL:
return 0;
case PLUGIN_OPCODE_BUFFER_SIZE_CHANGED:
CARLA_SAFE_ASSERT_RETURN(value > 0, 0);
handlePtr->bufferSizeChanged(static_cast<uint32_t>(value));
return 0;
case PLUGIN_OPCODE_SAMPLE_RATE_CHANGED:
handlePtr->sampleRateChanged(static_cast<double>(opt));
return 0;
case PLUGIN_OPCODE_OFFLINE_CHANGED:
handlePtr->offlineModeChanged(value != 0);
return 0;
case PLUGIN_OPCODE_UI_NAME_CHANGED:
//handlePtr->uiNameChanged(static_cast<const char*>(ptr));
return 0;
}

return 0;

// unused
(void)index;
(void)ptr;
} }


#undef handlePtr

private: private:
const NativeHostDescriptor* const pHost;

const bool fIsPatchbay; // rack if false const bool fIsPatchbay; // rack if false
#if 0
bool fIsRunning;
bool fIsActive, fIsRunning;
CarlaEngineNativeThread fThread; CarlaEngineNativeThread fThread;
#endif


CarlaPlugin* _getFirstPlugin() const noexcept CarlaPlugin* _getFirstPlugin() const noexcept
{ {
@@ -797,7 +919,26 @@ static const NativePluginDescriptor carlaRackDesc = {
/* copyright */ "GNU GPL v2+", /* copyright */ "GNU GPL v2+",
CarlaEngineNative::_instantiateRack, CarlaEngineNative::_instantiateRack,
CarlaEngineNative::_cleanup, CarlaEngineNative::_cleanup,
PluginDescriptorFILL2(CarlaEngineNative)
CarlaEngineNative::_get_parameter_count,
CarlaEngineNative::_get_parameter_info,
CarlaEngineNative::_get_parameter_value,
CarlaEngineNative::_get_parameter_text,
CarlaEngineNative::_get_midi_program_count,
CarlaEngineNative::_get_midi_program_info,
CarlaEngineNative::_set_parameter_value,
CarlaEngineNative::_set_midi_program,
/* _set_custom_data */ nullptr,
/* _ui_show */ nullptr,
/* _ui_idle */ nullptr,
/* _ui_set_parameter_value */ nullptr,
/* _ui_set_midi_program */ nullptr,
/* _ui_set_custom_data */ nullptr,
CarlaEngineNative::_activate,
CarlaEngineNative::_deactivate,
CarlaEngineNative::_process,
CarlaEngineNative::_get_state,
CarlaEngineNative::_set_state,
CarlaEngineNative::_dispatcher
}; };


#ifdef HAVE_JUCE #ifdef HAVE_JUCE
@@ -817,7 +958,26 @@ static const NativePluginDescriptor carlaPatchbayDesc = {
/* copyright */ "GNU GPL v2+", /* copyright */ "GNU GPL v2+",
CarlaEngineNative::_instantiatePatchbay, CarlaEngineNative::_instantiatePatchbay,
CarlaEngineNative::_cleanup, CarlaEngineNative::_cleanup,
PluginDescriptorFILL2(CarlaEngineNative)
CarlaEngineNative::_get_parameter_count,
CarlaEngineNative::_get_parameter_info,
CarlaEngineNative::_get_parameter_value,
CarlaEngineNative::_get_parameter_text,
CarlaEngineNative::_get_midi_program_count,
CarlaEngineNative::_get_midi_program_info,
CarlaEngineNative::_set_parameter_value,
CarlaEngineNative::_set_midi_program,
/* _set_custom_data */ nullptr,
/* _ui_show */ nullptr,
/* _ui_idle */ nullptr,
/* _ui_set_parameter_value */ nullptr,
/* _ui_set_midi_program */ nullptr,
/* _ui_set_custom_data */ nullptr,
CarlaEngineNative::_activate,
CarlaEngineNative::_deactivate,
CarlaEngineNative::_process,
CarlaEngineNative::_get_state,
CarlaEngineNative::_set_state,
CarlaEngineNative::_dispatcher
}; };
#endif #endif




+ 3
- 3
source/backend/engine/CarlaEngineRtAudio.cpp View File

@@ -865,7 +865,7 @@ protected:
FLOAT_CLEAR(fAudioBufRackOut[1], nframes); FLOAT_CLEAR(fAudioBufRackOut[1], nframes);


// initialize input events // initialize input events
carla_zeroMem(pData->bufEvents.in, sizeof(EngineEvent)*kEngineMaxInternalEventCount);
carla_zeroStruct<EngineEvent>(pData->bufEvents.in, kEngineMaxInternalEventCount);


if (fMidiInEvents.mutex.tryLock()) if (fMidiInEvents.mutex.tryLock())
{ {
@@ -874,8 +874,8 @@ protected:


while (! fMidiInEvents.data.isEmpty()) while (! fMidiInEvents.data.isEmpty())
{ {
RtMidiEvent& midiEvent(fMidiInEvents.data.getFirst(true));
EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]);
const RtMidiEvent& midiEvent(fMidiInEvents.data.getFirst(true));
EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]);


if (midiEvent.time < pData->timeInfo.frame) if (midiEvent.time < pData->timeInfo.frame)
{ {


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

@@ -454,6 +454,13 @@ struct PluginMidiProgramData {


data = new MidiProgramData[newCount]; data = new MidiProgramData[newCount];
count = newCount; count = newCount;

for (uint32_t i=0; i < count; ++i)
{
data[i].bank = 0;
data[i].program = 0;
data[i].name = nullptr;
}
} }


void clear() void clear()


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

@@ -2114,14 +2114,24 @@ protected:
// TODO // TODO
break; break;
case ::HOST_OPCODE_UPDATE_PARAMETER: case ::HOST_OPCODE_UPDATE_PARAMETER:
// TODO
pData->engine->callback(ENGINE_CALLBACK_UPDATE, pData->id, -1, 0, 0.0f, nullptr);
break; break;
case ::HOST_OPCODE_UPDATE_MIDI_PROGRAM: case ::HOST_OPCODE_UPDATE_MIDI_PROGRAM:
// TODO
pData->engine->callback(ENGINE_CALLBACK_UPDATE, pData->id, -1, 0, 0.0f, nullptr);
break; break;
case ::HOST_OPCODE_RELOAD_PARAMETERS: case ::HOST_OPCODE_RELOAD_PARAMETERS:
reload(); // FIXME
pData->engine->callback(ENGINE_CALLBACK_RELOAD_PARAMETERS, pData->id, -1, 0, 0.0f, nullptr);
break; break;
case ::HOST_OPCODE_RELOAD_MIDI_PROGRAMS: case ::HOST_OPCODE_RELOAD_MIDI_PROGRAMS:
reloadPrograms(false);
pData->engine->callback(ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, -1, 0, 0.0f, nullptr);
break; break;
case ::HOST_OPCODE_RELOAD_ALL: case ::HOST_OPCODE_RELOAD_ALL:
reload();
pData->engine->callback(ENGINE_CALLBACK_RELOAD_ALL, pData->id, -1, 0, 0.0f, nullptr);
break; break;
case HOST_OPCODE_UI_UNAVAILABLE: case HOST_OPCODE_UI_UNAVAILABLE:
pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0.0f, nullptr); pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, -1, 0, 0.0f, nullptr);


+ 5
- 5
source/carla_rack.py View File

@@ -458,7 +458,7 @@ class CarlaRackW(QListWidget):
if pitem is None: if pitem is None:
return return


pitem.ui.edit_dialog.updateInfo()
pitem.widget.ui.edit_dialog.updateInfo()


@pyqtSlot(int) @pyqtSlot(int)
def slot_handleReloadInfoCallback(self, pluginId): def slot_handleReloadInfoCallback(self, pluginId):
@@ -469,7 +469,7 @@ class CarlaRackW(QListWidget):
if pitem is None: if pitem is None:
return return


pitem.ui.edit_dialog.reloadInfo()
pitem.widget.ui.edit_dialog.reloadInfo()


@pyqtSlot(int) @pyqtSlot(int)
def slot_handleReloadParametersCallback(self, pluginId): def slot_handleReloadParametersCallback(self, pluginId):
@@ -480,7 +480,7 @@ class CarlaRackW(QListWidget):
if pitem is None: if pitem is None:
return return


pitem.ui.edit_dialog.reloadParameters()
pitem.widget.ui.edit_dialog.reloadParameters()


@pyqtSlot(int) @pyqtSlot(int)
def slot_handleReloadProgramsCallback(self, pluginId): def slot_handleReloadProgramsCallback(self, pluginId):
@@ -491,7 +491,7 @@ class CarlaRackW(QListWidget):
if pitem is None: if pitem is None:
return return


pitem.ui.edit_dialog.reloadPrograms()
pitem.widget.ui.edit_dialog.reloadPrograms()


@pyqtSlot(int) @pyqtSlot(int)
def slot_handleReloadAllCallback(self, pluginId): def slot_handleReloadAllCallback(self, pluginId):
@@ -502,6 +502,6 @@ class CarlaRackW(QListWidget):
if pitem is None: if pitem is None:
return return


pitem.ui.edit_dialog.reloadAll()
pitem.widget.ui.edit_dialog.reloadAll()


# ----------------------------------------------------------------- # -----------------------------------------------------------------

+ 8
- 11
source/modules/CarlaNative.hpp View File

@@ -567,23 +567,20 @@ public:


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


#define PluginClassEND(ClassName) \
public: \
#define PluginClassEND(ClassName) \
public: \
static NativePluginHandle _instantiate(const NativeHostDescriptor* host) \ static NativePluginHandle _instantiate(const NativeHostDescriptor* host) \
{ \
return new ClassName(host); \
} \
static void _cleanup(NativePluginHandle handle) \
{ \
delete (ClassName*)handle; \
{ \
return (host != nullptr) ? new ClassName(host) : nullptr; \
} \
static void _cleanup(NativePluginHandle handle) \
{ \
delete (ClassName*)handle; \
} }


#define PluginDescriptorFILL(ClassName) \ #define PluginDescriptorFILL(ClassName) \
ClassName::_instantiate, \ ClassName::_instantiate, \
ClassName::_cleanup, \ ClassName::_cleanup, \
PluginDescriptorFILL2(ClassName)

#define PluginDescriptorFILL2(ClassName) \
ClassName::_get_parameter_count, \ ClassName::_get_parameter_count, \
ClassName::_get_parameter_info, \ ClassName::_get_parameter_info, \
ClassName::_get_parameter_value, \ ClassName::_get_parameter_value, \


Loading…
Cancel
Save