Browse Source

More work, shared python classes almost complete

tags/1.9.4
falkTX 12 years ago
parent
commit
29ec63e799
14 changed files with 934 additions and 304 deletions
  1. +29
    -21
      source/backend/carla_engine.hpp
  2. +46
    -43
      source/backend/engine/carla_engine.cpp
  3. +5
    -5
      source/backend/engine/carla_engine.pro
  4. +4
    -4
      source/backend/engine/carla_engine_internal.hpp
  5. +9
    -11
      source/backend/engine/carla_engine_osc.cpp
  6. +217
    -203
      source/backend/engine/jack.cpp
  7. +2
    -2
      source/backend/engine/plugin.cpp
  8. +2
    -2
      source/backend/plugin/Makefile
  9. +2
    -2
      source/backend/plugin/carla_plugin.cpp
  10. +5
    -3
      source/backend/plugin/native.cpp
  11. +1
    -0
      source/backend/standalone/Makefile
  12. +2
    -1
      source/backend/standalone/carla_standalone.cpp
  13. +606
    -6
      source/carla_shared.py
  14. +4
    -1
      source/utils/carla_utils.hpp

+ 29
- 21
source/backend/carla_engine.hpp View File

@@ -308,6 +308,14 @@ struct EngineTimeInfo {
frame(0),
time(0),
valid(0x0) {}

void clear()
{
playing = false;
frame = 0;
time = 0;
valid = 0x0;
}
};

// -----------------------------------------------------------------------
@@ -539,9 +547,9 @@ private:

/*!
* Private data used in CarlaEngine.
* No other than CarlaEngine must have direct access to this.
* Non-engine code MUST NEVER have direct access to this.
*/
struct CarlaEnginePrivateData;
struct CarlaEngineProtectedData;

/*!
* Carla Engine.
@@ -857,6 +865,25 @@ protected:
EngineOptions fOptions;
EngineTimeInfo fTimeInfo;

ScopedPointer<CarlaEngineProtectedData> const fData;

/*!
* Report to all plugins about buffer size change.
*/
void bufferSizeChanged(const uint32_t newBufferSize);

/*!
* Report to all plugins about sample rate change.\n
* This is not supported on all plugin types, on which case they will be re-initiated.\n
* TODO: Not implemented yet.
*/
void sampleRateChanged(const double newSampleRate);

/*!
* TODO.
*/
void proccessPendingEvents();

#ifndef BUILD_BRIDGE
// Rack mode data
EngineEvent* getRackEventBuffer(const bool isInput);
@@ -877,26 +904,7 @@ protected:
void processPatchbay(float** inBuf, float** outBuf, const uint32_t bufCount[2], const uint32_t frames);
#endif

/*!
* TODO.
*/
void proccessPendingEvents();

/*!
* Report to all plugins about buffer size change.
*/
void bufferSizeChanged(const uint32_t newBufferSize);

/*!
* Report to all plugins about sample rate change.\n
* This is not supported on all plugin types, on which case they will be re-initiated.\n
* TODO: Not implemented yet.
*/
void sampleRateChanged(const double newSampleRate);

private:
ScopedPointer<CarlaEnginePrivateData> const fData;

#ifdef WANT_JACK
static CarlaEngine* newJack();
#endif


+ 46
- 43
source/backend/engine/carla_engine.cpp View File

@@ -182,6 +182,7 @@ void CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t
CARLA_ASSERT(fBuffer != nullptr);
CARLA_ASSERT(type != kEngineControlEventTypeNull);
CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
CARLA_ASSERT(value >= 0.0 && value <= 1.0);

if (fBuffer == nullptr)
return;
@@ -340,7 +341,7 @@ void CarlaEngineClient::setLatency(const uint32_t samples)
CarlaEngine::CarlaEngine()
: fBufferSize(0),
fSampleRate(0.0),
fData(new CarlaEnginePrivateData(this))
fData(new CarlaEngineProtectedData(this))
{
qDebug("CarlaEngine::CarlaEngine()");
}
@@ -355,7 +356,7 @@ CarlaEngine::~CarlaEngine()
// -----------------------------------------------------------------------
// Helpers

void doPluginRemove(CarlaEnginePrivateData* const fData, const bool unlock)
void doPluginRemove(CarlaEngineProtectedData* const fData, const bool unlock)
{
CARLA_ASSERT(fData->curPluginCount > 0);
fData->curPluginCount--;
@@ -511,6 +512,8 @@ bool CarlaEngine::init(const char* const clientName)
fName = clientName;
fName.toBasic();

fTimeInfo.clear();

fData->aboutToClose = false;
fData->curPluginCount = 0;

@@ -1198,6 +1201,40 @@ void CarlaEngine::setOscBridgeData(const CarlaOscData* const oscData)
// -----------------------------------------------------------------------
// protected calls

void CarlaEngine::bufferSizeChanged(const uint32_t newBufferSize)
{
qDebug("CarlaEngine::bufferSizeChanged(%i)", newBufferSize);

#if 0
for (unsigned short i=0; i < data->maxPluginNumber; i++)
{
if (data->carlaPlugins[i] && data->carlaPlugins[i]->enabled() /*&& ! data->carlaPlugins[i]->data->processHighPrecision*/)
data->carlaPlugins[i]->bufferSizeChanged(newBufferSize);
}
#endif
}

void CarlaEngine::sampleRateChanged(const double newSampleRate)
{
qDebug("CarlaEngine::sampleRateChanged(%g)", newSampleRate);

// TODO
}

void CarlaEngine::proccessPendingEvents()
{
switch (fData->nextAction.opcode)
{
case EnginePostActionNull:
break;
case EnginePostActionRemovePlugin:
doPluginRemove(fData, true);
break;
}

// TODO - peak values
}

#ifndef BUILD_BRIDGE
EngineEvent* CarlaEngine::getRackEventBuffer(const bool isInput)
{
@@ -1210,19 +1247,19 @@ void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t
// initialize outputs (zero)
carla_zeroFloat(outBuf[0], frames);
carla_zeroFloat(outBuf[1], frames);
#if 0
std::memset(rackEventsOut, 0, sizeof(EngineEvent)*MAX_EVENTS);

bool processed = false;
//std::memset(rackEventsOut, 0, sizeof(EngineEvent)*MAX_EVENTS);

bool processed = false;
// process plugins
for (unsigned short i=0, max=maxPluginNumber(); i < max; i++)
for (unsigned int i=0; i < fData->curPluginCount; i++)
{
CarlaPlugin* const plugin = getPluginUnchecked(i);

if (! (plugin && plugin->enabled()))
if (plugin == nullptr || ! plugin->enabled())
continue;

#if 0
if (processed)
{
// initialize inputs (from previous outputs)
@@ -1302,6 +1339,7 @@ void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t
data->outsPeak[i*MAX_PEAKS + 0] = outPeak1;
data->outsPeak[i*MAX_PEAKS + 1] = outPeak2;
}
#endif

processed = true;
}
@@ -1311,9 +1349,8 @@ void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t
{
std::memcpy(outBuf[0], inBuf[0], sizeof(float)*frames);
std::memcpy(outBuf[1], inBuf[1], sizeof(float)*frames);
std::memcpy(rackEventsOut, rackEventsIn, sizeof(EngineEvent)*MAX_EVENTS);
//std::memcpy(rackEventsOut, rackEventsIn, sizeof(EngineEvent)*MAX_EVENTS);
}
#endif
}

void CarlaEngine::processPatchbay(float** inBuf, float** outBuf, const uint32_t bufCount[2], const uint32_t frames)
@@ -1326,40 +1363,6 @@ void CarlaEngine::processPatchbay(float** inBuf, float** outBuf, const uint32_t
}
#endif

void CarlaEngine::proccessPendingEvents()
{
switch (fData->nextAction.opcode)
{
case EnginePostActionNull:
break;
case EnginePostActionRemovePlugin:
doPluginRemove(fData, true);
break;
}

// TODO - peak values
}

void CarlaEngine::bufferSizeChanged(const uint32_t newBufferSize)
{
qDebug("CarlaEngine::bufferSizeChanged(%i)", newBufferSize);

#if 0
for (unsigned short i=0; i < data->maxPluginNumber; i++)
{
if (data->carlaPlugins[i] && data->carlaPlugins[i]->enabled() /*&& ! data->carlaPlugins[i]->data->processHighPrecision*/)
data->carlaPlugins[i]->bufferSizeChanged(newBufferSize);
}
#endif
}

void CarlaEngine::sampleRateChanged(const double newSampleRate)
{
qDebug("CarlaEngine::sampleRateChanged(%g)", newSampleRate);

// TODO
}

// -------------------------------------------------------------------------------------------------------------------
// Carla Engine OSC stuff



+ 5
- 5
source/backend/engine/carla_engine.pro View File

@@ -1,10 +1,9 @@
# QtCreator project file

# QT = core
QT = core

CONFIG = debug
CONFIG += link_pkgconfig shared warn_on
# qt
CONFIG += link_pkgconfig qt shared warn_on

DEFINES = DEBUG
DEFINES += QTCREATOR_TEST
@@ -30,7 +29,7 @@ DEFINES += WANT_JACK WANT_RTAUDIO
PKGCONFIG = liblo jack alsa libpulse-simple

TARGET = carla_engine
TEMPLATE = app
TEMPLATE = lib
VERSION = 0.5.0

SOURCES = \
@@ -92,4 +91,5 @@ WARN_FLAGS = \
-fipa-pure-const -Wsuggest-attribute=const #pure,const,noreturn

QMAKE_CFLAGS *= $${WARN_FLAGS} -std=c99 -Wc++-compat -Wunsuffixed-float-constants -Wwrite-strings
QMAKE_CXXFLAGS *= $${WARN_FLAGS} -std=c++11 -Wzero-as-null-pointer-constant
QMAKE_CXXFLAGS *= $${WARN_FLAGS} -std=c++0x -fPIC
#QMAKE_CXXFLAGS *= $${WARN_FLAGS} -std=c++11 -Wzero-as-null-pointer-constant

+ 4
- 4
source/backend/engine/carla_engine_internal.hpp View File

@@ -135,7 +135,7 @@ struct EnginePluginData {

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

struct CarlaEnginePrivateData {
struct CarlaEngineProtectedData {
CarlaEngineOsc osc;
CarlaEngineThread thread;

@@ -172,7 +172,7 @@ struct CarlaEnginePrivateData {

EnginePluginData* plugins;

CarlaEnginePrivateData(CarlaEngine* const engine)
CarlaEngineProtectedData(CarlaEngine* const engine)
: osc(engine),
thread(engine),
oscData(nullptr),
@@ -183,9 +183,9 @@ struct CarlaEnginePrivateData {
maxPluginNumber(0),
plugins(nullptr) {}

CarlaEnginePrivateData() = delete;
CarlaEngineProtectedData() = delete;

CARLA_LEAK_DETECTOR(CarlaEnginePrivateData)
CARLA_LEAK_DETECTOR(CarlaEngineProtectedData)
};

CARLA_BACKEND_END_NAMESPACE


+ 9
- 11
source/backend/engine/carla_engine_osc.cpp View File

@@ -361,9 +361,9 @@ int CarlaEngineOsc::handleMsgRegister(const int argc, const lo_arg* const* const
qDebug("CarlaEngineOsc::handleMsgRegister()");
CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "s");

if (m_controlData.path)
if (fControlData.path != nullptr)
{
qWarning("CarlaEngineOsc::handleMsgRegister() - OSC backend already registered to %s", m_controlData.path);
qWarning("CarlaEngineOsc::handleMsgRegister() - OSC backend already registered to %s", fControlData.path);
return 1;
}

@@ -375,25 +375,23 @@ int CarlaEngineOsc::handleMsgRegister(const int argc, const lo_arg* const* const

host = lo_address_get_hostname(source);
port = lo_address_get_port(source);
m_controlData.source = lo_address_new_with_proto(LO_TCP, host, port);
fControlData.source = lo_address_new_with_proto(LO_TCP, host, port);

host = lo_url_get_hostname(url);
port = lo_url_get_port(url);
m_controlData.path = lo_url_get_path(url);
m_controlData.target = lo_address_new_with_proto(LO_TCP, host, port);
fControlData.path = lo_url_get_path(url);
fControlData.target = lo_address_new_with_proto(LO_TCP, host, port);

free((void*)host);
free((void*)port);

#if 0
for (unsigned short i=0; i < engine->maxPluginNumber(); i++)
for (unsigned short i=0; i < kEngine->currentPluginCount(); i++)
{
CarlaPlugin* const plugin = engine->getPluginUnchecked(i);
CarlaPlugin* const plugin = kEngine->getPluginUnchecked(i);

if (plugin && plugin->enabled())
plugin->registerToOscClient();
}
#endif

return 0;
}
@@ -402,13 +400,13 @@ int CarlaEngineOsc::handleMsgUnregister()
{
qDebug("CarlaEngineOsc::handleMsgUnregister()");

if (! m_controlData.path)
if (fControlData.path == nullptr)
{
qWarning("CarlaEngineOsc::handleMsgUnregister() - OSC backend is not registered yet");
return 1;
}

m_controlData.free();
fControlData.free();
return 0;
}
#endif


+ 217
- 203
source/backend/engine/jack.cpp View File

@@ -37,18 +37,18 @@ class CarlaEngineJackAudioPort : public CarlaEngineAudioPort
public:
CarlaEngineJackAudioPort(const bool isInput, const ProcessMode processMode, jack_client_t* const client, jack_port_t* const port)
: CarlaEngineAudioPort(isInput, processMode),
m_client(client),
m_port(port)
kClient(client),
kPort(port)
{
qDebug("CarlaEngineJackAudioPort::CarlaEngineJackAudioPort(%s, %s, %p, %p)", bool2str(isInput), ProcessMode2Str(processMode), client, port);

if (processMode == PROCESS_MODE_SINGLE_CLIENT || processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
{
CARLA_ASSERT(m_client && m_port);
CARLA_ASSERT(client != nullptr && port != nullptr);
}
else
{
CARLA_ASSERT(! (m_client || m_port));
CARLA_ASSERT(client == nullptr && port == nullptr);
}
}

@@ -56,29 +56,29 @@ public:
{
qDebug("CarlaEngineJackAudioPort::~CarlaEngineJackAudioPort()");

if (m_client && m_port)
jackbridge_port_unregister(m_client, m_port);
if (kClient != nullptr && kPort != nullptr)
jackbridge_port_unregister(kClient, kPort);
}

void initBuffer(CarlaEngine* const engine)
{
CARLA_ASSERT(engine);
CARLA_ASSERT(engine != nullptr);

if (! engine)
if (engine == nullptr)
{
fBuffer = nullptr;
return;
}

if (! m_port)
if (kPort == nullptr)
return CarlaEngineAudioPort::initBuffer(engine);

fBuffer = (float*)jackbridge_port_get_buffer(m_port, engine->getBufferSize());
fBuffer = (float*)jackbridge_port_get_buffer(kPort, engine->getBufferSize());
}

private:
jack_client_t* const m_client;
jack_port_t* const m_port;
jack_client_t* const kClient;
jack_port_t* const kPort;

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackAudioPort)
};
@@ -91,18 +91,19 @@ class CarlaEngineJackEventPort : public CarlaEngineEventPort
public:
CarlaEngineJackEventPort(const bool isInput, const ProcessMode processMode, jack_client_t* const client, jack_port_t* const port)
: CarlaEngineEventPort(isInput, processMode),
m_client(client),
m_port(port)
kClient(client),
kPort(port),
fJackBuffer(nullptr)
{
qDebug("CarlaEngineJackEventPort::CarlaEngineJackEventPort(%s, %s, %p, %p)", bool2str(isInput), ProcessMode2Str(processMode), client, port);

if (processMode == PROCESS_MODE_SINGLE_CLIENT || processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
{
CARLA_ASSERT(m_client && m_port);
CARLA_ASSERT(client != nullptr && port != nullptr);
}
else
{
CARLA_ASSERT(! (m_client || m_port));
CARLA_ASSERT(client == nullptr && port == nullptr);
}
}

@@ -110,140 +111,141 @@ public:
{
qDebug("CarlaEngineJackEventPort::~CarlaEngineJackEventPort()");

if (m_client && m_port)
jackbridge_port_unregister(m_client, m_port);
if (kClient != nullptr && kPort != nullptr)
jackbridge_port_unregister(kClient, kPort);
}

void initBuffer(CarlaEngine* const engine)
{
CARLA_ASSERT(engine);
CARLA_ASSERT(engine != nullptr);

if (! engine)
if (engine == nullptr)
{
fBuffer = nullptr;
fJackBuffer = nullptr;
return;
}

if (! m_port)
if (kPort == nullptr)
return CarlaEngineEventPort::initBuffer(engine);

fBuffer = jackbridge_port_get_buffer(m_port, engine->getBufferSize());
fJackBuffer = jackbridge_port_get_buffer(kPort, engine->getBufferSize());

if (! kIsInput)
jackbridge_midi_clear_buffer(fBuffer);
jackbridge_midi_clear_buffer(fJackBuffer);
}

uint32_t getEventCount()
{
if (! m_port)
if (kPort == nullptr)
return CarlaEngineEventPort::getEventCount();

if (! kIsInput)
return 0;

CARLA_ASSERT(fBuffer);
CARLA_ASSERT(fJackBuffer != nullptr);

if (! fBuffer)
if (fJackBuffer != nullptr)
return 0;

return jackbridge_midi_get_event_count(fBuffer);
return jackbridge_midi_get_event_count(fJackBuffer);
}

const EngineEvent* getEvent(const uint32_t index)
{
if (! m_port)
if (kPort == nullptr)
return CarlaEngineEventPort::getEvent(index);

if (! kIsInput)
return nullptr;

CARLA_ASSERT(fBuffer);
CARLA_ASSERT(fJackBuffer != nullptr);

if (! fBuffer)
if (fJackBuffer != nullptr)
return nullptr;

jack_midi_event_t jackEvent;

if (jackbridge_midi_event_get(&jackEvent, fBuffer, index) != 0 || jackEvent.size > 3)
if (jackbridge_midi_event_get(&jackEvent, fJackBuffer, index) != 0 || jackEvent.size > 3)
return nullptr;

m_retEvent.clear();
fRetEvent.clear();

const uint8_t midiStatus = MIDI_GET_STATUS_FROM_DATA(jackEvent.buffer);
const uint8_t midiChannel = MIDI_GET_CHANNEL_FROM_DATA(jackEvent.buffer);

m_retEvent.time = jackEvent.time;
m_retEvent.channel = midiChannel;
fRetEvent.time = jackEvent.time;
fRetEvent.channel = midiChannel;

if (MIDI_IS_STATUS_CONTROL_CHANGE(midiStatus))
{
const uint8_t midiControl = jackEvent.buffer[1];
m_retEvent.type = kEngineEventTypeControl;
fRetEvent.type = kEngineEventTypeControl;

if (MIDI_IS_CONTROL_BANK_SELECT(midiControl))
{
const uint8_t midiBank = jackEvent.buffer[2];

m_retEvent.ctrl.type = kEngineControlEventTypeMidiBank;
m_retEvent.ctrl.parameter = midiBank;
m_retEvent.ctrl.value = 0.0;
fRetEvent.ctrl.type = kEngineControlEventTypeMidiBank;
fRetEvent.ctrl.parameter = midiBank;
fRetEvent.ctrl.value = 0.0;
}
else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF)
{
m_retEvent.ctrl.type = kEngineControlEventTypeAllSoundOff;
m_retEvent.ctrl.parameter = 0;
m_retEvent.ctrl.value = 0.0;
fRetEvent.ctrl.type = kEngineControlEventTypeAllSoundOff;
fRetEvent.ctrl.parameter = 0;
fRetEvent.ctrl.value = 0.0;
}
else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF)
{
m_retEvent.ctrl.type = kEngineControlEventTypeAllNotesOff;
m_retEvent.ctrl.parameter = 0;
m_retEvent.ctrl.value = 0.0;
fRetEvent.ctrl.type = kEngineControlEventTypeAllNotesOff;
fRetEvent.ctrl.parameter = 0;
fRetEvent.ctrl.value = 0.0;
}
else
{
const uint8_t midiValue = jackEvent.buffer[2];

m_retEvent.ctrl.type = kEngineControlEventTypeParameter;
m_retEvent.ctrl.parameter = midiControl;
m_retEvent.ctrl.value = double(midiValue)/127;
fRetEvent.ctrl.type = kEngineControlEventTypeParameter;
fRetEvent.ctrl.parameter = midiControl;
fRetEvent.ctrl.value = double(midiValue)/127;
}
}
else if (MIDI_IS_STATUS_PROGRAM_CHANGE(midiStatus))
{
const uint8_t midiProgram = jackEvent.buffer[1];
m_retEvent.type = kEngineEventTypeControl;
fRetEvent.type = kEngineEventTypeControl;

m_retEvent.ctrl.type = kEngineControlEventTypeMidiProgram;
m_retEvent.ctrl.parameter = midiProgram;
m_retEvent.ctrl.value = 0.0;
fRetEvent.ctrl.type = kEngineControlEventTypeMidiProgram;
fRetEvent.ctrl.parameter = midiProgram;
fRetEvent.ctrl.value = 0.0;
}
else
{
m_retEvent.type = kEngineEventTypeMidi;
fRetEvent.type = kEngineEventTypeMidi;

m_retEvent.midi.data[0] = midiStatus;
m_retEvent.midi.data[1] = jackEvent.buffer[1];
m_retEvent.midi.data[2] = jackEvent.buffer[2];
m_retEvent.midi.size = jackEvent.size;
fRetEvent.midi.data[0] = midiStatus;
fRetEvent.midi.data[1] = jackEvent.buffer[1];
fRetEvent.midi.data[2] = jackEvent.buffer[2];
fRetEvent.midi.size = jackEvent.size;
}

return &m_retEvent;
return &fRetEvent;
}

void writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t parameter, const double value)
{
if (! m_port)
if (kPort == nullptr)
return CarlaEngineEventPort::writeControlEvent(time, channel, type, parameter, value);

if (kIsInput)
return;

CARLA_ASSERT(fBuffer);
CARLA_ASSERT(fJackBuffer != nullptr);
CARLA_ASSERT(type != kEngineControlEventTypeNull);
CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
CARLA_ASSERT(value >= 0.0 && value <= 1.0);

if (! fBuffer)
if (fJackBuffer == nullptr)
return;
if (type == kEngineControlEventTypeNull)
return;
@@ -291,23 +293,23 @@ public:
}

if (size > 0)
jackbridge_midi_event_write(fBuffer, time, data, size);
jackbridge_midi_event_write(fJackBuffer, time, data, size);
}

void writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t* const data, const uint8_t size)
{
if (! m_port)
if (kPort == nullptr)
return CarlaEngineEventPort::writeMidiEvent(time, channel, data, size);

if (kIsInput)
return;

CARLA_ASSERT(fBuffer);
CARLA_ASSERT(fJackBuffer != nullptr);
CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
CARLA_ASSERT(data);
CARLA_ASSERT(size > 0);

if (! fBuffer)
if (fJackBuffer == nullptr)
return;
if (channel >= MAX_MIDI_CHANNELS)
return;
@@ -319,16 +321,15 @@ public:

jdata[0] = data[0] + channel;

jackbridge_midi_event_write(fBuffer, time, jdata, size);
jackbridge_midi_event_write(fJackBuffer, time, jdata, size);
}

private:
void* fBuffer;

jack_client_t* const m_client;
jack_port_t* const m_port;
jack_client_t* const kClient;
jack_port_t* const kPort;

EngineEvent m_retEvent;
void* fJackBuffer;
EngineEvent fRetEvent;

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackEventPort)
};
@@ -341,15 +342,19 @@ class CarlaEngineJackClient : public CarlaEngineClient
public:
CarlaEngineJackClient(const EngineType engineType, const ProcessMode processMode, jack_client_t* const client)
: CarlaEngineClient(engineType, processMode),
m_client(client),
m_usesClient(processMode == PROCESS_MODE_SINGLE_CLIENT || processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
kClient(client),
kUseClient(processMode == PROCESS_MODE_SINGLE_CLIENT || processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
{
qDebug("CarlaEngineJackClient::CarlaEngineJackClient(%s, %s, %p)", EngineType2Str(engineType), ProcessMode2Str(processMode), client);

if (m_usesClient)
CARLA_ASSERT(m_client);
if (kUseClient)
{
CARLA_ASSERT(kClient != nullptr);
}
else
CARLA_ASSERT(! m_client);
{
CARLA_ASSERT(kClient == nullptr);
}
}

~CarlaEngineJackClient()
@@ -358,8 +363,8 @@ public:

if (kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS)
{
if (m_client)
jackbridge_client_close(m_client);
if (kClient)
jackbridge_client_close(kClient);
}
}

@@ -369,10 +374,10 @@ public:

if (kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS)
{
CARLA_ASSERT(m_client && ! isActive());
CARLA_ASSERT(kClient && ! isActive());

if (m_client && ! isActive())
jackbridge_activate(m_client);
if (kClient && ! isActive())
jackbridge_activate(kClient);
}

CarlaEngineClient::activate();
@@ -384,10 +389,10 @@ public:

if (kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS)
{
CARLA_ASSERT(m_client && isActive());
CARLA_ASSERT(kClient && isActive());

if (m_client && isActive())
jackbridge_deactivate(m_client);
if (kClient && isActive())
jackbridge_deactivate(kClient);
}

CarlaEngineClient::deactivate();
@@ -397,8 +402,8 @@ public:
{
qDebug("CarlaEngineClient::isOk()");

if (m_usesClient)
return bool(m_client);
if (kUseClient)
return bool(kClient);

return CarlaEngineClient::isOk();
}
@@ -407,8 +412,8 @@ public:
{
CarlaEngineClient::setLatency(samples);

if (m_usesClient)
jackbridge_recompute_total_latencies(m_client);
if (kUseClient)
jackbridge_recompute_total_latencies(kClient);
}

const CarlaEnginePort* addPort(const EnginePortType portType, const char* const name, const bool isInput)
@@ -418,17 +423,17 @@ public:
jack_port_t* port = nullptr;

// Create Jack port if needed
if (m_usesClient)
if (kUseClient)
{
switch (portType)
{
case kEnginePortTypeNull:
break;
case kEnginePortTypeAudio:
port = jackbridge_port_register(m_client, name, JACK_DEFAULT_AUDIO_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0);
port = jackbridge_port_register(kClient, name, JACK_DEFAULT_AUDIO_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0);
break;
case kEnginePortTypeEvent:
port = jackbridge_port_register(m_client, name, JACK_DEFAULT_MIDI_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0);
port = jackbridge_port_register(kClient, name, JACK_DEFAULT_MIDI_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0);
break;
}
}
@@ -439,9 +444,9 @@ public:
case kEnginePortTypeNull:
break;
case kEnginePortTypeAudio:
return new CarlaEngineJackAudioPort(isInput, kProcessMode, m_client, port);
return new CarlaEngineJackAudioPort(isInput, kProcessMode, kClient, port);
case kEnginePortTypeEvent:
return new CarlaEngineJackEventPort(isInput, kProcessMode, m_client, port);
return new CarlaEngineJackEventPort(isInput, kProcessMode, kClient, port);
}

qCritical("CarlaJackEngineClient::addPort(%s, \"%s\", %s) - invalid type", EnginePortType2Str(portType), name, bool2str(isInput));
@@ -449,8 +454,8 @@ public:
}

private:
jack_client_t* const m_client;
const bool m_usesClient;
jack_client_t* const kClient;
const bool kUseClient;

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackClient)
};
@@ -462,30 +467,29 @@ class CarlaEngineJack : public CarlaEngine
{
public:
CarlaEngineJack()
: CarlaEngine()
#ifndef BUILD_BRIDGE
, fRackPorts{nullptr}
: CarlaEngine(),
#ifdef BUILD_BRIDGE
fHasQuit(false),
#else
fClient(nullptr),
fTransportState(JackTransportStopped),
fRackPorts{nullptr},
#endif
fFreewheel(false)
{
qDebug("CarlaEngineJack::CarlaEngineJack()");

m_client = nullptr;
m_state = JackTransportStopped;
m_freewheel = false;

memset(&m_pos, 0, sizeof(jack_position_t));

#ifdef BUILD_BRIDGE
m_hasQuit = false;

fOptions.processMode = PROCESS_MODE_MULTIPLE_CLIENTS;
#endif

carla_zeroStruct<jack_position_t>(fTransportPos);
}

~CarlaEngineJack()
{
qDebug("CarlaEngineJack::~CarlaEngineJack()");
CARLA_ASSERT(! m_client);
CARLA_ASSERT(fClient == nullptr);
}

// -------------------------------------------------------------------
@@ -518,37 +522,39 @@ public:
{
qDebug("CarlaEngineJack::init(\"%s\")", clientName);

m_state = JackTransportStopped;
m_freewheel = false;
fFreewheel = false;
fTransportState = JackTransportStopped;

carla_zeroStruct<jack_position_t>(fTransportPos);

#ifndef BUILD_BRIDGE
m_client = jackbridge_client_open(clientName, JackNullOption, nullptr);
fClient = jackbridge_client_open(clientName, JackNullOption, nullptr);

if (m_client)
if (fClient)
{
fBufferSize = jackbridge_get_buffer_size(m_client);
fSampleRate = jackbridge_get_sample_rate(m_client);
fBufferSize = jackbridge_get_buffer_size(fClient);
fSampleRate = jackbridge_get_sample_rate(fClient);

jackbridge_set_buffer_size_callback(m_client, carla_jack_bufsize_callback, this);
jackbridge_set_sample_rate_callback(m_client, carla_jack_srate_callback, this);
jackbridge_set_freewheel_callback(m_client, carla_jack_freewheel_callback, this);
jackbridge_set_process_callback(m_client, carla_jack_process_callback, this);
jackbridge_set_latency_callback(m_client, carla_jack_latency_callback, this);
jackbridge_on_shutdown(m_client, carla_jack_shutdown_callback, this);
jackbridge_set_buffer_size_callback(fClient, carla_jack_bufsize_callback, this);
jackbridge_set_sample_rate_callback(fClient, carla_jack_srate_callback, this);
jackbridge_set_freewheel_callback(fClient, carla_jack_freewheel_callback, this);
jackbridge_set_process_callback(fClient, carla_jack_process_callback, this);
jackbridge_set_latency_callback(fClient, carla_jack_latency_callback, this);
jackbridge_on_shutdown(fClient, carla_jack_shutdown_callback, this);

if (fOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK)
{
fRackPorts[rackPortAudioIn1] = jackbridge_port_register(m_client, "audio-in1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
fRackPorts[rackPortAudioIn2] = jackbridge_port_register(m_client, "audio-in2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
fRackPorts[rackPortAudioOut1] = jackbridge_port_register(m_client, "audio-out1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
fRackPorts[rackPortAudioOut2] = jackbridge_port_register(m_client, "audio-out2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
fRackPorts[rackPortEventIn] = jackbridge_port_register(m_client, "events-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
fRackPorts[rackPortEventOut] = jackbridge_port_register(m_client, "events-out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
fRackPorts[rackPortAudioIn1] = jackbridge_port_register(fClient, "audio-in1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
fRackPorts[rackPortAudioIn2] = jackbridge_port_register(fClient, "audio-in2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
fRackPorts[rackPortAudioOut1] = jackbridge_port_register(fClient, "audio-out1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
fRackPorts[rackPortAudioOut2] = jackbridge_port_register(fClient, "audio-out2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
fRackPorts[rackPortEventIn] = jackbridge_port_register(fClient, "events-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
fRackPorts[rackPortEventOut] = jackbridge_port_register(fClient, "events-out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
}

if (jackbridge_activate(m_client) == 0)
if (jackbridge_activate(fClient) == 0)
{
const char* const clientName = jackbridge_get_client_name(m_client);
const char* const clientName = jackbridge_get_client_name(fClient);

CarlaEngine::init(clientName);
return true;
@@ -556,7 +562,7 @@ public:
else
{
setLastError("Failed to activate the JACK client");
m_client = nullptr;
fClient = nullptr;
}
}
else
@@ -567,15 +573,15 @@ public:
// open temp client to get initial buffer-size and sample-rate values
if (fBufferSize == 0 || fSampleRate == 0.0)
{
m_client = jackbridge_client_open(clientName, JackNullOption, nullptr);
fClient = jackbridge_client_open(clientName, JackNullOption, nullptr);

if (m_client)
if (fClient)
{
fBufferSize = jackbridge_get_buffer_size(m_client);
fSampleRate = jackbridge_get_sample_rate(m_client);
fBufferSize = jackbridge_get_buffer_size(fClient);
fSampleRate = jackbridge_get_sample_rate(fClient);

jackbridge_client_close(m_client);
m_client = nullptr;
jackbridge_client_close(fClient);
fClient = nullptr;
}
}

@@ -590,25 +596,25 @@ public:
CarlaEngine::close();

#ifdef BUILD_BRIDGE
m_client = nullptr;
m_hasQuit = true;
fClient = nullptr;
fHasQuit = true;
return true;
#else
if (jackbridge_deactivate(m_client) == 0)
if (jackbridge_deactivate(fClient) == 0)
{
if (fOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK)
{
jackbridge_port_unregister(m_client, fRackPorts[rackPortAudioIn1]);
jackbridge_port_unregister(m_client, fRackPorts[rackPortAudioIn2]);
jackbridge_port_unregister(m_client, fRackPorts[rackPortAudioOut1]);
jackbridge_port_unregister(m_client, fRackPorts[rackPortAudioOut2]);
jackbridge_port_unregister(m_client, fRackPorts[rackPortEventIn]);
jackbridge_port_unregister(m_client, fRackPorts[rackPortEventOut]);
jackbridge_port_unregister(fClient, fRackPorts[rackPortAudioIn1]);
jackbridge_port_unregister(fClient, fRackPorts[rackPortAudioIn2]);
jackbridge_port_unregister(fClient, fRackPorts[rackPortAudioOut1]);
jackbridge_port_unregister(fClient, fRackPorts[rackPortAudioOut2]);
jackbridge_port_unregister(fClient, fRackPorts[rackPortEventIn]);
jackbridge_port_unregister(fClient, fRackPorts[rackPortEventOut]);
}

if (jackbridge_client_close(m_client) == 0)
if (jackbridge_client_close(fClient) == 0)
{
m_client = nullptr;
fClient = nullptr;
return true;
}
else
@@ -617,7 +623,7 @@ public:
else
setLastError("Failed to deactivate the JACK client");

m_client = nullptr;
fClient = nullptr;
#endif
return false;
}
@@ -625,15 +631,15 @@ public:
bool isRunning() const
{
#ifdef BUILD_BRIDGE
return bool(m_client || ! m_hasQuit);
return (fClient != nullptr || ! m_hasQuit);
#else
return bool(m_client);
return (fClient != nullptr);
#endif
}

bool isOffline() const
{
return m_freewheel;
return fFreewheel;
}

EngineType type() const
@@ -646,7 +652,7 @@ public:
jack_client_t* client = nullptr;

#ifdef BUILD_BRIDGE
client = m_client = jackbridge_client_open(plugin->name(), JackNullOption, nullptr);
client = fClient = jackbridge_client_open(plugin->name(), JackNullOption, nullptr);

fBufferSize = jackbridge_get_buffer_size(client);
fSampleRate = jackbridge_get_sample_rate(client);
@@ -660,7 +666,7 @@ public:
#else
if (fOptions.processMode == PROCESS_MODE_SINGLE_CLIENT)
{
client = m_client;
client = fClient;
}
else if (fOptions.processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
{
@@ -682,57 +688,66 @@ public:
protected:
void handleJackBufferSizeCallback(const uint32_t newBufferSize)
{
fBufferSize = newBufferSize;
if (fBufferSize != newBufferSize)
{
fBufferSize = newBufferSize;

bufferSizeChanged(newBufferSize);
bufferSizeChanged(newBufferSize);
}
}

void handleJackSampleRateCallback(const double newSampleRate)
{
fSampleRate = newSampleRate;
if (fSampleRate != newSampleRate)
{
fSampleRate = newSampleRate;

sampleRateChanged(newSampleRate);
}
}

void handleJackFreewheelCallback(const bool isFreewheel)
{
m_freewheel = isFreewheel;
fFreewheel = isFreewheel;
}

void handleJackProcessCallback(const uint32_t nframes)
{
#ifndef BUILD_BRIDGE
if (currentPluginCount() == 0)
if (fData->curPluginCount == 0)
return;
#endif

m_pos.unique_1 = m_pos.unique_2 + 1; // invalidate
m_state = jackbridge_transport_query(m_client, &m_pos);
fTransportPos.unique_1 = fTransportPos.unique_2 + 1; // invalidate

fTransportState = jackbridge_transport_query(fClient, &fTransportPos);

fTimeInfo.playing = (m_state != JackTransportStopped);
fTimeInfo.playing = (fTransportState == JackTransportRolling);

if (m_pos.unique_1 == m_pos.unique_2)
if (fTransportPos.unique_1 == fTransportPos.unique_2)
{
fTimeInfo.frame = m_pos.frame;
fTimeInfo.time = m_pos.usecs;
fTimeInfo.frame = fTransportPos.frame;
fTimeInfo.time = fTransportPos.usecs;

if (m_pos.valid & JackPositionBBT)
if (fTransportPos.valid & JackPositionBBT)
{
fTimeInfo.valid = EngineTimeInfo::ValidBBT;
fTimeInfo.bbt.bar = m_pos.bar;
fTimeInfo.bbt.beat = m_pos.beat;
fTimeInfo.bbt.tick = m_pos.tick;
fTimeInfo.bbt.barStartTick = m_pos.bar_start_tick;
fTimeInfo.bbt.beatsPerBar = m_pos.beats_per_bar;
fTimeInfo.bbt.beatType = m_pos.beat_type;
fTimeInfo.bbt.ticksPerBeat = m_pos.ticks_per_beat;
fTimeInfo.bbt.beatsPerMinute = m_pos.beats_per_minute;
fTimeInfo.valid = EngineTimeInfo::ValidBBT;
fTimeInfo.bbt.bar = fTransportPos.bar;
fTimeInfo.bbt.beat = fTransportPos.beat;
fTimeInfo.bbt.tick = fTransportPos.tick;
fTimeInfo.bbt.barStartTick = fTransportPos.bar_start_tick;
fTimeInfo.bbt.beatsPerBar = fTransportPos.beats_per_bar;
fTimeInfo.bbt.beatType = fTransportPos.beat_type;
fTimeInfo.bbt.ticksPerBeat = fTransportPos.ticks_per_beat;
fTimeInfo.bbt.beatsPerMinute = fTransportPos.beats_per_minute;
}
else
fTimeInfo.valid = 0;
fTimeInfo.valid = 0x0;
}
else
{
fTimeInfo.frame = 0;
fTimeInfo.valid = 0;
fTimeInfo.valid = 0x0;
}

#ifdef BUILD_BRIDGE
@@ -744,9 +759,9 @@ protected:
processPlugin(plugin, nframes);
}
#else
if (options.processMode == PROCESS_MODE_SINGLE_CLIENT)
if (fOptions.processMode == PROCESS_MODE_SINGLE_CLIENT)
{
for (unsigned short i=0, max=maxPluginNumber(); i < max; i++)
for (unsigned int i=0; i < fData->curPluginCount; i++)
{
CarlaPlugin* const plugin = getPluginUnchecked(i);

@@ -757,32 +772,29 @@ protected:
}
}
}
else if (options.processMode == PROCESS_MODE_CONTINUOUS_RACK)
else if (fOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK)
{
// get buffers from jack
float* audioIn1 = (float*)jackbridge_port_get_buffer(m_rackPorts[rackPortAudioIn1], nframes);
float* audioIn2 = (float*)jackbridge_port_get_buffer(m_rackPorts[rackPortAudioIn2], nframes);
float* audioOut1 = (float*)jackbridge_port_get_buffer(m_rackPorts[rackPortAudioOut1], nframes);
float* audioOut2 = (float*)jackbridge_port_get_buffer(m_rackPorts[rackPortAudioOut2], nframes);
void* controlIn = jackbridge_port_get_buffer(m_rackPorts[rackPortControlIn], nframes);
void* controlOut = jackbridge_port_get_buffer(m_rackPorts[rackPortControlOut], nframes);
void* midiIn = jackbridge_port_get_buffer(m_rackPorts[rackPortMidiIn], nframes);
void* midiOut = jackbridge_port_get_buffer(m_rackPorts[rackPortMidiOut], nframes);
float* const audioIn1 = (float*)jackbridge_port_get_buffer(fRackPorts[rackPortAudioIn1], nframes);
float* const audioIn2 = (float*)jackbridge_port_get_buffer(fRackPorts[rackPortAudioIn2], nframes);
float* const audioOut1 = (float*)jackbridge_port_get_buffer(fRackPorts[rackPortAudioOut1], nframes);
float* const audioOut2 = (float*)jackbridge_port_get_buffer(fRackPorts[rackPortAudioOut2], nframes);
void* const eventIn = jackbridge_port_get_buffer(fRackPorts[rackPortEventIn], nframes);
void* const eventOut = jackbridge_port_get_buffer(fRackPorts[rackPortEventOut], nframes);

// assert buffers
CARLA_ASSERT(audioIn1);
CARLA_ASSERT(audioIn2);
CARLA_ASSERT(audioOut1);
CARLA_ASSERT(audioOut2);
CARLA_ASSERT(controlIn);
CARLA_ASSERT(controlOut);
CARLA_ASSERT(midiIn);
CARLA_ASSERT(midiOut);
CARLA_ASSERT(audioIn1 != nullptr);
CARLA_ASSERT(audioIn2 != nullptr);
CARLA_ASSERT(audioOut1 != nullptr);
CARLA_ASSERT(audioOut2 != nullptr);
CARLA_ASSERT(eventIn != nullptr);
CARLA_ASSERT(eventOut != nullptr);

// create audio buffers
float* inBuf[2] = { audioIn1, audioIn2 };
float* outBuf[2] = { audioOut1, audioOut2 };

#if 0
// initialize control input
memset(rackControlEventsIn, 0, sizeof(CarlaEngineControlEvent)*MAX_CONTROL_EVENTS);
{
@@ -859,10 +871,12 @@ protected:
}
}
}
#endif

// process rack
processRack(inBuf, outBuf, nframes);

#if 0
// output control
{
jackbridge_midi_clear_buffer(controlOut);
@@ -923,6 +937,7 @@ protected:
jackbridge_midi_event_write(midiOut, rackMidiEventsOut[i].time, rackMidiEventsOut[i].data, rackMidiEventsOut[i].size);
}
}
#endif
}
#endif

@@ -936,7 +951,7 @@ protected:
return;
#endif

for (unsigned short i=0, max=maxPluginNumber(); i < max; i++)
for (unsigned int i=0; i < fData->curPluginCount; i++)
{
CarlaPlugin* const plugin = getPluginUnchecked(i);

@@ -947,7 +962,7 @@ protected:

void handleJackShutdownCallback()
{
for (unsigned short i=0, max=maxPluginNumber(); i < max; i++)
for (unsigned int i=0; i < fData->curPluginCount; i++)
{
//CarlaPlugin* const plugin = getPluginUnchecked(i);

@@ -955,22 +970,21 @@ protected:
// plugin->x_client = nullptr;
}

m_client = nullptr;
fClient = nullptr;
callback(CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr);
}

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

private:
jack_client_t* m_client;
jack_transport_state_t m_state;
jack_position_t m_pos;
bool m_freewheel;
jack_client_t* fClient;
jack_position_t fTransportPos;
jack_transport_state_t fTransportState;

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

#ifdef BUILD_BRIDGE
bool m_hasQuit;
bool fHasQuit;
#else
enum RackPorts {
rackPortAudioIn1 = 0,
@@ -985,6 +999,8 @@ private:
jack_port_t* fRackPorts[rackPortCount];
#endif

bool fFreewheel;

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

static void processPlugin(CarlaPlugin* const p, const uint32_t nframes)
@@ -1096,10 +1112,8 @@ private:

if (plugin && plugin->enabled())
{
//plugin->engineProcessLock();
plugin->initBuffers();
processPlugin(plugin, nframes);
//plugin->engineProcessUnlock();
}

return 0;


+ 2
- 2
source/backend/engine/plugin.cpp View File

@@ -430,7 +430,7 @@ protected:
void d_activate()
{
#if 0
for (unsigned short i=0, max=maxPluginNumber(); i < max; i++)
for (unsigned int i=0; i < fData->curPluginCount; i++)
{
CarlaPlugin* const plugin = getPluginUnchecked(i);

@@ -445,7 +445,7 @@ protected:
void d_deactivate()
{
#if 0
for (unsigned short i=0, max=maxPluginNumber(); i < max; i++)
for (unsigned int i=0; i < fData->curPluginCount; i++)
{
CarlaPlugin* const plugin = getPluginUnchecked(i);



+ 2
- 2
source/backend/plugin/Makefile View File

@@ -30,11 +30,11 @@ endif

OBJS = \
carla_plugin.cpp.o \
native.cpp.o
native.cpp.o \
ladspa.cpp.o

# carla_plugin_thread.cpp.o \
# carla_bridge.cpp.o \
# ladspa.cpp.o \
# dssi.cpp.o \
# lv2.cpp.o \
# vst.cpp.o \


+ 2
- 2
source/backend/plugin/carla_plugin.cpp View File

@@ -1231,7 +1231,7 @@ void CarlaPlugin::postRtEventsRun()
// Update OSC control client
if (fData->engine->isOscControlRegistered())
{
fData->engine->osc_send_control_set_program(m_id, event->value1);
fData->engine->osc_send_control_set_program(fData->id, event->value1);

for (uint32_t j=0; j < fData->param.count; j++)
fData->engine->osc_send_control_set_default_value(fData->id, j, fData->param.ranges[j].def);
@@ -1253,7 +1253,7 @@ void CarlaPlugin::postRtEventsRun()
{
fData->engine->osc_send_control_set_midi_program(fData->id, event->value1);

for (uint32_t j=0; j < param.count; j++)
for (uint32_t j=0; j < fData->param.count; j++)
fData->engine->osc_send_control_set_default_value(fData->id, j, fData->param.ranges[j].def);
}
#endif


+ 5
- 3
source/backend/plugin/native.cpp View File

@@ -1668,11 +1668,13 @@ std::vector<const PluginDescriptor*> NativePlugin::pluginDescriptors;

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

#if 0
CarlaPlugin* CarlaPlugin::newNative(const initializer& init)
CarlaPlugin* CarlaPlugin::newNative(const Initializer& init)
{
qDebug("CarlaPlugin::newNative(%p, \"%s\", \"%s\", \"%s\")", init.engine, init.filename, init.name, init.label);

return nullptr;

#if 0
short id = init.engine->getNewPluginId();

if (id < 0 || id > init.engine->maxPluginNumber())
@@ -1704,8 +1706,8 @@ CarlaPlugin* CarlaPlugin::newNative(const initializer& init)
plugin->registerToOscClient();

return plugin;
}
#endif
}

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



+ 1
- 0
source/backend/standalone/Makefile View File

@@ -51,6 +51,7 @@ endif
LIBS = ../libcarla_engine.a
LIBS += ../libcarla_plugin.a
LIBS += ../libcarla_native.a
LIBS += ../../libs/rtmempool.a

OBJS = \
carla_standalone.cpp.o


+ 2
- 1
source/backend/standalone/carla_standalone.cpp View File

@@ -201,7 +201,8 @@ bool carla_engine_init(const char* driverName, const char* clientName)
}
#endif

standalone.engine->setCallback(standalone.callback, nullptr);
if (standalone.callback != nullptr)
standalone.engine->setCallback(standalone.callback, nullptr);

standalone.engine->setOption(CarlaBackend::OPTION_PROCESS_MODE, standalone.options.processMode, nullptr);
standalone.engine->setOption(CarlaBackend::OPTION_FORCE_STEREO, standalone.options.forceStereo, nullptr);


+ 606
- 6
source/carla_shared.py View File

@@ -25,19 +25,19 @@ import sys
from codecs import open as codecopen
from copy import deepcopy
#from decimal import Decimal
from PyQt4.QtCore import pyqtSlot, qWarning, Qt, QSettings, QTimer, SIGNAL, SLOT
from PyQt4.QtCore import pyqtSlot, qWarning, Qt, QByteArray, QSettings, QTimer, SIGNAL, SLOT
#pyqtSlot, qFatal,
from PyQt4.QtGui import QDialog, QIcon, QMessageBox, QWidget
#from PyQt4.QtGui import QColor, QCursor, QFontMetrics, QFrame, QGraphicsScene, QInputDialog, QLinearGradient, QMenu, QPainter, QPainterPath, QVBoxLayout
from PyQt4.QtGui import QColor, QDialog, QIcon, QFontMetrics, QFrame, QMessageBox, QPainter, QPainterPath, QVBoxLayout, QWidget
#from PyQt4.QtGui import QCursor, QGraphicsScene, QInputDialog, QLinearGradient, QMenu,
#from PyQt4.QtXml import QDomDocument

# ------------------------------------------------------------------------------------------------------------
# Imports (Custom)

import ui_carla_about
#import ui_carla_edit
import ui_carla_edit
import ui_carla_parameter
#import ui_carla_plugin
import ui_carla_plugin

# ------------------------------------------------------------------------------------------------------------
# Try Import Signal
@@ -398,7 +398,7 @@ CarlaStateParameter = {
}

CarlaStateCustomData = {
'type': None, #CUSTOM_DATA_INVALID,
'type': "",
'key': "",
'value': ""
}
@@ -842,6 +842,10 @@ class PluginParameter(QWidget):
self.fMidiChannel = channel
self.ui.sb_channel.setValue(channel)

def setLabelWidth(self, width):
self.ui.label.setMinimumWidth(width)
self.ui.label.setMaximumWidth(width)

def tabIndex(self):
return self.fTabIndex

@@ -883,6 +887,598 @@ class PluginParameter(QWidget):
def _textCallBack(self):
return cString(Carla.host.get_parameter_text(self.fPluginId, self.fParameterId))

# ------------------------------------------------------------------------------------------------------------
# Plugin Editor (Built-in)

class PluginEdit(QDialog):
def __init__(self, parent, pluginId):
QDialog.__init__(self, Carla.gui)
self.ui = ui_carla_edit.Ui_PluginEdit()
self.ui.setupUi(self)

self.fGeometry = QByteArray()
self.fPluginId = pluginId
self.fPuginInfo = None
self.fRealParent = parent

self.fCurrentProgram = -1
self.fCurrentMidiProgram = -1
self.fCurrentStateFilename = None

self.fParameterCount = 0
self.fParameterList = [] # (type, id, widget)
self.fParameterIdsToUpdate = [] # id

self.fTabIconOff = QIcon(":/bitmaps/led_off.png")
self.fTabIconOn = QIcon(":/bitmaps/led_yellow.png")
self.fTabIconCount = 0
self.fTabIconTimers = []

self.ui.keyboard.setMode(self.ui.keyboard.HORIZONTAL)
self.ui.keyboard.setOctaves(6)
self.ui.scrollArea.ensureVisible(self.ui.keyboard.width() * 1 / 5, 0)
self.ui.scrollArea.setVisible(False)

# TODO - not implemented yet
self.ui.b_reload_program.setEnabled(False)
self.ui.b_reload_midi_program.setEnabled(False)

# Not available for carla-control
if Carla.isControl:
self.ui.b_load_state.setEnabled(False)
self.ui.b_save_state.setEnabled(False)
else:
self.connect(self.ui.b_save_state, SIGNAL("clicked()"), SLOT("slot_saveState()"))
self.connect(self.ui.b_load_state, SIGNAL("clicked()"), SLOT("slot_loadState()"))

self.connect(self.ui.keyboard, SIGNAL("noteOn(int)"), SLOT("slot_noteOn(int)"))
self.connect(self.ui.keyboard, SIGNAL("noteOff(int)"), SLOT("slot_noteOff(int)"))

self.connect(self.ui.cb_programs, SIGNAL("currentIndexChanged(int)"), SLOT("slot_programIndexChanged(int)"))
self.connect(self.ui.cb_midi_programs, SIGNAL("currentIndexChanged(int)"), SLOT("slot_midiProgramIndexChanged(int)"))

self.connect(self, SIGNAL("finished(int)"), SLOT("slot_finished()"))

#self.reloadAll()

def reloadAll(self):
self.fPluginInfo = Carla.host.get_plugin_info(self.fPluginId)
self.fPluginInfo["binary"] = cString(self.fPluginInfo["binary"])
self.fPluginInfo["name"] = cString(self.fPluginInfo["name"])
self.fPluginInfo["label"] = cString(self.fPluginInfo["label"])
self.fPluginInfo["maker"] = cString(self.fPluginInfo["maker"])
self.fPluginInfo["copyright"] = cString(self.fPluginInfo["copyright"])

self.reloadInfo()
self.reloadParameters()
self.reloadPrograms()

def reloadInfo(self):
pluginName = cString(Carla.host.get_real_plugin_name(self.fPluginId))
pluginType = self.fPluginInfo['type']
pluginHints = self.fPluginInfo['hints']

# Automatically change to MidiProgram tab
if pluginType != PLUGIN_VST and not self.ui.le_name.text():
self.ui.tab_programs.setCurrentIndex(1)

# Set Meta-Data
if pluginType == PLUGIN_INTERNAL:
self.ui.le_type.setText(self.tr("Internal"))
elif pluginType == PLUGIN_LADSPA:
self.ui.le_type.setText("LADSPA")
elif pluginType == PLUGIN_DSSI:
self.ui.le_type.setText("DSSI")
elif pluginType == PLUGIN_LV2:
self.ui.le_type.setText("LV2")
elif pluginType == PLUGIN_VST:
self.ui.le_type.setText("VST")
elif pluginType == PLUGIN_GIG:
self.ui.le_type.setText("GIG")
elif pluginType == PLUGIN_SF2:
self.ui.le_type.setText("SF2")
elif pluginType == PLUGIN_SFZ:
self.ui.le_type.setText("SFZ")
else:
self.ui.le_type.setText(self.tr("Unknown"))

self.ui.le_name.setText(pluginName)
self.ui.le_name.setToolTip(pluginName)
self.ui.le_label.setText(self.fPluginInfo['label'])
self.ui.le_label.setToolTip(self.fPluginInfo['label'])
self.ui.le_maker.setText(self.fPluginInfo['maker'])
self.ui.le_maker.setToolTip(self.fPluginInfo['maker'])
self.ui.le_copyright.setText(self.fPluginInfo['copyright'])
self.ui.le_copyright.setToolTip(self.fPluginInfo['copyright'])
self.ui.le_unique_id.setText(str(self.fPluginInfo['uniqueId']))
self.ui.le_unique_id.setToolTip(str(self.fPluginInfo['uniqueId']))
self.ui.label_plugin.setText("\n%s\n" % self.fPluginInfo['name'])
self.setWindowTitle(self.fPluginInfo['name'])

# Set Processing Data
audioCountInfo = Carla.host.get_audio_port_count_info(self.fPluginId)
midiCountInfo = Carla.host.get_midi_port_count_info(self.fPluginId)
paramCountInfo = Carla.host.get_parameter_count_info(self.fPluginId)

self.ui.le_ains.setText(str(audioCountInfo['ins']))
self.ui.le_aouts.setText(str(audioCountInfo['outs']))
self.ui.le_params.setText(str(paramCountInfo['ins']))
self.ui.le_couts.setText(str(paramCountInfo['outs']))

self.ui.le_is_synth.setText(self.tr("Yes") if (pluginHints & PLUGIN_IS_SYNTH) else self.tr("No"))
self.ui.le_has_gui.setText(self.tr("Yes") if (pluginHints & PLUGIN_HAS_GUI) else self.tr("No"))

# Show/hide keyboard
self.ui.scrollArea.setVisible((pluginHints & PLUGIN_IS_SYNTH) != 0 or (midiCountInfo['ins'] > 0 < midiCountInfo['outs']))

# Force-Update parent for new hints (knobs)
if self.fRealParent:
self.fRealParent.recheckPluginHints(pluginHints)

def reloadParameters(self):
parameterCount = Carla.host.get_parameter_count(self.m_pluginId)

# Reset
self.fParameterCount = 0
self.fParameterList = []
self.fParameterIdsToUpdate = []

self.fTabIconCount = 0
self.fTabIconTimers = []

# Remove all previous parameters
for i in range(self.ui.tabWidget.count()-1):
self.ui.tabWidget.widget(1).deleteLater()
self.ui.tabWidget.removeTab(1)

if parameterCount <= 0:
pass

elif parameterCount <= Carla.maxParameters:
paramInputListFull = []
paramOutputListFull = []

paramInputList = [] # ([params], width)
paramInputWidth = 0
paramOutputList = [] # ([params], width)
paramOutputWidth = 0

for i in range(parameterCount):
paramInfo = Carla.host.get_parameter_info(self.fPluginId, i)
paramData = Carla.host.get_parameter_data(self.fPluginId, i)
paramRanges = Carla.host.get_parameter_ranges(self.fPluginId, i)

if paramData['type'] not in (PARAMETER_INPUT, PARAMETER_OUTPUT):
continue

parameter = {
'type': paramData['type'],
'hints': paramData['hints'],
'name': cString(paramInfo['name']),
'unit': cString(paramInfo['unit']),
'scalePoints': [],

'index': paramData['index'],
'default': paramRanges['def'],
'minimum': paramRanges['min'],
'maximum': paramRanges['max'],
'step': paramRanges['step'],
'stepSmall': paramRanges['stepSmall'],
'stepLarge': paramRanges['stepLarge'],
'midiCC': paramData['midiCC'],
'midiChannel': paramData['midiChannel'],

'current': Carla.host.get_current_parameter_value(self.fPluginId, i)
}

for j in range(paramInfo['scalePointCount']):
scalePointInfo = Carla.host.get_parameter_scalepoint_info(self.fPluginId, i, j)

parameter['scalepoints'].append(
{
'value': scalePointInfo['value'],
'label': cString(scalePointInfo['label'])
})

paramInputList.append(parameter)

# -----------------------------------------------------------------
# Get width values, in packs of 10

if parameter['type'] == PARAMETER_INPUT:
paramInputWidthTMP = QFontMetrics(self.font()).width(parameter['name'])

if paramInputWidthTMP > paramInputWidth:
paramInputWidth = paramInputWidthTMP

if len(paramInputList) == 10:
paramInputListFull.append((paramInputList, paramInputWidth))
paramInputList = []
paramInputWidth = 0

else:
paramOutputWidthTMP = QFontMetrics(self.font()).width(parameter['name'])

if paramOutputWidthTMP > paramOutputWidth:
paramOutputWidth = paramOutputWidthTMP

if len(paramOutputList) == 10:
paramOutputListFull.append((paramOutputList, paramOutputWidth))
paramOutputList = []
paramOutputWidth = 0

# for i in range(parameterCount)
else:
# Final page width values
if 0 < len(paramInputList) < 10:
paramInputListFull.append((paramInputList, paramInputWidth))

if 0 < len(paramOutputList) < 10:
paramOutputListFull.append((paramOutputList, paramOutputWidth))

# -----------------------------------------------------------------
# Create parameter widgets

self._createParameterWidgets(PARAMETER_INPUT, paramInputListFull, self.tr("Parameters"))
self._createParameterWidgets(PARAMETER_OUTPUT, paramOutputListFull, self.tr("Outputs"))

else: # > Carla.maxParameters
fakeName = self.tr("This plugin has too many parameters to display here!")

paramFakeListFull = []
paramFakeList = []
paramFakeWidth = QFontMetrics(self.font()).width(fakeName)

parameter = {
'type': PARAMETER_UNKNOWN,
'hints': 0,
'name': fakeName,
'unit': "",
'scalepoints': [],

'index': 0,
'default': 0,
'minimum': 0,
'maximum': 0,
'step': 0,
'stepSmall': 0,
'stepLarge': 0,
'midiCC': -1,
'midiChannel': 0,

'current': 0.0
}

paramFakeList.append(parameter)
paramFakeListFull.append((paramFakeList, paramFakeWidth))

self.createParameterWidgets(PARAMETER_UNKNOWN, paramFakeListFull, self.tr("Information"))

def reloadPrograms(self):
# Programs
self.ui.cb_programs.blockSignals(True)
self.ui.cb_programs.clear()

programCount = Carla.host.get_program_count(self.fPluginId)

if programCount > 0:
self.ui.cb_programs.setEnabled(True)

for i in range(programCount):
pName = cString(Carla.host.get_program_name(self.fPluginId, i))
self.ui.cb_programs.addItem(pName)

self.fCurrentProgram = Carla.host.get_current_program_index(self.fPluginId)
self.ui.cb_programs.setCurrentIndex(self.fCurrentProgram)

else:
self.fCurrentProgram = -1
self.ui.cb_programs.setEnabled(False)

self.ui.cb_programs.blockSignals(False)

# MIDI Programs
self.ui.cb_midi_programs.blockSignals(True)
self.ui.cb_midi_programs.clear()

midiProgramCount = Carla.host.get_midi_program_count(self.fPluginId)

if midiProgramCount > 0:
self.ui.cb_midi_programs.setEnabled(True)

for i in range(midiProgramCount):
mpData = Carla.host.get_midi_program_data(self.fPluginId, i)
mpBank = int(mpData['bank'])
mpProg = int(mpData['program'])
mpLabel = cString(mpData['label'])
self.ui.cb_midi_programs.addItem("%03i:%03i - %s" % (mpBank, mpProg, mpLabel))

self.fCurrentMidiProgram = Carla.host.get_current_midi_program_index(self.fPluginId)
self.ui.cb_midi_programs.setCurrentIndex(self.fCurrentMidiProgram)

else:
self.fCurrentMidiProgram = -1
self.ui.cb_midi_programs.setEnabled(False)

self.ui.cb_midi_programs.blockSignals(False)

def setVisible(self, yesNo):
if yesNo:
if not self.fGeometry.isNull():
self.restoreGeometry(self.fGeometry)
else:
self.fGeometry = self.saveGeometry()

QDialog.setVisible(self, yesNo)

@pyqtSlot(int, float)
def slot_parameterValueChanged(self, parameterId, value):
Carla.host.set_parameter_value(self.fPluginId, parameterId, value)

@pyqtSlot(int, int)
def slot_parameterMidiChannelChanged(self, parameterId, channel):
Carla.host.set_parameter_midi_channel(self.fPluginId, parameterId, channel-1)

@pyqtSlot(int, int)
def slot_parameterMidiCcChanged(self, parameterId, cc):
Carla.host.set_parameter_midi_cc(self.fPluginId, parameterId, cc)

@pyqtSlot(int)
def slot_programIndexChanged(self, index):
if self.fCurrentProgram != index:
self.fCurrentProgram = index
Carla.host.set_program(self.fPluginId, index)

@pyqtSlot(int)
def slot_midiProgramIndexChanged(self, index):
if self.fCurrentMidiProgram != index:
self.fCurrentMidiProgram = index
Carla.host.set_midi_program(self.fPluginId, index)

@pyqtSlot(int)
def slot_noteOn(self, note):
Carla.host.send_midi_note(self.fPluginId, 0, note, 100)

@pyqtSlot(int)
def slot_noteOff(self, note):
Carla.host.send_midi_note(self.fPluginId, 0, note, 0)

@pyqtSlot()
def slot_notesOn(self):
if self.fRealParent:
self.fRealParent.led_midi.setChecked(True)

@pyqtSlot()
def slot_notesOff(self):
if self.fRealParent:
self.fRealParent.led_midi.setChecked(False)

@pyqtSlot()
def slot_finished(self):
if self.fRealParent:
self.fRealParent.editClosed()

def _createParameterWidgets(self, paramType, paramListFull, tabPageName):
i = 1
for paramList, width in paramListFull:
if len(paramList) == 0:
break

tabIndex = self.ui.tabWidget.count()
tabPageContainer = QWidget(self.ui.tabWidget)
tabPageLayout = QVBoxLayout(tabPageContainer)
tabPageContainer.setLayout(tabPageLayout)

for paramInfo in paramList:
paramWidget = PluginParameter(tabPageContainer, paramInfo, self.fPluginId, tabIndex)
paramWidget.setLabelWidth(width)
tabPageLayout.addWidget(paramWidget)

self.fParameterList.append((paramType, paramInfo['index'], paramWidget))

if paramType == PARAMETER_INPUT:
self.connect(paramWidget, SIGNAL("valueChanged(int, double)"), SLOT("slot_parameterValueChanged(int, double)"))

self.connect(paramWidget, SIGNAL("midiChannelChanged(int, int)"), SLOT("slot_parameterMidiChannelChanged(int, int)"))
self.connect(paramWidget, SIGNAL("midiCcChanged(int, int)"), SLOT("slot_parameterMidiCcChanged(int, int)"))

tabPageLayout.addStretch()

self.ui.tabWidget.addTab(tabPageContainer, "%s (%i)" % (tabPageName, i))
i += 1

if paramType == PARAMETER_INPUT:
self.ui.tabWidget.setTabIcon(tabIndex, self.fTabIconOff)

self.fTabIconTimers.append(ICON_STATE_NULL)

def done(self, r):
QDialog.done(self, r)
self.close()

# ------------------------------------------------------------------------------------------------------------
# Plugin Widget

class PluginWidget(QFrame):
def __init__(self, parent, pluginId):
QFrame.__init__(self, parent)
self.ui = ui_carla_plugin.Ui_PluginWidget()
self.ui.setupUi(self)

self.fPluginId = pluginId
#self.fPluginInfo = Carla.host.get_plugin_info(self.fPluginId)
#self.fPluginInfo["binary"] = cString(self.fPluginInfo["binary"])
#self.fPluginInfo["name"] = cString(self.fPluginInfo["name"])
#self.fPluginInfo["label"] = cString(self.fPluginInfo["label"])
#self.fPluginInfo["maker"] = cString(self.fPluginInfo["maker"])
#self.fPluginInfo["copyright"] = cString(self.fPluginInfo["copyright"])

self.fParameterIconTimer = ICON_STATE_NULL

self.fLastGreenLedState = False
self.fLastBlueLedState = False

if Carla.processMode == PROCESS_MODE_CONTINUOUS_RACK:
self.fPeaksInputCount = 2
self.fPeaksOutputCount = 2
#self.ui.stackedWidget.setCurrentIndex(0)
else:
audioCountInfo = Carla.host.get_audio_port_count_info(self.fPluginId)

self.fPeaksInputCount = int(audioCountInfo['ins'])
self.fPeaksOutputCount = int(audioCountInfo['outs'])

if self.fPeaksInputCount > 2:
self.fPeaksInputCount = 2

if self.fPeaksOutputCount > 2:
self.fPeaksOutputCount = 2

#if audioCountInfo['total'] == 0:
#self.ui.stackedWidget.setCurrentIndex(1)
#else:
#self.ui.stackedWidget.setCurrentIndex(0)

# Background
self.fColorTop = QColor(60, 60, 60)
self.fColorBottom = QColor(47, 47, 47)

# Colorify
#if self.m_pluginInfo['category'] == PLUGIN_CATEGORY_SYNTH:
#self.setWidgetColor(PALETTE_COLOR_WHITE)
#elif self.m_pluginInfo['category'] == PLUGIN_CATEGORY_DELAY:
#self.setWidgetColor(PALETTE_COLOR_ORANGE)
#elif self.m_pluginInfo['category'] == PLUGIN_CATEGORY_EQ:
#self.setWidgetColor(PALETTE_COLOR_GREEN)
#elif self.m_pluginInfo['category'] == PLUGIN_CATEGORY_FILTER:
#self.setWidgetColor(PALETTE_COLOR_BLUE)
#elif self.m_pluginInfo['category'] == PLUGIN_CATEGORY_DYNAMICS:
#self.setWidgetColor(PALETTE_COLOR_PINK)
#elif self.m_pluginInfo['category'] == PLUGIN_CATEGORY_MODULATOR:
#self.setWidgetColor(PALETTE_COLOR_RED)
#elif self.m_pluginInfo['category'] == PLUGIN_CATEGORY_UTILITY:
#self.setWidgetColor(PALETTE_COLOR_YELLOW)
#elif self.m_pluginInfo['category'] == PLUGIN_CATEGORY_OTHER:
#self.setWidgetColor(PALETTE_COLOR_BROWN)
#else:
#self.setWidgetColor(PALETTE_COLOR_NONE)

self.ui.led_enable.setColor(self.ui.led_enable.BIG_RED)
self.ui.led_enable.setChecked(False)

self.ui.led_control.setColor(self.ui.led_control.YELLOW)
self.ui.led_control.setEnabled(False)

self.ui.led_midi.setColor(self.ui.led_midi.RED)
self.ui.led_midi.setEnabled(False)

self.ui.led_audio_in.setColor(self.ui.led_audio_in.GREEN)
self.ui.led_audio_in.setEnabled(False)

self.ui.led_audio_out.setColor(self.ui.led_audio_out.BLUE)
self.ui.led_audio_out.setEnabled(False)

self.ui.dial_drywet.setPixmap(3)
self.ui.dial_vol.setPixmap(3)
self.ui.dial_b_left.setPixmap(4)
self.ui.dial_b_right.setPixmap(4)

self.ui.dial_drywet.setCustomPaint(self.ui.dial_drywet.CUSTOM_PAINT_CARLA_WET)
self.ui.dial_vol.setCustomPaint(self.ui.dial_vol.CUSTOM_PAINT_CARLA_VOL)
self.ui.dial_b_left.setCustomPaint(self.ui.dial_b_left.CUSTOM_PAINT_CARLA_L)
self.ui.dial_b_right.setCustomPaint(self.ui.dial_b_right.CUSTOM_PAINT_CARLA_R)

self.ui.peak_in.setColor(self.ui.peak_in.GREEN)
self.ui.peak_in.setOrientation(self.ui.peak_in.HORIZONTAL)

self.ui.peak_out.setColor(self.ui.peak_in.BLUE)
self.ui.peak_out.setOrientation(self.ui.peak_out.HORIZONTAL)

self.ui.peak_in.setChannels(self.fPeaksInputCount)
self.ui.peak_out.setChannels(self.fPeaksOutputCount)

#self.ui.label_name.setText(self.fPluginInfo['name'])

self.ui.edit_dialog = PluginEdit(self, self.fPluginId)
self.ui.edit_dialog.hide()

#self.connect(self.ui.led_enable, SIGNAL("clicked(bool)"), SLOT("slot_setActive(bool)"))
#self.connect(self.ui.dial_drywet, SIGNAL("sliderMoved(int)"), SLOT("slot_setDryWet(int)"))
#self.connect(self.ui.dial_vol, SIGNAL("sliderMoved(int)"), SLOT("slot_setVolume(int)"))
#self.connect(self.ui.dial_b_left, SIGNAL("sliderMoved(int)"), SLOT("slot_setBalanceLeft(int)"))
#self.connect(self.ui.dial_b_right, SIGNAL("sliderMoved(int)"), SLOT("slot_setBalanceRight(int)"))
#self.connect(self.ui.b_gui, SIGNAL("clicked(bool)"), SLOT("slot_guiClicked(bool)"))
self.connect(self.ui.b_edit, SIGNAL("clicked(bool)"), SLOT("slot_editClicked(bool)"))
#self.connect(self.ui.b_remove, SIGNAL("clicked()"), SLOT("slot_removeClicked()"))

#self.connect(self.ui.dial_drywet, SIGNAL("customContextMenuRequested(QPoint)"), SLOT("slot_showCustomDialMenu()"))
#self.connect(self.ui.dial_vol, SIGNAL("customContextMenuRequested(QPoint)"), SLOT("slot_showCustomDialMenu()"))
#self.connect(self.ui.dial_b_left, SIGNAL("customContextMenuRequested(QPoint)"), SLOT("slot_showCustomDialMenu()"))
#self.connect(self.ui.dial_b_right, SIGNAL("customContextMenuRequested(QPoint)"), SLOT("slot_showCustomDialMenu()"))

# FIXME
self.ui.frame_controls.setVisible(False)
self.ui.pushButton.setVisible(False)
self.ui.pushButton_2.setVisible(False)
self.ui.pushButton_3.setVisible(False)
self.setMaximumHeight(30)

def editClosed(self):
self.ui.b_edit.setChecked(False)

def recheckPluginHints(self, hints):
self.fPluginInfo['hints'] = hints
self.ui.dial_drywet.setEnabled(hints & PLUGIN_CAN_DRYWET)
self.ui.dial_vol.setEnabled(hints & PLUGIN_CAN_VOLUME)
self.ui.dial_b_left.setEnabled(hints & PLUGIN_CAN_BALANCE)
self.ui.dial_b_right.setEnabled(hints & PLUGIN_CAN_BALANCE)
self.ui.b_gui.setEnabled(hints & PLUGIN_HAS_GUI)

def paintEvent(self, event):
painter = QPainter(self)

areaX = self.ui.area_right.x()

# background
#painter.setPen(self.m_colorTop)
#painter.setBrush(self.m_colorTop)
#painter.drawRect(0, 0, areaX+40, self.height())

# bottom line
painter.setPen(self.fColorBottom)
painter.setBrush(self.fColorBottom)
painter.drawRect(0, self.height()-5, areaX, 5)

# top line
painter.drawLine(0, 0, areaX+40, 0)

# name -> leds arc
path = QPainterPath()
path.moveTo(areaX-80, self.height())
path.cubicTo(areaX+40, self.height()-5, areaX-40, 30, areaX+20, 0)
path.lineTo(areaX+20, self.height())
painter.drawPath(path)

# fill the rest
painter.drawRect(areaX+20, 0, self.width(), self.height())

#painter.drawLine(0, 3, self.width(), 3)
#painter.drawLine(0, self.height() - 4, self.width(), self.height() - 4)
#painter.setPen(self.m_color2)
#painter.drawLine(0, 2, self.width(), 2)
#painter.drawLine(0, self.height() - 3, self.width(), self.height() - 3)
#painter.setPen(self.m_color3)
#painter.drawLine(0, 1, self.width(), 1)
#painter.drawLine(0, self.height() - 2, self.width(), self.height() - 2)
#painter.setPen(self.m_color4)
#painter.drawLine(0, 0, self.width(), 0)
#painter.drawLine(0, self.height() - 1, self.width(), self.height() - 1)
QFrame.paintEvent(self, event)

@pyqtSlot(bool)
def slot_editClicked(self, show):
self.ui.edit_dialog.setVisible(show)

# ------------------------------------------------------------------------------------------------------------
# TESTING

@@ -912,6 +1508,10 @@ class PluginParameter(QWidget):
#app = QApplication(sys.argv)
#gui1 = CarlaAboutW(None)
#gui2 = PluginParameter(None, ptest, 0, 0)
#gui3 = PluginEdit(None, 0)
#gui4 = PluginWidget(None, 0)
#gui1.show()
#gui2.show()
#gui3.show()
#gui4.show()
#app.exec_()

+ 4
- 1
source/utils/carla_utils.hpp View File

@@ -633,6 +633,9 @@ private:

std::strcpy(buffer, strBuf);

// FIXME?
buffer[bufferLen-1] = '\0';

firstInit = false;
}
}
@@ -651,7 +654,7 @@ private:

bufferLen = 0;
buffer = new char[1];
buffer[0] = 0;
buffer[0] = '\0';

firstInit = false;
}


Loading…
Cancel
Save