| @@ -691,7 +691,7 @@ struct ParameterData { | |||||
| ParameterType type; | ParameterType type; | ||||
| int32_t index; | int32_t index; | ||||
| int32_t rindex; | int32_t rindex; | ||||
| uint32_t hints; | |||||
| unsigned int hints; | |||||
| uint8_t midiChannel; | uint8_t midiChannel; | ||||
| int16_t midiCC; | int16_t midiCC; | ||||
| @@ -381,7 +381,12 @@ const char** CarlaEngine::getDriverDeviceNames(const unsigned int index) | |||||
| carla_debug("CarlaEngine::getDriverDeviceNames(%i)", index); | carla_debug("CarlaEngine::getDriverDeviceNames(%i)", index); | ||||
| if (index == 0) | if (index == 0) | ||||
| return nullptr; | |||||
| { | |||||
| //static const char* const strOff = "Auto-connect OFF"; | |||||
| //static const char* const strOn = "Auto-connect ON"; | |||||
| static const char* ret[3] = { "Auto-connect OFF", "Auto-connect ON", nullptr }; | |||||
| return ret; | |||||
| } | |||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| const unsigned int rtAudioIndex(index-1); | const unsigned int rtAudioIndex(index-1); | ||||
| @@ -1057,29 +1062,18 @@ bool CarlaEngine::loadFilename(const char* const filename) | |||||
| CARLA_ASSERT(filename != nullptr); | CARLA_ASSERT(filename != nullptr); | ||||
| carla_debug("CarlaEngine::loadFilename(\"%s\")", filename); | carla_debug("CarlaEngine::loadFilename(\"%s\")", filename); | ||||
| #if 0 | |||||
| QFileInfo fileInfo(filename); | |||||
| using namespace juce; | |||||
| if (! fileInfo.exists()) | |||||
| { | |||||
| setLastError("File does not exist"); | |||||
| return false; | |||||
| } | |||||
| if (! fileInfo.isFile()) | |||||
| { | |||||
| setLastError("Not a file"); | |||||
| return false; | |||||
| } | |||||
| File file(filename); | |||||
| if (! fileInfo.isReadable()) | |||||
| if (! file.existsAsFile()) | |||||
| { | { | ||||
| setLastError("File is not readable"); | |||||
| setLastError("File does not exist"); | |||||
| return false; | return false; | ||||
| } | } | ||||
| CarlaString baseName(fileInfo.baseName().toUtf8().constData()); | |||||
| CarlaString extension(fileInfo.suffix().toLower().toUtf8().constData()); | |||||
| CarlaString baseName(file.getFileNameWithoutExtension().toRawUTF8()); | |||||
| CarlaString extension(file.getFileExtension().toRawUTF8()); | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -1175,7 +1169,6 @@ bool CarlaEngine::loadFilename(const char* const filename) | |||||
| } | } | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| #endif | |||||
| setLastError("Unknown file extension"); | setLastError("Unknown file extension"); | ||||
| return false; | return false; | ||||
| @@ -1200,71 +1193,68 @@ bool CarlaEngine::loadProject(const char* const filename) | |||||
| CARLA_ASSERT(filename != nullptr); | CARLA_ASSERT(filename != nullptr); | ||||
| carla_debug("CarlaEngine::loadProject(\"%s\")", filename); | carla_debug("CarlaEngine::loadProject(\"%s\")", filename); | ||||
| #if 0 | |||||
| QFile file(filename); | |||||
| if (! file.open(QIODevice::ReadOnly | QIODevice::Text)) | |||||
| return false; | |||||
| using namespace juce; | |||||
| QDomDocument xml; | |||||
| xml.setContent(file.readAll()); | |||||
| file.close(); | |||||
| File file(filename); | |||||
| QDomNode xmlNode(xml.documentElement()); | |||||
| XmlDocument xml(file); | |||||
| if (xmlNode.toElement().tagName() != "CARLA-PROJECT" && xmlNode.toElement().tagName() != "CARLA-PRESET") | |||||
| if (XmlElement* const xmlCheck = xml.getDocumentElement(true)) | |||||
| { | { | ||||
| setLastError("Not a valid Carla project or preset file"); | |||||
| return false; | |||||
| } | |||||
| const String& tagNameTest(xmlCheck->getTagName()); | |||||
| const bool isPreset(tagNameTest.equalsIgnoreCase("carla-preset")); | |||||
| const bool isPreset(xmlNode.toElement().tagName() == "CARLA-PRESET"); | |||||
| if (tagNameTest.equalsIgnoreCase("carla-project") || isPreset) | |||||
| { | |||||
| if (XmlElement* const xmlElem = xml.getDocumentElement(false)) | |||||
| { | |||||
| for (XmlElement* subElem = xmlElem->getFirstChildElement(); subElem != nullptr; subElem = subElem->getNextElement()) | |||||
| { | |||||
| if (isPreset || subElem->getTagName().equalsIgnoreCase("Plugin")) | |||||
| { | |||||
| SaveState saveState; | |||||
| fillSaveStateFromXmlElement(saveState, isPreset ? xmlElem : subElem); | |||||
| QDomNode node(xmlNode.firstChild()); | |||||
| CARLA_SAFE_ASSERT_CONTINUE(saveState.type != nullptr); | |||||
| while (! node.isNull()) | |||||
| { | |||||
| if (isPreset || node.toElement().tagName() == "Plugin") | |||||
| { | |||||
| SaveState saveState; | |||||
| fillSaveStateFromXmlNode(saveState, isPreset ? xmlNode : node); | |||||
| const void* extraStuff = nullptr; | |||||
| CARLA_ASSERT(saveState.type != nullptr); | |||||
| if (std::strcmp(saveState.type, "SF2") == 0) | |||||
| { | |||||
| const char* const use16OutsSuffix = " (16 outs)"; | |||||
| if (saveState.type == nullptr) | |||||
| continue; | |||||
| if (charEndsWith(saveState.label, use16OutsSuffix)) | |||||
| extraStuff = (void*)0x1; // non-null | |||||
| } | |||||
| const void* extraStuff = nullptr; | |||||
| // TODO - proper find&load plugins | |||||
| if (std::strcmp(saveState.type, "DSSI") == 0) | |||||
| { | |||||
| extraStuff = findDSSIGUI(saveState.binary, saveState.label); | |||||
| } | |||||
| else if (std::strcmp(saveState.type, "SF2") == 0) | |||||
| { | |||||
| const char use16OutsSuffix[] = " (16 outs)"; | |||||
| if (addPlugin(getPluginTypeFromString(saveState.type), saveState.binary, saveState.name, saveState.label, extraStuff)) | |||||
| { | |||||
| if (CarlaPlugin* plugin = getPlugin(pData->curPluginCount-1)) | |||||
| plugin->loadSaveState(saveState); | |||||
| } | |||||
| } | |||||
| if (charEndsWith(saveState.label, use16OutsSuffix)) | |||||
| extraStuff = (void*)0x1; // non-null | |||||
| } | |||||
| if (isPreset) | |||||
| break; | |||||
| } | |||||
| // TODO - proper find&load plugins | |||||
| if (addPlugin(getPluginTypeFromString(saveState.type), saveState.binary, saveState.name, saveState.label, extraStuff)) | |||||
| { | |||||
| if (CarlaPlugin* plugin = getPlugin(pData->curPluginCount-1)) | |||||
| plugin->loadSaveState(saveState); | |||||
| delete xmlElem; | |||||
| delete xmlCheck; | |||||
| return true; | |||||
| } | } | ||||
| else | |||||
| setLastError("Failed to parse file"); | |||||
| } | } | ||||
| else | |||||
| setLastError("Not a valid Carla project or preset file"); | |||||
| if (isPreset) | |||||
| break; | |||||
| node = node.nextSibling(); | |||||
| delete xmlCheck; | |||||
| return false; | |||||
| } | } | ||||
| return true; | |||||
| #endif | |||||
| setLastError("Not implemented yet"); | |||||
| setLastError("Not a valid file"); | |||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -1273,16 +1263,14 @@ bool CarlaEngine::saveProject(const char* const filename) | |||||
| CARLA_ASSERT(filename != nullptr); | CARLA_ASSERT(filename != nullptr); | ||||
| carla_debug("CarlaEngine::saveProject(\"%s\")", filename); | carla_debug("CarlaEngine::saveProject(\"%s\")", filename); | ||||
| #if 0 | |||||
| QFile file(filename); | |||||
| using namespace juce; | |||||
| if (! file.open(QIODevice::WriteOnly | QIODevice::Text)) | |||||
| return false; | |||||
| File file(filename); | |||||
| QTextStream out(&file); | |||||
| MemoryOutputStream out; | |||||
| out << "<?xml version='1.0' encoding='UTF-8'?>\n"; | out << "<?xml version='1.0' encoding='UTF-8'?>\n"; | ||||
| out << "<!DOCTYPE CARLA-PROJECT>\n"; | out << "<!DOCTYPE CARLA-PROJECT>\n"; | ||||
| out << "<CARLA-PROJECT VERSION='1.0'>\n"; | |||||
| out << "<CARLA-PROJECT VERSION='2.0'>\n"; | |||||
| bool firstPlugin = true; | bool firstPlugin = true; | ||||
| char strBuf[STR_MAX+1]; | char strBuf[STR_MAX+1]; | ||||
| @@ -1296,12 +1284,18 @@ bool CarlaEngine::saveProject(const char* const filename) | |||||
| if (! firstPlugin) | if (! firstPlugin) | ||||
| out << "\n"; | out << "\n"; | ||||
| strBuf[0] = '\0'; | |||||
| plugin->getRealName(strBuf); | plugin->getRealName(strBuf); | ||||
| if (*strBuf != 0) | |||||
| out << QString(" <!-- %1 -->\n").arg(xmlSafeString(strBuf, true)); | |||||
| if (strBuf[0] != '\0') | |||||
| { | |||||
| out << " <!-- "; | |||||
| out << xmlSafeString(strBuf, true); | |||||
| out << " -->\n"; | |||||
| } | |||||
| QString content; | |||||
| String content; | |||||
| fillXmlStringFromSaveState(content, plugin->getSaveState()); | fillXmlStringFromSaveState(content, plugin->getSaveState()); | ||||
| out << " <Plugin>\n"; | out << " <Plugin>\n"; | ||||
| @@ -1314,11 +1308,7 @@ bool CarlaEngine::saveProject(const char* const filename) | |||||
| out << "</CARLA-PROJECT>\n"; | out << "</CARLA-PROJECT>\n"; | ||||
| file.close(); | |||||
| return true; | |||||
| #endif | |||||
| setLastError("Not implemented yet"); | |||||
| return false; | |||||
| return file.replaceWithData(out.getData(), out.getDataSize()); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -227,6 +227,11 @@ public: | |||||
| CARLA_SAFE_ASSERT_RETURN(fIsInput, kFallbackJackEngineEvent); | CARLA_SAFE_ASSERT_RETURN(fIsInput, kFallbackJackEngineEvent); | ||||
| CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, kFallbackJackEngineEvent); | CARLA_SAFE_ASSERT_RETURN(fJackBuffer != nullptr, kFallbackJackEngineEvent); | ||||
| return getEventUnchecked(index); | |||||
| } | |||||
| const EngineEvent& getEventUnchecked(const uint32_t index) override | |||||
| { | |||||
| jack_midi_event_t jackEvent; | jack_midi_event_t jackEvent; | ||||
| carla_zeroStruct<jack_midi_event_t>(jackEvent); | carla_zeroStruct<jack_midi_event_t>(jackEvent); | ||||
| @@ -829,16 +829,14 @@ bool CarlaPlugin::saveStateToFile(const char* const filename) | |||||
| String content; | String content; | ||||
| fillXmlStringFromSaveState(content, getSaveState()); | fillXmlStringFromSaveState(content, getSaveState()); | ||||
| String out; | |||||
| MemoryOutputStream out; | |||||
| out << "<?xml version='1.0' encoding='UTF-8'?>\n"; | out << "<?xml version='1.0' encoding='UTF-8'?>\n"; | ||||
| out << "<!DOCTYPE CARLA-PRESET>\n"; | out << "<!DOCTYPE CARLA-PRESET>\n"; | ||||
| out << "<CARLA-PRESET VERSION='2.0'>\n"; | out << "<CARLA-PRESET VERSION='2.0'>\n"; | ||||
| out << content; | out << content; | ||||
| out << "</CARLA-PRESET>\n"; | out << "</CARLA-PRESET>\n"; | ||||
| carla_stdout("TESTING, FULL OUT FILE:\n%s", out.toRawUTF8()); | |||||
| return file.replaceWithText(out); | |||||
| return file.replaceWithData(out.getData(), out.getDataSize()); | |||||
| } | } | ||||
| bool CarlaPlugin::loadStateFromFile(const char* const filename) | bool CarlaPlugin::loadStateFromFile(const char* const filename) | ||||
| @@ -16,16 +16,6 @@ | |||||
| # | # | ||||
| # For a full copy of the GNU General Public License see the GPL.txt file | # For a full copy of the GNU General Public License see the GPL.txt file | ||||
| # ------------------------------------------------------------------------------------------------------------ | |||||
| # Imports (Global) | |||||
| try: | |||||
| from PyQt5.QtCore import QTimer | |||||
| from PyQt5.QtWidgets import QApplication | |||||
| except: | |||||
| from PyQt4.QtCore import QTimer | |||||
| from PyQt4.QtGui import QApplication | |||||
| # ------------------------------------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------------------------------------ | ||||
| # Imports (Custom Stuff) | # Imports (Custom Stuff) | ||||
| @@ -0,0 +1,367 @@ | |||||
| #!/usr/bin/env python3 | |||||
| # -*- coding: utf-8 -*- | |||||
| # Carla plugin host (plugin UI) | |||||
| # Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||||
| # | |||||
| # This program is free software; you can redistribute it and/or | |||||
| # modify it under the terms of the GNU General Public License as | |||||
| # published by the Free Software Foundation; either version 2 of | |||||
| # the License, or any later version. | |||||
| # | |||||
| # This program is distributed in the hope that it will be useful, | |||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| # GNU General Public License for more details. | |||||
| # | |||||
| # For a full copy of the GNU General Public License see the GPL.txt file | |||||
| # ------------------------------------------------------------------------------------------------------------ | |||||
| # Imports (Custom Stuff) | |||||
| from carla_host import * | |||||
| from externalui import ExternalUI | |||||
| # ------------------------------------------------------------------------------------------------------------ | |||||
| # Host Plugin object | |||||
| class PluginHost(object): | |||||
| def __init__(self): | |||||
| object.__init__(self) | |||||
| self.fParent = None | |||||
| self.fBufferSize = 0 | |||||
| self.fSampleRate = 0.0 | |||||
| self.fLastError = "" | |||||
| self.fSupportedFileTypes = "" | |||||
| # ------------------------------------------------------------------- | |||||
| def get_engine_driver_count(self): | |||||
| return 0 | |||||
| def get_supported_file_types(self): | |||||
| return self.fSupportedFileTypes | |||||
| def engine_init(self, driverName, clientName): | |||||
| return True | |||||
| def engine_close(self): | |||||
| return True | |||||
| def is_engine_running(self): | |||||
| return True | |||||
| def set_engine_about_to_close(self): | |||||
| pass | |||||
| def set_engine_callback(self, func): | |||||
| pass | |||||
| def load_filename(self, filename): | |||||
| self.fParent.send(["load_filename", filename]) | |||||
| return True | |||||
| def load_project(self, filename): | |||||
| self.fParent.send(["load_project", filename]) | |||||
| return True | |||||
| def save_project(self, filename): | |||||
| self.fParent.send(["save_project", filename]) | |||||
| return True | |||||
| def patchbay_connect(self, portIdA, portIdB): | |||||
| self.fParent.send(["patchbay_connect", portIdA, portIdB]) | |||||
| return True | |||||
| def patchbay_disconnect(self, connectionId): | |||||
| self.fParent.send(["patchbay_disconnect", connectionId]) | |||||
| return True | |||||
| def patchbay_refresh(self): | |||||
| self.fParent.send(["patchbay_refresh"]) | |||||
| def add_plugin(self, btype, ptype, filename, name, label, extraStuff): | |||||
| self.fParent.send(["add_plugin", btype, ptype, filename, name, label]) | |||||
| return True | |||||
| def remove_plugin(self, pluginId): | |||||
| self.fParent.send(["remove_plugin", pluginId]) | |||||
| return True | |||||
| def remove_all_plugins(self): | |||||
| self.fParent.send(["remove_all_plugins"]) | |||||
| def rename_plugin(self, pluginId, newName): | |||||
| self.fParent.send(["rename_plugin", pluginId, newName]) | |||||
| return True | |||||
| def clone_plugin(self, pluginId): | |||||
| self.fParent.send(["clone_plugin", pluginId]) | |||||
| return True | |||||
| def replace_plugin(self, pluginId): | |||||
| self.fParent.send(["replace_plugin", pluginId]) | |||||
| return True | |||||
| def switch_plugins(self, pluginIdA, pluginIdB): | |||||
| self.fParent.send(["switch_plugins", pluginIdA, pluginIdB]) | |||||
| return True | |||||
| def load_plugin_state(self, pluginId, filename): | |||||
| self.fParent.send(["load_plugin_state", pluginId, filename]) | |||||
| return True | |||||
| def save_plugin_state(self, pluginId, filename): | |||||
| self.fParent.send(["save_plugin_state", pluginId, filename]) | |||||
| return True | |||||
| #def get_plugin_info(self, pluginId): | |||||
| #return structToDict(self.lib.carla_get_plugin_info(pluginId).contents) | |||||
| #def get_audio_port_count_info(self, pluginId): | |||||
| #return structToDict(self.lib.carla_get_audio_port_count_info(pluginId).contents) | |||||
| #def get_midi_port_count_info(self, pluginId): | |||||
| #return structToDict(self.lib.carla_get_midi_port_count_info(pluginId).contents) | |||||
| #def get_parameter_count_info(self, pluginId): | |||||
| #return structToDict(self.lib.carla_get_parameter_count_info(pluginId).contents) | |||||
| #def get_parameter_info(self, pluginId, parameterId): | |||||
| #return structToDict(self.lib.carla_get_parameter_info(pluginId, parameterId).contents) | |||||
| #def get_parameter_scalepoint_info(self, pluginId, parameterId, scalePointId): | |||||
| #return structToDict(self.lib.carla_get_parameter_scalepoint_info(pluginId, parameterId, scalePointId).contents) | |||||
| #def get_parameter_data(self, pluginId, parameterId): | |||||
| #return structToDict(self.lib.carla_get_parameter_data(pluginId, parameterId).contents) | |||||
| #def get_parameter_ranges(self, pluginId, parameterId): | |||||
| #return structToDict(self.lib.carla_get_parameter_ranges(pluginId, parameterId).contents) | |||||
| #def get_midi_program_data(self, pluginId, midiProgramId): | |||||
| #return structToDict(self.lib.carla_get_midi_program_data(pluginId, midiProgramId).contents) | |||||
| #def get_custom_data(self, pluginId, customDataId): | |||||
| #return structToDict(self.lib.carla_get_custom_data(pluginId, customDataId).contents) | |||||
| #def get_chunk_data(self, pluginId): | |||||
| #return self.lib.carla_get_chunk_data(pluginId) | |||||
| #def get_parameter_count(self, pluginId): | |||||
| #return self.lib.carla_get_parameter_count(pluginId) | |||||
| #def get_program_count(self, pluginId): | |||||
| #return self.lib.carla_get_program_count(pluginId) | |||||
| #def get_midi_program_count(self, pluginId): | |||||
| #return self.lib.carla_get_midi_program_count(pluginId) | |||||
| #def get_custom_data_count(self, pluginId): | |||||
| #return self.lib.carla_get_custom_data_count(pluginId) | |||||
| #def get_parameter_text(self, pluginId, parameterId): | |||||
| #return self.lib.carla_get_parameter_text(pluginId, parameterId) | |||||
| #def get_program_name(self, pluginId, programId): | |||||
| #return self.lib.carla_get_program_name(pluginId, programId) | |||||
| #def get_midi_program_name(self, pluginId, midiProgramId): | |||||
| #return self.lib.carla_get_midi_program_name(pluginId, midiProgramId) | |||||
| #def get_real_plugin_name(self, pluginId): | |||||
| #return self.lib.carla_get_real_plugin_name(pluginId) | |||||
| #def get_current_program_index(self, pluginId): | |||||
| #return self.lib.carla_get_current_program_index(pluginId) | |||||
| #def get_current_midi_program_index(self, pluginId): | |||||
| #return self.lib.carla_get_current_midi_program_index(pluginId) | |||||
| #def get_default_parameter_value(self, pluginId, parameterId): | |||||
| #return self.lib.carla_get_default_parameter_value(pluginId, parameterId) | |||||
| #def get_current_parameter_value(self, pluginId, parameterId): | |||||
| #return self.lib.carla_get_current_parameter_value(pluginId, parameterId) | |||||
| #def get_input_peak_value(self, pluginId, portId): | |||||
| #return self.lib.carla_get_input_peak_value(pluginId, portId) | |||||
| #def get_output_peak_value(self, pluginId, portId): | |||||
| #return self.lib.carla_get_output_peak_value(pluginId, portId) | |||||
| def set_option(self, pluginId, option, yesNo): | |||||
| self.fParent.send(["set_option", pluginId, option, yesNo]) | |||||
| def set_active(self, pluginId, onOff): | |||||
| self.fParent.send(["set_active", pluginId, onOff]) | |||||
| def set_drywet(self, pluginId, value): | |||||
| self.fParent.send(["set_drywet", pluginId, value]) | |||||
| def set_volume(self, pluginId, value): | |||||
| self.fParent.send(["set_volume", pluginId, value]) | |||||
| def set_balance_left(self, pluginId, value): | |||||
| self.fParent.send(["set_balance_left", pluginId, value]) | |||||
| def set_balance_right(self, pluginId, value): | |||||
| self.fParent.send(["set_balance_right", pluginId, value]) | |||||
| def set_panning(self, pluginId, value): | |||||
| self.fParent.send(["set_panning", pluginId, value]) | |||||
| def set_ctrl_channel(self, pluginId, channel): | |||||
| self.fParent.send(["set_ctrl_channel", pluginId, channel]) | |||||
| def set_parameter_value(self, pluginId, parameterId, value): | |||||
| self.fParent.send(["set_parameter_value", pluginId, parameterId, value]) | |||||
| def set_parameter_midi_cc(self, pluginId, parameterId, cc): | |||||
| self.fParent.send(["set_parameter_midi_cc", pluginId, parameterId, cc]) | |||||
| def set_parameter_midi_channel(self, pluginId, parameterId, channel): | |||||
| self.fParent.send(["set_parameter_midi_channel", pluginId, parameterId, channel]) | |||||
| def set_program(self, pluginId, programId): | |||||
| self.fParent.send(["set_program", pluginId, programId]) | |||||
| def set_midi_program(self, pluginId, midiProgramId): | |||||
| self.fParent.send(["set_midi_program", pluginId, midiProgramId]) | |||||
| def set_custom_data(self, pluginId, type_, key, value): | |||||
| self.fParent.send(["set_custom_data", pluginId, type_, key, value]) | |||||
| def set_chunk_data(self, pluginId, chunkData): | |||||
| self.fParent.send(["set_chunk_data", pluginId, chunkData]) | |||||
| def prepare_for_save(self, pluginId): | |||||
| self.fParent.send(["prepare_for_save", pluginId]) | |||||
| def send_midi_note(self, pluginId, channel, note, velocity): | |||||
| self.fParent.send(["send_midi_note", pluginId, channel, note, velocity]) | |||||
| def show_gui(self, pluginId, yesNo): | |||||
| self.fParent.send(["show_gui", pluginId, yesNo]) | |||||
| def get_last_error(self): | |||||
| return self.fLastError | |||||
| def get_buffer_size(self): | |||||
| return self.fBufferSize | |||||
| def get_sample_rate(self): | |||||
| return self.fSampleRate | |||||
| # ------------------------------------------------------------------------------------------------------------ | |||||
| # Init plugin | |||||
| def initPlugin(): | |||||
| Carla.host = PluginHost() | |||||
| # ------------------------------------------------------------------------------------------------------------ | |||||
| # Main Window | |||||
| class CarlaMiniW(HostWindow, ExternalUI): | |||||
| def __init__(self): | |||||
| HostWindow.__init__(self, None) | |||||
| ExternalUI.__init__(self) | |||||
| if Carla.host is not None: | |||||
| Carla.host.fParent = None | |||||
| Carla.host.fSampleRate = self.d_getSampleRate() | |||||
| if False: | |||||
| from carla_patchbay import CarlaPatchbayW | |||||
| self.fContainer = CarlaPatchbayW(self) | |||||
| else: | |||||
| from carla_rack import CarlaRackW | |||||
| self.fContainer = CarlaRackW(self) | |||||
| self.setCentralWidget(self.fContainer) | |||||
| self.setWindowTitle(self.fUiName) | |||||
| self.fIdleTimer = self.startTimer(50) | |||||
| self.showUiIfTesting() | |||||
| # ------------------------------------------------------------------- | |||||
| # ExternalUI Callbacks | |||||
| def d_uiShow(self): | |||||
| self.show() | |||||
| def d_uiHide(self): | |||||
| self.hide() | |||||
| def d_uiQuit(self): | |||||
| self.close() | |||||
| app.quit() | |||||
| def d_uiTitleChanged(self, uiTitle): | |||||
| self.setWindowTitle(uiTitle) | |||||
| # ------------------------------------------------------------------- | |||||
| # Qt events | |||||
| def timerEvent(self, event): | |||||
| if event.timerId() == self.fIdleTimer: | |||||
| if not self.idleExternalUI(): | |||||
| self.d_uiQuit() | |||||
| QWidget.timerEvent(self, event) | |||||
| def closeEvent(self, event): | |||||
| self.closeExternalUI() | |||||
| HostWindow.closeEvent(self, event) | |||||
| # ------------------------------------------------------------------------------------------------------------ | |||||
| # Main | |||||
| if __name__ == '__main__': | |||||
| # ------------------------------------------------------------- | |||||
| # Setup | |||||
| Carla.isControl = False | |||||
| Carla.isLocal = False | |||||
| Carla.isPlugin = True | |||||
| # ------------------------------------------------------------- | |||||
| # App initialization | |||||
| app = QApplication(sys.argv) | |||||
| app.setApplicationName("Carla") | |||||
| app.setApplicationVersion(VERSION) | |||||
| app.setOrganizationName("falkTX") | |||||
| app.setWindowIcon(QIcon(":/scalable/carla.svg")) | |||||
| # ------------------------------------------------------------- | |||||
| # Set-up custom signal handling | |||||
| setUpSignals() | |||||
| # ------------------------------------------------------------- | |||||
| # Read CLI args | |||||
| argv = app.arguments() | |||||
| argc = len(argv) | |||||
| if argc > 1: | |||||
| pass | |||||
| # ------------------------------------------------------------- | |||||
| # Init plugin backend | |||||
| initPlugin() | |||||
| # ------------------------------------------------------------- | |||||
| # Create GUI | |||||
| Carla.gui = CarlaMiniW() | |||||
| # ------------------------------------------------------------- | |||||
| # App-Loop | |||||
| sys.exit(app.exec_()) | |||||
| @@ -89,7 +89,7 @@ def structToDict(struct): | |||||
| MAX_DEFAULT_PLUGINS = 99 | MAX_DEFAULT_PLUGINS = 99 | ||||
| MAX_RACK_PLUGINS = 16 | MAX_RACK_PLUGINS = 16 | ||||
| MAX_PATCHBAY_PLUGINS = 999 | |||||
| MAX_PATCHBAY_PLUGINS = 255 | |||||
| MAX_DEFAULT_PARAMETERS = 200 | MAX_DEFAULT_PARAMETERS = 200 | ||||
| # Plugin Hints | # Plugin Hints | ||||
| @@ -162,13 +162,13 @@ PLUGIN_SFZ = 10 | |||||
| # Plugin Category | # Plugin Category | ||||
| PLUGIN_CATEGORY_NONE = 0 | PLUGIN_CATEGORY_NONE = 0 | ||||
| PLUGIN_CATEGORY_SYNTH = 1 | PLUGIN_CATEGORY_SYNTH = 1 | ||||
| PLUGIN_CATEGORY_DELAY = 2 # also Reverb | |||||
| PLUGIN_CATEGORY_DELAY = 2 | |||||
| PLUGIN_CATEGORY_EQ = 3 | PLUGIN_CATEGORY_EQ = 3 | ||||
| PLUGIN_CATEGORY_FILTER = 4 | PLUGIN_CATEGORY_FILTER = 4 | ||||
| PLUGIN_CATEGORY_DYNAMICS = 5 # Amplifier, Compressor, Gate | |||||
| PLUGIN_CATEGORY_MODULATOR = 6 # Chorus, Flanger, Phaser | |||||
| PLUGIN_CATEGORY_UTILITY = 7 # Analyzer, Converter, Mixer | |||||
| PLUGIN_CATEGORY_OTHER = 8 # used to check if a plugin has a category | |||||
| PLUGIN_CATEGORY_DYNAMICS = 5 | |||||
| PLUGIN_CATEGORY_MODULATOR = 6 | |||||
| PLUGIN_CATEGORY_UTILITY = 7 | |||||
| PLUGIN_CATEGORY_OTHER = 8 | |||||
| # Parameter Type | # Parameter Type | ||||
| PARAMETER_UNKNOWN = 0 | PARAMETER_UNKNOWN = 0 | ||||
| @@ -304,7 +304,7 @@ class ParameterData(Structure): | |||||
| ("type", c_enum), | ("type", c_enum), | ||||
| ("index", c_int32), | ("index", c_int32), | ||||
| ("rindex", c_int32), | ("rindex", c_int32), | ||||
| ("hints", c_uint32), | |||||
| ("hints", c_uint), | |||||
| ("midiChannel", c_uint8), | ("midiChannel", c_uint8), | ||||
| ("midiCC", c_int16) | ("midiCC", c_int16) | ||||
| ] | ] | ||||
| @@ -400,6 +400,73 @@ class CarlaTransportInfo(Structure): | |||||
| ("bpm", c_double) | ("bpm", c_double) | ||||
| ] | ] | ||||
| # ------------------------------------------------------------------------------------------------------------ | |||||
| # Python object dicts compatible with ctypes struct | |||||
| PyParameterData = { | |||||
| 'type': PARAMETER_NULL, | |||||
| 'index': 0, | |||||
| 'rindex': -1, | |||||
| 'hints': 0x0, | |||||
| 'midiChannel': 0, | |||||
| 'midiCC': -1 | |||||
| } | |||||
| PyParameterRanges = { | |||||
| 'def': 0.0, | |||||
| 'min': 0.0, | |||||
| 'max': 1.0, | |||||
| 'step': 0.0, | |||||
| 'stepSmall': 0.0, | |||||
| 'stepLarge': 0.0 | |||||
| } | |||||
| PyMidiProgramData = { | |||||
| 'bank': 0, | |||||
| 'program': 0, | |||||
| 'name': None | |||||
| } | |||||
| PyCustomData = { | |||||
| 'type': None, | |||||
| 'key': None, | |||||
| 'value': None | |||||
| } | |||||
| PyCarlaPluginInfo = { | |||||
| 'type': PLUGIN_NONE, | |||||
| 'category': PLUGIN_CATEGORY_NONE, | |||||
| 'hints': 0x0, | |||||
| 'optionsAvailable': 0x0, | |||||
| 'optionsEnabled': 0x0, | |||||
| 'binary': None, | |||||
| 'name': None, | |||||
| 'label': None, | |||||
| 'maker': None, | |||||
| 'copyright': None, | |||||
| 'iconName': None, | |||||
| 'uniqueId': 0, | |||||
| 'latency': 0 | |||||
| } | |||||
| PyCarlaPortCountInfo = { | |||||
| 'ins': 0, | |||||
| 'outs': 0, | |||||
| 'total': 0 | |||||
| } | |||||
| PyCarlaParameterInfo = { | |||||
| 'name': None, | |||||
| 'symbol': None, | |||||
| 'unit': None, | |||||
| 'scalePointCount': 0, | |||||
| } | |||||
| PyCarlaScalePointInfo = { | |||||
| 'value': 0.0, | |||||
| 'label': None | |||||
| } | |||||
| # ------------------------------------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------------------------------------ | ||||
| # Host Python object (Control/Standalone) | # Host Python object (Control/Standalone) | ||||
| @@ -39,99 +39,6 @@ lo_targetName = "" | |||||
| Carla.isControl = True | Carla.isControl = True | ||||
| Carla.isLocal = False | Carla.isLocal = False | ||||
| # ------------------------------------------------------------------------------------------------------------ | |||||
| # Python Object dicts compatible to carla-backend struct ctypes | |||||
| ParameterData = { | |||||
| 'type': PARAMETER_NULL, | |||||
| 'index': 0, | |||||
| 'rindex': -1, | |||||
| 'hints': 0x0, | |||||
| 'midiChannel': 0, | |||||
| 'midiCC': -1 | |||||
| } | |||||
| ParameterRanges = { | |||||
| 'def': 0.0, | |||||
| 'min': 0.0, | |||||
| 'max': 1.0, | |||||
| 'step': 0.0, | |||||
| 'stepSmall': 0.0, | |||||
| 'stepLarge': 0.0 | |||||
| } | |||||
| MidiProgramData = { | |||||
| 'bank': 0, | |||||
| 'program': 0, | |||||
| 'name': None | |||||
| } | |||||
| CustomData = { | |||||
| 'type': CUSTOM_DATA_INVALID, | |||||
| 'key': None, | |||||
| 'value': None | |||||
| } | |||||
| # ------------------------------------------------------------------------------------------------------------ | |||||
| CarlaPluginInfo = { | |||||
| 'type': PLUGIN_NONE, | |||||
| 'category': PLUGIN_CATEGORY_NONE, | |||||
| 'hints': 0x0, | |||||
| 'optionsAvailable': 0x0, | |||||
| 'optionsEnabled': 0x0, | |||||
| 'binary': None, | |||||
| 'name': None, | |||||
| 'label': None, | |||||
| 'maker': None, | |||||
| 'copyright': None, | |||||
| 'iconName': None, | |||||
| 'uniqueId': 0, | |||||
| 'latency': 0 | |||||
| } | |||||
| CarlaNativePluginInfo = { | |||||
| 'category': PLUGIN_CATEGORY_NONE, | |||||
| 'hints': 0x0, | |||||
| 'audioIns': 0, | |||||
| 'audioOuts': 0, | |||||
| 'midiIns': 0, | |||||
| 'midiOuts': 0, | |||||
| 'parameterIns': 0, | |||||
| 'parameterOuts': 0, | |||||
| 'name': None, | |||||
| 'label': None, | |||||
| 'maker': None, | |||||
| 'copyright': None | |||||
| } | |||||
| CarlaPortCountInfo = { | |||||
| 'ins': 0, | |||||
| 'outs': 0, | |||||
| 'total': 0 | |||||
| } | |||||
| CarlaParameterInfo = { | |||||
| 'name': None, | |||||
| 'symbol': None, | |||||
| 'unit': None, | |||||
| 'scalePointCount': 0, | |||||
| } | |||||
| CarlaScalePointInfo = { | |||||
| 'value': 0.0, | |||||
| 'label': None | |||||
| } | |||||
| CarlaTransportInfo = { | |||||
| 'playing': False, | |||||
| 'frame': 0, | |||||
| 'bar': 0, | |||||
| 'beat': 0, | |||||
| 'tick': 0, | |||||
| 'bpm': 0.0 | |||||
| } | |||||
| # ------------------------------------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------------------------------------ | ||||
| # Helper class | # Helper class | ||||
| @@ -1442,7 +1442,9 @@ class PluginDatabaseW(QDialog): | |||||
| for plugins in internalPlugins: | for plugins in internalPlugins: | ||||
| internalCount += len(plugins) | internalCount += len(plugins) | ||||
| if Carla.host is not None and internalCount != Carla.host.get_internal_plugin_count(): | |||||
| canRefreshInternals = not (Carla.isControl or Carla.isPlugin or Carla.host is None) | |||||
| if canRefreshInternals and internalCount != Carla.host.get_internal_plugin_count(): | |||||
| internalCount = Carla.host.get_internal_plugin_count() | internalCount = Carla.host.get_internal_plugin_count() | ||||
| internalPlugins = [] | internalPlugins = [] | ||||
| @@ -192,12 +192,21 @@ class HostWindow(QMainWindow): | |||||
| # ------------------------------------------------------------- | # ------------------------------------------------------------- | ||||
| # Set up GUI (engine stopped) | # Set up GUI (engine stopped) | ||||
| if Carla.isPlugin: | |||||
| self.ui.act_file_new.setEnabled(False) | |||||
| self.ui.act_file_open.setEnabled(False) | |||||
| self.ui.act_engine_start.setEnabled(False) | |||||
| self.ui.act_engine_stop.setEnabled(False) | |||||
| self.ui.menu_Engine.setEnabled(False) | |||||
| else: | |||||
| self.ui.act_engine_start.setEnabled(True) | |||||
| self.ui.act_file_save.setEnabled(False) | self.ui.act_file_save.setEnabled(False) | ||||
| self.ui.act_file_save_as.setEnabled(False) | self.ui.act_file_save_as.setEnabled(False) | ||||
| self.ui.act_engine_start.setEnabled(True) | |||||
| self.ui.act_engine_stop.setEnabled(False) | self.ui.act_engine_stop.setEnabled(False) | ||||
| self.ui.act_plugin_remove_all.setEnabled(False) | self.ui.act_plugin_remove_all.setEnabled(False) | ||||
| #self.ui.menu_Plugins.setEnabled(False) | |||||
| self.ui.menu_PluginMacros.setEnabled(False) | |||||
| self.ui.menu_Canvas.setEnabled(False) | self.ui.menu_Canvas.setEnabled(False) | ||||
| self.setTransportMenuEnabled(False) | self.setTransportMenuEnabled(False) | ||||
| @@ -254,10 +263,10 @@ class HostWindow(QMainWindow): | |||||
| # ------------------------------------------------------------- | # ------------------------------------------------------------- | ||||
| # Final setup | # Final setup | ||||
| if NSM_URL: | |||||
| if Carla.isPlugin: | |||||
| QTimer.singleShot(0, self.slot_engineStart) | |||||
| elif NSM_URL: | |||||
| Carla.host.nsm_ready() | Carla.host.nsm_ready() | ||||
| #else: | |||||
| #QTimer.singleShot(0, self.slot_engineStart) | |||||
| # ----------------------------------------------------------------- | # ----------------------------------------------------------------- | ||||
| # Called by containers | # Called by containers | ||||
| @@ -266,116 +275,6 @@ class HostWindow(QMainWindow): | |||||
| dialog = CarlaSettingsW(self, hasCanvas, hasCanvasGL) | dialog = CarlaSettingsW(self, hasCanvas, hasCanvasGL) | ||||
| return dialog.exec_() | return dialog.exec_() | ||||
| def loadSettings(self, doGeometry): | |||||
| settings = QSettings() | |||||
| if doGeometry: | |||||
| self.restoreGeometry(settings.value("Geometry", "")) | |||||
| showToolbar = settings.value("ShowToolbar", True, type=bool) | |||||
| self.ui.act_settings_show_toolbar.setChecked(showToolbar) | |||||
| self.ui.toolBar.setVisible(showToolbar) | |||||
| #if settings.contains("SplitterState"): | |||||
| #self.ui.splitter.restoreState(settings.value("SplitterState", "")) | |||||
| #else: | |||||
| #self.ui.splitter.setSizes([99999, 210]) | |||||
| #diskFolders = toList(settings.value("DiskFolders", [HOME])) | |||||
| #self.ui.cb_disk.setItemData(0, HOME) | |||||
| #for i in range(len(diskFolders)): | |||||
| #if i == 0: continue | |||||
| #folder = diskFolders[i] | |||||
| #self.ui.cb_disk.addItem(os.path.basename(folder), folder) | |||||
| if MACOS and not settings.value("Main/UseProTheme", True, type=bool): | |||||
| self.setUnifiedTitleAndToolBarOnMac(True) | |||||
| useCustomMiniCanvasPaint = bool(settings.value("Main/UseProTheme", True, type=bool) and | |||||
| settings.value("Main/ProThemeColor", "Black", type=str) == "Black") | |||||
| # --------------------------------------------- | |||||
| # engine | |||||
| self.setEngineSettings(settings) | |||||
| # --------------------------------------------- | |||||
| # plugin checks | |||||
| if settings.value("Engine/DisableChecks", False, type=bool): | |||||
| os.environ["CARLA_DISCOVERY_NO_PROCESSING_CHECKS"] = "true" | |||||
| elif os.getenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS"): | |||||
| os.environ.pop("CARLA_DISCOVERY_NO_PROCESSING_CHECKS") | |||||
| # --------------------------------------------- | |||||
| # plugin paths | |||||
| LADSPA_PATH = toList(settings.value("Paths/LADSPA", Carla.DEFAULT_LADSPA_PATH)) | |||||
| DSSI_PATH = toList(settings.value("Paths/DSSI", Carla.DEFAULT_DSSI_PATH)) | |||||
| LV2_PATH = toList(settings.value("Paths/LV2", Carla.DEFAULT_LV2_PATH)) | |||||
| VST_PATH = toList(settings.value("Paths/VST", Carla.DEFAULT_VST_PATH)) | |||||
| AU_PATH = toList(settings.value("Paths/AU", Carla.DEFAULT_AU_PATH)) | |||||
| CSOUND_PATH = toList(settings.value("Paths/CSOUND", Carla.DEFAULT_CSOUND_PATH)) | |||||
| GIG_PATH = toList(settings.value("Paths/GIG", Carla.DEFAULT_GIG_PATH)) | |||||
| SF2_PATH = toList(settings.value("Paths/SF2", Carla.DEFAULT_SF2_PATH)) | |||||
| SFZ_PATH = toList(settings.value("Paths/SFZ", Carla.DEFAULT_SFZ_PATH)) | |||||
| os.environ["LADSPA_PATH"] = splitter.join(LADSPA_PATH) | |||||
| os.environ["DSSI_PATH"] = splitter.join(DSSI_PATH) | |||||
| os.environ["LV2_PATH"] = splitter.join(LV2_PATH) | |||||
| os.environ["VST_PATH"] = splitter.join(VST_PATH) | |||||
| os.environ["AU_PATH"] = splitter.join(AU_PATH) | |||||
| os.environ["CSOUND_PATH"] = splitter.join(CSOUND_PATH) | |||||
| os.environ["GIG_PATH"] = splitter.join(GIG_PATH) | |||||
| os.environ["SF2_PATH"] = splitter.join(SF2_PATH) | |||||
| os.environ["SFZ_PATH"] = splitter.join(SFZ_PATH) | |||||
| # --------------------------------------------- | |||||
| self.fSavedSettings = { | |||||
| "Main/DefaultProjectFolder": settings.value("Main/DefaultProjectFolder", HOME, type=str), | |||||
| "Main/RefreshInterval": settings.value("Main/RefreshInterval", 50, type=int), | |||||
| "Canvas/Theme": settings.value("Canvas/Theme", CANVAS_DEFAULT_THEME_NAME, type=str), | |||||
| "Canvas/AutoHideGroups": settings.value("Canvas/AutoHideGroups", False, type=bool), | |||||
| "Canvas/UseBezierLines": settings.value("Canvas/UseBezierLines", True, type=bool), | |||||
| "Canvas/EyeCandy": settings.value("Canvas/EyeCandy", CANVAS_EYECANDY_SMALL, type=int), | |||||
| "Canvas/UseOpenGL": settings.value("Canvas/UseOpenGL", False, type=bool), | |||||
| "Canvas/Antialiasing": settings.value("Canvas/Antialiasing", CANVAS_ANTIALIASING_SMALL, type=int), | |||||
| "Canvas/HighQualityAntialiasing": settings.value("Canvas/HighQualityAntialiasing", False, type=bool), | |||||
| "UseCustomMiniCanvasPaint": useCustomMiniCanvasPaint | |||||
| } | |||||
| # --------------------------------------------- | |||||
| if self.fIdleTimerFast != 0: | |||||
| self.killTimer(self.fIdleTimerFast) | |||||
| self.fIdleTimerFast = self.startTimer(self.fSavedSettings["Main/RefreshInterval"]) | |||||
| if self.fIdleTimerSlow != 0: | |||||
| self.killTimer(self.fIdleTimerSlow) | |||||
| self.fIdleTimerSlow = self.startTimer(self.fSavedSettings["Main/RefreshInterval"]*2) | |||||
| def saveSettings(self): | |||||
| settings = QSettings() | |||||
| settings.setValue("Geometry", self.saveGeometry()) | |||||
| #settings.setValue("SplitterState", self.ui.splitter.saveState()) | |||||
| settings.setValue("ShowToolbar", self.ui.toolBar.isVisible()) | |||||
| #settings.setValue("HorizontalScrollBarValue", self.ui.graphicsView.horizontalScrollBar().value()) | |||||
| #settings.setValue("VerticalScrollBarValue", self.ui.graphicsView.verticalScrollBar().value()) | |||||
| #diskFolders = [] | |||||
| #for i in range(self.ui.cb_disk.count()): | |||||
| #diskFolders.append(self.ui.cb_disk.itemData(i)) | |||||
| #settings.setValue("DiskFolders", diskFolders) | |||||
| self.fContainer.saveSettings(settings) | |||||
| # ----------------------------------------------------------------- | # ----------------------------------------------------------------- | ||||
| # Internal stuff (files) | # Internal stuff (files) | ||||
| @@ -410,6 +309,9 @@ class HostWindow(QMainWindow): | |||||
| # Internal stuff (engine) | # Internal stuff (engine) | ||||
| def setEngineSettings(self, settings = None): | def setEngineSettings(self, settings = None): | ||||
| if Carla.isPlugin: | |||||
| return "Plugin" | |||||
| if settings is None: settings = QSettings() | if settings is None: settings = QSettings() | ||||
| forceStereo = settings.value("Engine/ForceStereo", CARLA_DEFAULT_FORCE_STEREO, type=bool) | forceStereo = settings.value("Engine/ForceStereo", CARLA_DEFAULT_FORCE_STEREO, type=bool) | ||||
| @@ -602,6 +504,118 @@ class HostWindow(QMainWindow): | |||||
| self.ui.act_transport_forwards.setEnabled(enabled) | self.ui.act_transport_forwards.setEnabled(enabled) | ||||
| self.ui.menu_Transport.setEnabled(enabled) | self.ui.menu_Transport.setEnabled(enabled) | ||||
| # ----------------------------------------------------------------- | |||||
| # Internal stuff (settings) | |||||
| def loadSettings(self, doGeometry): | |||||
| settings = QSettings() | |||||
| if doGeometry: | |||||
| self.restoreGeometry(settings.value("Geometry", "")) | |||||
| showToolbar = settings.value("ShowToolbar", True, type=bool) | |||||
| self.ui.act_settings_show_toolbar.setChecked(showToolbar) | |||||
| self.ui.toolBar.setVisible(showToolbar) | |||||
| #if settings.contains("SplitterState"): | |||||
| #self.ui.splitter.restoreState(settings.value("SplitterState", "")) | |||||
| #else: | |||||
| #self.ui.splitter.setSizes([99999, 210]) | |||||
| #diskFolders = toList(settings.value("DiskFolders", [HOME])) | |||||
| #self.ui.cb_disk.setItemData(0, HOME) | |||||
| #for i in range(len(diskFolders)): | |||||
| #if i == 0: continue | |||||
| #folder = diskFolders[i] | |||||
| #self.ui.cb_disk.addItem(os.path.basename(folder), folder) | |||||
| if MACOS and not settings.value("Main/UseProTheme", True, type=bool): | |||||
| self.setUnifiedTitleAndToolBarOnMac(True) | |||||
| # --------------------------------------------- | |||||
| # plugin checks | |||||
| if settings.value("Engine/DisableChecks", False, type=bool): | |||||
| os.environ["CARLA_DISCOVERY_NO_PROCESSING_CHECKS"] = "true" | |||||
| elif os.getenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS"): | |||||
| os.environ.pop("CARLA_DISCOVERY_NO_PROCESSING_CHECKS") | |||||
| # --------------------------------------------- | |||||
| if not Carla.isPlugin: | |||||
| # engine | |||||
| self.setEngineSettings(settings) | |||||
| # plugin paths | |||||
| LADSPA_PATH = toList(settings.value("Paths/LADSPA", Carla.DEFAULT_LADSPA_PATH)) | |||||
| DSSI_PATH = toList(settings.value("Paths/DSSI", Carla.DEFAULT_DSSI_PATH)) | |||||
| LV2_PATH = toList(settings.value("Paths/LV2", Carla.DEFAULT_LV2_PATH)) | |||||
| VST_PATH = toList(settings.value("Paths/VST", Carla.DEFAULT_VST_PATH)) | |||||
| AU_PATH = toList(settings.value("Paths/AU", Carla.DEFAULT_AU_PATH)) | |||||
| CSOUND_PATH = toList(settings.value("Paths/CSOUND", Carla.DEFAULT_CSOUND_PATH)) | |||||
| GIG_PATH = toList(settings.value("Paths/GIG", Carla.DEFAULT_GIG_PATH)) | |||||
| SF2_PATH = toList(settings.value("Paths/SF2", Carla.DEFAULT_SF2_PATH)) | |||||
| SFZ_PATH = toList(settings.value("Paths/SFZ", Carla.DEFAULT_SFZ_PATH)) | |||||
| os.environ["LADSPA_PATH"] = splitter.join(LADSPA_PATH) | |||||
| os.environ["DSSI_PATH"] = splitter.join(DSSI_PATH) | |||||
| os.environ["LV2_PATH"] = splitter.join(LV2_PATH) | |||||
| os.environ["VST_PATH"] = splitter.join(VST_PATH) | |||||
| os.environ["AU_PATH"] = splitter.join(AU_PATH) | |||||
| os.environ["CSOUND_PATH"] = splitter.join(CSOUND_PATH) | |||||
| os.environ["GIG_PATH"] = splitter.join(GIG_PATH) | |||||
| os.environ["SF2_PATH"] = splitter.join(SF2_PATH) | |||||
| os.environ["SFZ_PATH"] = splitter.join(SFZ_PATH) | |||||
| # --------------------------------------------- | |||||
| useCustomMiniCanvasPaint = bool(settings.value("Main/UseProTheme", True, type=bool) and | |||||
| settings.value("Main/ProThemeColor", "Black", type=str) == "Black") | |||||
| self.fSavedSettings = { | |||||
| "Main/DefaultProjectFolder": settings.value("Main/DefaultProjectFolder", HOME, type=str), | |||||
| "Main/RefreshInterval": settings.value("Main/RefreshInterval", 50, type=int), | |||||
| "Canvas/Theme": settings.value("Canvas/Theme", CANVAS_DEFAULT_THEME_NAME, type=str), | |||||
| "Canvas/AutoHideGroups": settings.value("Canvas/AutoHideGroups", False, type=bool), | |||||
| "Canvas/UseBezierLines": settings.value("Canvas/UseBezierLines", True, type=bool), | |||||
| "Canvas/EyeCandy": settings.value("Canvas/EyeCandy", CANVAS_EYECANDY_SMALL, type=int), | |||||
| "Canvas/UseOpenGL": settings.value("Canvas/UseOpenGL", False, type=bool), | |||||
| "Canvas/Antialiasing": settings.value("Canvas/Antialiasing", CANVAS_ANTIALIASING_SMALL, type=int), | |||||
| "Canvas/HighQualityAntialiasing": settings.value("Canvas/HighQualityAntialiasing", False, type=bool), | |||||
| "UseCustomMiniCanvasPaint": useCustomMiniCanvasPaint | |||||
| } | |||||
| # --------------------------------------------- | |||||
| if self.fIdleTimerFast != 0: | |||||
| self.killTimer(self.fIdleTimerFast) | |||||
| self.fIdleTimerFast = self.startTimer(self.fSavedSettings["Main/RefreshInterval"]) | |||||
| if self.fIdleTimerSlow != 0: | |||||
| self.killTimer(self.fIdleTimerSlow) | |||||
| self.fIdleTimerSlow = self.startTimer(self.fSavedSettings["Main/RefreshInterval"]*2) | |||||
| def saveSettings(self): | |||||
| settings = QSettings() | |||||
| settings.setValue("Geometry", self.saveGeometry()) | |||||
| #settings.setValue("SplitterState", self.ui.splitter.saveState()) | |||||
| settings.setValue("ShowToolbar", self.ui.toolBar.isVisible()) | |||||
| #settings.setValue("HorizontalScrollBarValue", self.ui.graphicsView.horizontalScrollBar().value()) | |||||
| #settings.setValue("VerticalScrollBarValue", self.ui.graphicsView.verticalScrollBar().value()) | |||||
| #diskFolders = [] | |||||
| #for i in range(self.ui.cb_disk.count()): | |||||
| #diskFolders.append(self.ui.cb_disk.itemData(i)) | |||||
| #settings.setValue("DiskFolders", diskFolders) | |||||
| self.fContainer.saveSettings(settings) | |||||
| # ----------------------------------------------------------------- | # ----------------------------------------------------------------- | ||||
| # Internal stuff (gui) | # Internal stuff (gui) | ||||
| @@ -680,43 +694,51 @@ class HostWindow(QMainWindow): | |||||
| if doStart: self.startEngine() | if doStart: self.startEngine() | ||||
| check = Carla.host.is_engine_running() | check = Carla.host.is_engine_running() | ||||
| self.ui.act_file_save.setEnabled(check) | |||||
| self.ui.act_engine_start.setEnabled(not check) | |||||
| self.ui.act_engine_stop.setEnabled(check) | |||||
| self.ui.menu_PluginMacros.setEnabled(check) | |||||
| self.ui.menu_Canvas.setEnabled(check) | self.ui.menu_Canvas.setEnabled(check) | ||||
| if self.fSessionManagerName != "Non Session Manager": | |||||
| self.ui.act_file_open.setEnabled(check) | |||||
| self.ui.act_file_save_as.setEnabled(check) | |||||
| if not Carla.isPlugin: | |||||
| self.ui.act_file_save.setEnabled(check) | |||||
| self.ui.act_engine_start.setEnabled(not check) | |||||
| self.ui.act_engine_stop.setEnabled(check) | |||||
| if self.fSessionManagerName != "Non Session Manager": | |||||
| self.ui.act_file_open.setEnabled(check) | |||||
| self.ui.act_file_save_as.setEnabled(check) | |||||
| self.setTransportMenuEnabled(check) | |||||
| if check: | if check: | ||||
| #self.fInfoText = "Engine running | SampleRate: %g | BufferSize: %i" % (self.fSampleRate, self.fBufferSize) | #self.fInfoText = "Engine running | SampleRate: %g | BufferSize: %i" % (self.fSampleRate, self.fBufferSize) | ||||
| self.refreshTransport(True) | |||||
| self.fContainer.engineStarted() | self.fContainer.engineStarted() | ||||
| self.setTransportMenuEnabled(check) | |||||
| if not Carla.isPlugin: | |||||
| self.refreshTransport(True) | |||||
| @pyqtSlot() | @pyqtSlot() | ||||
| def slot_engineStop(self, doStop = True): | def slot_engineStop(self, doStop = True): | ||||
| if doStop: self.stopEngine() | if doStop: self.stopEngine() | ||||
| check = Carla.host.is_engine_running() | check = Carla.host.is_engine_running() | ||||
| self.ui.act_file_save.setEnabled(check) | |||||
| self.ui.act_engine_start.setEnabled(not check) | |||||
| self.ui.act_engine_stop.setEnabled(check) | |||||
| self.ui.menu_PluginMacros.setEnabled(check) | |||||
| self.ui.menu_Canvas.setEnabled(check) | self.ui.menu_Canvas.setEnabled(check) | ||||
| if self.fSessionManagerName != "Non Session Manager": | |||||
| self.ui.act_file_open.setEnabled(check) | |||||
| self.ui.act_file_save_as.setEnabled(check) | |||||
| if not Carla.isPlugin: | |||||
| self.ui.act_file_save.setEnabled(check) | |||||
| self.ui.act_engine_start.setEnabled(not check) | |||||
| self.ui.act_engine_stop.setEnabled(check) | |||||
| if self.fSessionManagerName != "Non Session Manager": | |||||
| self.ui.act_file_open.setEnabled(check) | |||||
| self.ui.act_file_save_as.setEnabled(check) | |||||
| self.setTransportMenuEnabled(check) | |||||
| if not check: | if not check: | ||||
| self.fContainer.engineStopped() | self.fContainer.engineStopped() | ||||
| #self.fInfoText = "" | #self.fInfoText = "" | ||||
| #self.fInfoLabel.setText("Engine stopped") | #self.fInfoLabel.setText("Engine stopped") | ||||
| self.setTransportMenuEnabled(check) | |||||
| # ----------------------------------------------------------------- | # ----------------------------------------------------------------- | ||||
| @pyqtSlot() | @pyqtSlot() | ||||
| @@ -884,9 +906,11 @@ class HostWindow(QMainWindow): | |||||
| def timerEvent(self, event): | def timerEvent(self, event): | ||||
| if event.timerId() == self.fIdleTimerFast: | if event.timerId() == self.fIdleTimerFast: | ||||
| Carla.host.engine_idle() | |||||
| if not Carla.isPlugin: | |||||
| Carla.host.engine_idle() | |||||
| self.refreshTransport() | |||||
| self.fContainer.idleFast() | self.fContainer.idleFast() | ||||
| self.refreshTransport() | |||||
| elif event.timerId() == self.fIdleTimerSlow: | elif event.timerId() == self.fIdleTimerSlow: | ||||
| self.fContainer.idleSlow() | self.fContainer.idleSlow() | ||||
| @@ -38,10 +38,10 @@ from carla_widgets import * | |||||
| # Try Import OpenGL | # Try Import OpenGL | ||||
| try: | try: | ||||
| #try: | |||||
| from PyQt5.QtOpenGL import QGLWidget | |||||
| #except: | |||||
| #from PyQt4.QtOpenGL import QGLWidget | |||||
| try: | |||||
| from PyQt5.QtOpenGL import QGLWidget | |||||
| except: | |||||
| from PyQt4.QtOpenGL import QGLWidget | |||||
| hasGL = True | hasGL = True | ||||
| except: | except: | ||||
| hasGL = False | hasGL = False | ||||
| @@ -65,17 +65,17 @@ class CarlaPatchbayW(QGraphicsView): | |||||
| self.scene = patchcanvas.PatchScene(self, self) # FIXME? | self.scene = patchcanvas.PatchScene(self, self) # FIXME? | ||||
| self.setScene(self.scene) | self.setScene(self.scene) | ||||
| #self.setRenderHint(QPainter.Antialiasing, bool(self.fSavedSettings["Canvas/Antialiasing"] == patchcanvas.ANTIALIASING_FULL)) | |||||
| #if self.fSavedSettings["Canvas/UseOpenGL"] and hasGL: | |||||
| #self.setViewport(QGLWidget(self)) | |||||
| #self.setRenderHint(QPainter.HighQualityAntialiasing, self.fSavedSettings["Canvas/HighQualityAntialiasing"]) | |||||
| #pOptions = patchcanvas.options_t() | |||||
| #pOptions.theme_name = self.fSavedSettings["Canvas/Theme"] | |||||
| #pOptions.auto_hide_groups = self.fSavedSettings["Canvas/AutoHideGroups"] | |||||
| #pOptions.use_bezier_lines = self.fSavedSettings["Canvas/UseBezierLines"] | |||||
| #pOptions.antialiasing = self.fSavedSettings["Canvas/Antialiasing"] | |||||
| #pOptions.eyecandy = self.fSavedSettings["Canvas/EyeCandy"] | |||||
| self.setRenderHint(QPainter.Antialiasing, bool(parent.fSavedSettings["Canvas/Antialiasing"] == patchcanvas.ANTIALIASING_FULL)) | |||||
| if parent.fSavedSettings["Canvas/UseOpenGL"] and hasGL: | |||||
| self.setViewport(QGLWidget(self)) | |||||
| self.setRenderHint(QPainter.HighQualityAntialiasing, parent.fSavedSettings["Canvas/HighQualityAntialiasing"]) | |||||
| pOptions = patchcanvas.options_t() | |||||
| pOptions.theme_name = parent.fSavedSettings["Canvas/Theme"] | |||||
| pOptions.auto_hide_groups = parent.fSavedSettings["Canvas/AutoHideGroups"] | |||||
| pOptions.use_bezier_lines = parent.fSavedSettings["Canvas/UseBezierLines"] | |||||
| pOptions.antialiasing = parent.fSavedSettings["Canvas/Antialiasing"] | |||||
| pOptions.eyecandy = parent.fSavedSettings["Canvas/EyeCandy"] | |||||
| pFeatures = patchcanvas.features_t() | pFeatures = patchcanvas.features_t() | ||||
| pFeatures.group_info = False | pFeatures.group_info = False | ||||
| @@ -84,7 +84,7 @@ class CarlaPatchbayW(QGraphicsView): | |||||
| pFeatures.port_rename = False | pFeatures.port_rename = False | ||||
| pFeatures.handle_group_pos = True | pFeatures.handle_group_pos = True | ||||
| #patchcanvas.setOptions(pOptions) | |||||
| patchcanvas.setOptions(pOptions) | |||||
| patchcanvas.setFeatures(pFeatures) | patchcanvas.setFeatures(pFeatures) | ||||
| patchcanvas.init("Carla", self.scene, CanvasCallback, True) | patchcanvas.init("Carla", self.scene, CanvasCallback, True) | ||||
| @@ -334,18 +334,18 @@ class CarlaPatchbayW(QGraphicsView): | |||||
| @pyqtSlot() | @pyqtSlot() | ||||
| def slot_configureCarla(self): | def slot_configureCarla(self): | ||||
| if self.fParent is None or not self.fParent.openSettings(False, False): | |||||
| if self.fParent is None or not self.fParent.openSettingsWindow(False, False): | |||||
| return | return | ||||
| #self.loadSettings(False) | |||||
| self.fParent.loadSettings(False) | |||||
| patchcanvas.clear() | patchcanvas.clear() | ||||
| #pOptions = patchcanvas.options_t() | |||||
| #pOptions.theme_name = self.fSavedSettings["Canvas/Theme"] | |||||
| #pOptions.auto_hide_groups = self.fSavedSettings["Canvas/AutoHideGroups"] | |||||
| #pOptions.use_bezier_lines = self.fSavedSettings["Canvas/UseBezierLines"] | |||||
| #pOptions.antialiasing = self.fSavedSettings["Canvas/Antialiasing"] | |||||
| #pOptions.eyecandy = self.fSavedSettings["Canvas/EyeCandy"] | |||||
| pOptions = patchcanvas.options_t() | |||||
| pOptions.theme_name = self.fParent.fSavedSettings["Canvas/Theme"] | |||||
| pOptions.auto_hide_groups = self.fParent.fSavedSettings["Canvas/AutoHideGroups"] | |||||
| pOptions.use_bezier_lines = self.fParent.fSavedSettings["Canvas/UseBezierLines"] | |||||
| pOptions.antialiasing = self.fParent.fSavedSettings["Canvas/Antialiasing"] | |||||
| pOptions.eyecandy = self.fParent.fSavedSettings["Canvas/EyeCandy"] | |||||
| pFeatures = patchcanvas.features_t() | pFeatures = patchcanvas.features_t() | ||||
| pFeatures.group_info = False | pFeatures.group_info = False | ||||
| @@ -354,7 +354,7 @@ class CarlaPatchbayW(QGraphicsView): | |||||
| pFeatures.port_rename = False | pFeatures.port_rename = False | ||||
| pFeatures.handle_group_pos = True | pFeatures.handle_group_pos = True | ||||
| #patchcanvas.setOptions(pOptions) | |||||
| patchcanvas.setOptions(pOptions) | |||||
| patchcanvas.setFeatures(pFeatures) | patchcanvas.setFeatures(pFeatures) | ||||
| patchcanvas.init("Carla", self.scene, CanvasCallback, False) | patchcanvas.init("Carla", self.scene, CanvasCallback, False) | ||||
| @@ -329,10 +329,10 @@ class CarlaRackW(QListWidget): | |||||
| @pyqtSlot() | @pyqtSlot() | ||||
| def slot_configureCarla(self): | def slot_configureCarla(self): | ||||
| if self.fParent is None or not self.fParent.openSettings(False, False): | |||||
| if self.fParent is None or not self.fParent.openSettingsWindow(False, False): | |||||
| return | return | ||||
| #self.loadSettings(False) | |||||
| self.loadSettings(False) | |||||
| # ----------------------------------------------------------------- | # ----------------------------------------------------------------- | ||||
| @@ -216,6 +216,14 @@ class CarlaSettingsW(QDialog): | |||||
| self.ui.group_theme.setEnabled(False) | self.ui.group_theme.setEnabled(False) | ||||
| self.ui.ch_theme_pro.setChecked(False) | self.ui.ch_theme_pro.setChecked(False) | ||||
| if Carla.isPlugin: | |||||
| self.ui.lw_page.hideRow(self.TAB_INDEX_CARLA_ENGINE) | |||||
| self.ui.lw_page.hideRow(self.TAB_INDEX_CARLA_PATHS) | |||||
| #from PyQt4.QtGui import QTableWidget | |||||
| #x = QTableWidget(self) | |||||
| #x.() | |||||
| # ------------------------------------------------------------- | # ------------------------------------------------------------- | ||||
| # Set-up connections | # Set-up connections | ||||
| @@ -311,8 +311,10 @@ class CarlaObject(object): | |||||
| 'gui', | 'gui', | ||||
| # bool, is controller | # bool, is controller | ||||
| 'isControl', | 'isControl', | ||||
| # bool, is controller local | |||||
| # bool, is running local | |||||
| 'isLocal', | 'isLocal', | ||||
| # bool, is plugin | |||||
| 'isPlugin', | |||||
| # current process mode | # current process mode | ||||
| 'processMode', | 'processMode', | ||||
| # current max parameters | # current max parameters | ||||
| @@ -340,6 +342,7 @@ Carla.host = None | |||||
| Carla.gui = None | Carla.gui = None | ||||
| Carla.isControl = False | Carla.isControl = False | ||||
| Carla.isLocal = True | Carla.isLocal = True | ||||
| Carla.isPlugin = False | |||||
| Carla.processMode = PROCESS_MODE_MULTIPLE_CLIENTS if LINUX else PROCESS_MODE_CONTINUOUS_RACK | Carla.processMode = PROCESS_MODE_MULTIPLE_CLIENTS if LINUX else PROCESS_MODE_CONTINUOUS_RACK | ||||
| Carla.maxParameters = MAX_DEFAULT_PARAMETERS | Carla.maxParameters = MAX_DEFAULT_PARAMETERS | ||||
| @@ -102,6 +102,8 @@ class CarlaAboutW(QDialog): | |||||
| if Carla.isControl: | if Carla.isControl: | ||||
| extraInfo = " - <b>%s</b>" % self.tr("OSC Bridge Version") | extraInfo = " - <b>%s</b>" % self.tr("OSC Bridge Version") | ||||
| elif Carla.isPlugin: | |||||
| extraInfo = " - <b>%s</b>" % self.tr("Plugin Version") | |||||
| else: | else: | ||||
| extraInfo = "" | extraInfo = "" | ||||
| @@ -111,7 +113,7 @@ class CarlaAboutW(QDialog): | |||||
| "<br>Copyright (C) 2011-2013 falkTX<br>" | "<br>Copyright (C) 2011-2013 falkTX<br>" | ||||
| "" % (VERSION, extraInfo))) | "" % (VERSION, extraInfo))) | ||||
| if Carla.host is None: | |||||
| if Carla.isControl or Carla.isPlugin or Carla.host is None: | |||||
| self.ui.l_extended.hide() | self.ui.l_extended.hide() | ||||
| self.ui.tabWidget.removeTab(1) | self.ui.tabWidget.removeTab(1) | ||||
| self.ui.tabWidget.removeTab(1) | self.ui.tabWidget.removeTab(1) | ||||
| @@ -337,6 +337,10 @@ const char* CallbackType2Str(const CallbackType type) | |||||
| return "CALLBACK_SAMPLE_RATE_CHANGED"; | return "CALLBACK_SAMPLE_RATE_CHANGED"; | ||||
| case CALLBACK_PROCESS_MODE_CHANGED: | case CALLBACK_PROCESS_MODE_CHANGED: | ||||
| return "CALLBACK_PROCESS_MODE_CHANGED"; | return "CALLBACK_PROCESS_MODE_CHANGED"; | ||||
| case CALLBACK_ENGINE_STARTED: | |||||
| return "CALLBACK_ENGINE_STARTED"; | |||||
| case CALLBACK_ENGINE_STOPPED: | |||||
| return "CALLBACK_ENGINE_STOPPED"; | |||||
| case CALLBACK_NSM_ANNOUNCE: | case CALLBACK_NSM_ANNOUNCE: | ||||
| return "CALLBACK_NSM_ANNOUNCE"; | return "CALLBACK_NSM_ANNOUNCE"; | ||||
| case CALLBACK_NSM_OPEN: | case CALLBACK_NSM_OPEN: | ||||