diff --git a/source/backend/carla_engine.hpp b/source/backend/carla_engine.hpp index a68042fc9..d4d2bbee2 100644 --- a/source/backend/carla_engine.hpp +++ b/source/backend/carla_engine.hpp @@ -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 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 const fData; - #ifdef WANT_JACK static CarlaEngine* newJack(); #endif diff --git a/source/backend/engine/carla_engine.cpp b/source/backend/engine/carla_engine.cpp index ddb43581e..e21a540ca 100644 --- a/source/backend/engine/carla_engine.cpp +++ b/source/backend/engine/carla_engine.cpp @@ -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 diff --git a/source/backend/engine/carla_engine.pro b/source/backend/engine/carla_engine.pro index 188df7748..f607973ef 100644 --- a/source/backend/engine/carla_engine.pro +++ b/source/backend/engine/carla_engine.pro @@ -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 diff --git a/source/backend/engine/carla_engine_internal.hpp b/source/backend/engine/carla_engine_internal.hpp index 806c1eab3..c382ce9d5 100644 --- a/source/backend/engine/carla_engine_internal.hpp +++ b/source/backend/engine/carla_engine_internal.hpp @@ -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 diff --git a/source/backend/engine/carla_engine_osc.cpp b/source/backend/engine/carla_engine_osc.cpp index f57bb8ce5..e230e0813 100644 --- a/source/backend/engine/carla_engine_osc.cpp +++ b/source/backend/engine/carla_engine_osc.cpp @@ -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 diff --git a/source/backend/engine/jack.cpp b/source/backend/engine/jack.cpp index e132f7446..358a75f14 100644 --- a/source/backend/engine/jack.cpp +++ b/source/backend/engine/jack.cpp @@ -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(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(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; diff --git a/source/backend/engine/plugin.cpp b/source/backend/engine/plugin.cpp index ec792999d..6dda84e96 100644 --- a/source/backend/engine/plugin.cpp +++ b/source/backend/engine/plugin.cpp @@ -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); diff --git a/source/backend/plugin/Makefile b/source/backend/plugin/Makefile index 8cf3fc39a..5c865b5bd 100644 --- a/source/backend/plugin/Makefile +++ b/source/backend/plugin/Makefile @@ -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 \ diff --git a/source/backend/plugin/carla_plugin.cpp b/source/backend/plugin/carla_plugin.cpp index 7c4fd3cc2..0ead34c50 100644 --- a/source/backend/plugin/carla_plugin.cpp +++ b/source/backend/plugin/carla_plugin.cpp @@ -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 diff --git a/source/backend/plugin/native.cpp b/source/backend/plugin/native.cpp index 5fe6d2c78..49348e94c 100644 --- a/source/backend/plugin/native.cpp +++ b/source/backend/plugin/native.cpp @@ -1668,11 +1668,13 @@ std::vector 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 +} // ----------------------------------------------------------------------- diff --git a/source/backend/standalone/Makefile b/source/backend/standalone/Makefile index d47764580..8005e49c2 100644 --- a/source/backend/standalone/Makefile +++ b/source/backend/standalone/Makefile @@ -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 diff --git a/source/backend/standalone/carla_standalone.cpp b/source/backend/standalone/carla_standalone.cpp index bd16e7716..f862d62a7 100644 --- a/source/backend/standalone/carla_standalone.cpp +++ b/source/backend/standalone/carla_standalone.cpp @@ -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); diff --git a/source/carla_shared.py b/source/carla_shared.py index cf2561be6..8f008946b 100644 --- a/source/carla_shared.py +++ b/source/carla_shared.py @@ -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_() diff --git a/source/utils/carla_utils.hpp b/source/utils/carla_utils.hpp index f6724dc3b..1a799fb41 100644 --- a/source/utils/carla_utils.hpp +++ b/source/utils/carla_utils.hpp @@ -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; }