| @@ -2311,7 +2311,7 @@ void CarlaEngine::oscSend_bridge_parameter_data(const uint32_t index, const int3 | |||
| CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); | |||
| CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); | |||
| CARLA_SAFE_ASSERT_RETURN(name != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(unit != nullptr,); | |||
| carla_debug("CarlaEngine::oscSend_bridge_parameter_data(%i, %i, %i:%s, %X, \"%s\", \"%s\")", index, rindex, type, ParameterType2Str(type), hints, name, unit); | |||
| @@ -2430,6 +2430,7 @@ void CarlaEngine::oscSend_bridge_program_name(const uint32_t index, const char* | |||
| CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); | |||
| CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); | |||
| CARLA_SAFE_ASSERT_RETURN(name != nullptr,); | |||
| carla_debug("CarlaEngine::oscSend_bridge_program_name(%i, \"%s\")", index, name); | |||
| char targetPath[std::strlen(pData->oscData->path)+21]; | |||
| @@ -197,13 +197,19 @@ protected: | |||
| name = nullptr; | |||
| } | |||
| fEngine->addPlugin((BinaryType)btype, (PluginType)ptype, filename, name, label); | |||
| const bool ok = fEngine->addPlugin((BinaryType)btype, (PluginType)ptype, filename, name, label); | |||
| if (filename != nullptr) | |||
| delete[] filename; | |||
| if (name != nullptr) | |||
| delete[] name; | |||
| delete[] label; | |||
| if (! ok) | |||
| { | |||
| writeMsg("error\n", 6); | |||
| writeAndFixMsg(fEngine->getLastError()); | |||
| } | |||
| } | |||
| else if (std::strcmp(msg, "remove_plugin") == 0) | |||
| { | |||
| @@ -550,6 +556,16 @@ public: | |||
| init("Carla-Rack"); | |||
| } | |||
| if (pData->options.resourceDir != nullptr) | |||
| delete[] pData->options.resourceDir; | |||
| if (pData->options.binaryDir != nullptr) | |||
| delete[] pData->options.binaryDir; | |||
| pData->options.resourceDir = carla_strdup(pHost->resourceDir); | |||
| // FIXME | |||
| pData->options.binaryDir = carla_strdup("/usr/lib/carla"); | |||
| setCallback(_ui_server_callback, this); | |||
| } | |||
| @@ -702,6 +702,18 @@ public: | |||
| pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false); | |||
| } | |||
| // extra plugin hints | |||
| pData->extraHints = 0x0; | |||
| if (fInfo.mIns > 0) | |||
| pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN; | |||
| if (fInfo.mOuts > 0) | |||
| pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_OUT; | |||
| if (fInfo.aIns <= 2 && fInfo.aOuts <= 2 && (fInfo.aIns == fInfo.aOuts || fInfo.aIns == 0 || fInfo.aOuts == 0)) | |||
| pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK; | |||
| bufferSizeChanged(pData->engine->getBufferSize()); | |||
| reloadPrograms(true); | |||
| @@ -1424,7 +1436,7 @@ public: | |||
| CARLA_BRIDGE_CHECK_OSC_TYPES(2, "ii"); | |||
| const int32_t index = argv[0]->i; | |||
| const int32_t channel = argv[0]->i; | |||
| const int32_t channel = argv[1]->i; | |||
| CARLA_SAFE_ASSERT_BREAK(index >= 0); | |||
| CARLA_SAFE_ASSERT_BREAK(channel >= 0 && channel < MAX_MIDI_CHANNELS); | |||
| @@ -1781,9 +1793,6 @@ public: | |||
| if (fInitError || ! fInitiated) | |||
| { | |||
| // unregister so it gets handled properly | |||
| pData->engine->registerEnginePlugin(pData->id, nullptr); | |||
| pData->osc.thread.stop(6000); | |||
| if (! fInitError) | |||
| @@ -1936,6 +1945,7 @@ CarlaPlugin* CarlaPlugin::newJACK(const Initializer& init) | |||
| if (! plugin->init(init.filename, init.name, init.label, nullptr)) | |||
| { | |||
| init.engine->registerEnginePlugin(init.id, nullptr); | |||
| delete plugin; | |||
| return nullptr; | |||
| } | |||
| @@ -1944,6 +1954,7 @@ CarlaPlugin* CarlaPlugin::newJACK(const Initializer& init) | |||
| if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack()) | |||
| { | |||
| init.engine->registerEnginePlugin(init.id, nullptr); | |||
| init.engine->setLastError("Carla's rack mode can only work with Stereo bridged apps, sorry!"); | |||
| delete plugin; | |||
| return nullptr; | |||
| @@ -2504,7 +2504,7 @@ public: | |||
| lv2_atom_forge_set_buffer(&fAtomForge, timeInfoBuf, sizeof(timeInfoBuf)); | |||
| LV2_Atom_Forge_Frame forgeFrame; | |||
| lv2_atom_forge_object(&fAtomForge, &forgeFrame, 1, CARLA_URI_MAP_ID_TIME_POSITION); | |||
| lv2_atom_forge_object(&fAtomForge, &forgeFrame, CARLA_URI_MAP_ID_NULL, CARLA_URI_MAP_ID_TIME_POSITION); | |||
| lv2_atom_forge_key(&fAtomForge, CARLA_URI_MAP_ID_TIME_SPEED); | |||
| lv2_atom_forge_float(&fAtomForge, timeInfo.playing ? 1.0f : 0.0f); | |||
| @@ -2538,10 +2538,11 @@ public: | |||
| LV2_Atom* const atom((LV2_Atom*)timeInfoBuf); | |||
| CARLA_SAFE_ASSERT_BREAK(atom->size < 256); | |||
| lv2_atom_buffer_write(&evInAtomIters[i], 0, 0, atom->type, atom->size, LV2_ATOM_BODY_CONST(atom)); | |||
| // send deprecated blank object as well | |||
| // send only deprecated blank object for now | |||
| lv2_atom_buffer_write(&evInAtomIters[i], 0, 0, CARLA_URI_MAP_ID_ATOM_BLANK, atom->size, LV2_ATOM_BODY_CONST(atom)); | |||
| // for atom:object | |||
| //lv2_atom_buffer_write(&evInAtomIters[i], 0, 0, atom->type, atom->size, LV2_ATOM_BODY_CONST(atom)); | |||
| } | |||
| pData->postRtEvents.trySplice(); | |||
| @@ -576,7 +576,7 @@ bool carla_engine_init_bridge(const char audioBaseName[6+1], const char controlB | |||
| gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_RESOURCES, 0, resourceDir); | |||
| if (const char* const frontendWinId = std::getenv("ENGINE_OPTION_FRONTEND_WIN_ID")) | |||
| gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_BINARIES, 0, frontendWinId); | |||
| gStandalone.engine->setOption(CB::ENGINE_OPTION_FRONTEND_WIN_ID, 0, frontendWinId); | |||
| if (gStandalone.engine->init(clientName)) | |||
| { | |||
| @@ -143,31 +143,31 @@ class PluginHost(object): | |||
| self.fPluginsInfo[pluginId].midiProgramDataS.append(PyMidiProgramData) | |||
| def _set_parameterInfoS(self, pluginId, paramIndex, info): | |||
| if paramIndex < self.fPluginsInfo[pluginId].parameterCount: | |||
| if pluginId < len(self.fPluginsInfo) and paramIndex < self.fPluginsInfo[pluginId].parameterCount: | |||
| self.fPluginsInfo[pluginId].parameterInfoS[paramIndex] = info | |||
| def _set_parameterDataS(self, pluginId, paramIndex, data): | |||
| if paramIndex < self.fPluginsInfo[pluginId].parameterCount: | |||
| if pluginId < len(self.fPluginsInfo) and paramIndex < self.fPluginsInfo[pluginId].parameterCount: | |||
| self.fPluginsInfo[pluginId].parameterDataS[paramIndex] = data | |||
| def _set_parameterRangeS(self, pluginId, paramIndex, ranges): | |||
| if paramIndex < self.fPluginsInfo[pluginId].parameterCount: | |||
| if pluginId < len(self.fPluginsInfo) and paramIndex < self.fPluginsInfo[pluginId].parameterCount: | |||
| self.fPluginsInfo[pluginId].parameterRangeS[paramIndex] = ranges | |||
| def _set_parameterValueS(self, pluginId, paramIndex, value): | |||
| if paramIndex < self.fPluginsInfo[pluginId].parameterCount: | |||
| if pluginId < len(self.fPluginsInfo) and paramIndex < self.fPluginsInfo[pluginId].parameterCount: | |||
| self.fPluginsInfo[pluginId].parameterValueS[paramIndex] = value | |||
| def _set_parameterDefault(self, pluginId, paramIndex, value): | |||
| if paramIndex < self.fPluginsInfo[pluginId].parameterCount: | |||
| if pluginId < len(self.fPluginsInfo) and paramIndex < self.fPluginsInfo[pluginId].parameterCount: | |||
| self.fPluginsInfo[pluginId].parameterRangeS[paramIndex]['def'] = value | |||
| def _set_parameterMidiChannel(self, pluginId, paramIndex, channel): | |||
| if paramIndex < self.fPluginsInfo[pluginId].parameterCount: | |||
| if pluginId < len(self.fPluginsInfo) and paramIndex < self.fPluginsInfo[pluginId].parameterCount: | |||
| self.fPluginsInfo[pluginId].parameterDataS[paramIndex]['midiChannel'] = channel | |||
| def _set_parameterMidiCC(self, pluginId, paramIndex, cc): | |||
| if paramIndex < self.fPluginsInfo[pluginId].parameterCount: | |||
| if pluginId < len(self.fPluginsInfo) and paramIndex < self.fPluginsInfo[pluginId].parameterCount: | |||
| self.fPluginsInfo[pluginId].parameterDataS[paramIndex]['midiCC'] = cc | |||
| def _set_currentProgram(self, pluginId, pIndex): | |||
| @@ -690,6 +690,10 @@ class CarlaMiniW(HostWindow, ExternalUI): | |||
| name = self.fPipeRecv.readline().strip().replace("\r", "\n") | |||
| Carla.host._set_midiProgramDataS(pluginId, midiProgId, {'bank': bank, 'program': program, 'name': name}) | |||
| elif msg == "error": | |||
| error = self.fPipeRecv.readline().strip().replace("\r", "\n") | |||
| engineCallback(None, ENGINE_CALLBACK_ERROR, 0, 0, 0, 0.0, error) | |||
| elif msg == "show": | |||
| self.d_uiShow() | |||
| @@ -1058,11 +1058,11 @@ class HostWindow(QMainWindow): | |||
| @pyqtSlot(str) | |||
| def slot_handleInfoCallback(self, info): | |||
| pass | |||
| QMessageBox.information(self, "Information", info) | |||
| @pyqtSlot(str) | |||
| def slot_handleErrorCallback(self, error): | |||
| pass | |||
| QMessageBox.critical(self, "Error", error) | |||
| @pyqtSlot() | |||
| def slot_handleQuitCallback(self): | |||