diff --git a/c++/carla-backend/carla_engine.cpp b/c++/carla-backend/carla_engine.cpp index 0a38459..c313343 100644 --- a/c++/carla-backend/carla_engine.cpp +++ b/c++/carla-backend/carla_engine.cpp @@ -286,7 +286,9 @@ short CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, con case PLUGIN_NONE: break; case PLUGIN_INTERNAL: +#ifndef BUILD_BRIDGE plugin = CarlaPlugin::newNative(init); +#endif break; case PLUGIN_LADSPA: plugin = CarlaPlugin::newLADSPA(init, extra); diff --git a/c++/carla-backend/carla_native.cpp b/c++/carla-backend/carla_native.cpp index 64ab8e9..7726bd1 100644 --- a/c++/carla-backend/carla_native.cpp +++ b/c++/carla-backend/carla_native.cpp @@ -91,7 +91,6 @@ public: midiEventCount = 0; memset(midiEvents, 0, sizeof(::MidiEvent) * MAX_MIDI_EVENTS * 2); - memset(midiEventOffsets, 0, sizeof(uint32_t) * MAX_MIDI_EVENTS * 2); } ~NativePlugin() @@ -540,13 +539,13 @@ public: { if (portHints & PORT_HINT_IS_OUTPUT) { - j = aOut.count++; + j = mOut.count++; mOut.ports[j] = (CarlaEngineMidiPort*)x_client->addPort(CarlaEnginePortTypeMIDI, portName, false); mOut.rindexes[j] = i; } else { - j = aIn.count++; + j = mIn.count++; mIn.ports[j] = (CarlaEngineMidiPort*)x_client->addPort(CarlaEnginePortTypeMIDI, portName, true); mIn.rindexes[j] = i; } @@ -684,6 +683,8 @@ public: aIn.count = aIns; aOut.count = aOuts; + mIn.count = mIns; + mOut.count = mOuts; param.count = params; // plugin checks @@ -811,7 +812,6 @@ public: // reset MIDI midiEventCount = 0; memset(midiEvents, 0, sizeof(::MidiEvent) * MAX_MIDI_EVENTS * 2); - memset(midiEventOffsets, 0, sizeof(uint32_t) * MAX_MIDI_EVENTS * 2); CARLA_PROCESS_CONTINUE_CHECK; @@ -984,7 +984,7 @@ public: case CarlaEngineEventAllSoundOff: if (cinEvent->channel == m_ctrlInChannel) { - if (midi.portMin && ! allNotesOffSent) + if (mIn.count > 0 && ! allNotesOffSent) sendMidiAllNotesOff(); if (descriptor->deactivate) @@ -1006,7 +1006,7 @@ public: case CarlaEngineEventAllNotesOff: if (cinEvent->channel == m_ctrlInChannel) { - if (midi.portMin && ! allNotesOffSent) + if (mIn.count > 0 && ! allNotesOffSent) sendMidiAllNotesOff(); allNotesOffSent = true; @@ -1055,13 +1055,17 @@ public: // ---------------------------------------------------------------------------------------------------- // MIDI Input (System) + for (i=0; i < mIn.count; i++) { + if (! mIn.ports[i]) + continue; + const CarlaEngineMidiEvent* minEvent; - uint32_t time, nEvents = midi.portMin->getEventCount(); + uint32_t time, nEvents = mIn.ports[i]->getEventCount(); - for (i=0; i < nEvents && midiEventCount < MAX_MIDI_EVENTS; i++) + for (k=0; k < nEvents && midiEventCount < MAX_MIDI_EVENTS; k++) { - minEvent = midi.portMin->getEvent(i); + minEvent = mIn.ports[i]->getEvent(k); if (! minEvent) continue; @@ -1081,8 +1085,9 @@ public: ::MidiEvent* const midiEvent = &midiEvents[midiEventCount]; memset(midiEvent, 0, sizeof(::MidiEvent)); - midiEvent->size = minEvent->size; + midiEvent->portOffset = i; midiEvent->time = minEvent->time; + midiEvent->size = minEvent->size; if (MIDI_IS_STATUS_NOTE_OFF(status)) { @@ -1287,7 +1292,7 @@ public: if (MIDI_IS_STATUS_NOTE_ON(data[0]) && data[2] == 0) data[0] -= 0x10; - const uint32_t portOffset = midiEventOffsets[i]; + const uint32_t portOffset = midiEvents[i].portOffset; if (portOffset < mOut.count) mOut.ports[portOffset]->writeEvent(midiEvents[i].time, data, 3); @@ -1420,7 +1425,7 @@ public: return nullptr; } - bool handleWriteMidiEvent(uint32_t portOffset, MidiEvent* event) + bool handleWriteMidiEvent(MidiEvent* event) { Q_ASSERT(m_enabled); Q_ASSERT(mOut.count > 0); @@ -1435,7 +1440,7 @@ public: if (! isProcessing) { - qCritical("NativePlugin::handleWriteMidiEvent(%i, %p) - received MIDI out events outside audio thread, ignoring", portOffset, event); + qCritical("NativePlugin::handleWriteMidiEvent(%p) - received MIDI out events outside audio thread, ignoring", event); return false; } @@ -1443,7 +1448,6 @@ public: return false; memcpy(&midiEvents[midiEventCount], event, sizeof(::MidiEvent)); - midiEventOffsets[midiEventCount] = portOffset; midiEventCount += 1; return true; @@ -1467,10 +1471,10 @@ public: return ((NativePlugin*)handle)->handleGetTimeInfo(); } - static bool carla_host_write_midi_event(HostHandle handle, uint32_t port_offset, MidiEvent* event) + static bool carla_host_write_midi_event(HostHandle handle, MidiEvent* event) { Q_ASSERT(handle); - return ((NativePlugin*)handle)->handleWriteMidiEvent(port_offset, event); + return ((NativePlugin*)handle)->handleWriteMidiEvent(event); } // ------------------------------------------------------------------- @@ -1567,7 +1571,6 @@ private: uint32_t midiEventCount; ::MidiEvent midiEvents[MAX_MIDI_EVENTS*2]; - uint32_t midiEventOffsets[MAX_MIDI_EVENTS*2]; static std::vector pluginDescriptors; }; diff --git a/c++/carla-backend/lv2.cpp b/c++/carla-backend/lv2.cpp index a87a6d5..7d99abe 100644 --- a/c++/carla-backend/lv2.cpp +++ b/c++/carla-backend/lv2.cpp @@ -2052,7 +2052,7 @@ public: case CarlaEngineEventAllSoundOff: if (cinEvent->channel == m_ctrlInChannel) { - if (midi.portMin && ! allNotesOffSent) + if (evIn.count > 0 && ! allNotesOffSent) sendMidiAllNotesOff(); if (descriptor->deactivate) @@ -2074,7 +2074,7 @@ public: case CarlaEngineEventAllNotesOff: if (cinEvent->channel == m_ctrlInChannel) { - if (midi.portMin && ! allNotesOffSent) + if (evIn.count > 0 && ! allNotesOffSent) sendMidiAllNotesOff(); allNotesOffSent = true; @@ -2107,7 +2107,7 @@ public: midiEvent[1] = extMidiNotes[i].note; midiEvent[2] = extMidiNotes[i].velo; - // send to all midi inputs + // send to first midi input for (k=0; k < evIn.count; k++) { if (evIn.data[k].type & CARLA_EVENT_TYPE_MIDI) @@ -2132,6 +2132,8 @@ public: { lv2midi_put_event(&evInMidiStates[k], 0, 3, midiEvent); } + + break; } } @@ -2148,66 +2150,64 @@ public: // ---------------------------------------------------------------------------------------------------- // MIDI Input (System) + for (i=0; i < evIn.count; i++) { - for (i=0; i < evIn.count; i++) - { - if (! evIn.data[i].port) - continue; + if (! evIn.data[i].port) + continue; - const CarlaEngineMidiEvent* minEvent; - uint32_t time, nEvents = evIn.data[i].port->getEventCount(); + const CarlaEngineMidiEvent* minEvent; + uint32_t time, nEvents = evIn.data[i].port->getEventCount(); - for (k=0; k < nEvents && midiEventCount < MAX_MIDI_EVENTS; k++) - { - minEvent = evIn.data[i].port->getEvent(k); + for (k=0; k < nEvents && midiEventCount < MAX_MIDI_EVENTS; k++) + { + minEvent = evIn.data[i].port->getEvent(k); - if (! minEvent) - continue; + if (! minEvent) + continue; - time = minEvent->time - framesOffset; + time = minEvent->time - framesOffset; - if (time >= frames) - continue; + if (time >= frames) + continue; - uint8_t status = minEvent->data[0]; - uint8_t channel = status & 0x0F; + uint8_t status = minEvent->data[0]; + uint8_t channel = status & 0x0F; - // Fix bad note-off - if (MIDI_IS_STATUS_NOTE_ON(status) && minEvent->data[2] == 0) - status -= 0x10; + // Fix bad note-off + if (MIDI_IS_STATUS_NOTE_ON(status) && minEvent->data[2] == 0) + status -= 0x10; - // only write supported status types - if (MIDI_IS_STATUS_NOTE_OFF(status) || MIDI_IS_STATUS_NOTE_ON(status) || MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status) || MIDI_IS_STATUS_AFTERTOUCH(status) || MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status)) + // only write supported status types + if (MIDI_IS_STATUS_NOTE_OFF(status) || MIDI_IS_STATUS_NOTE_ON(status) || MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status) || MIDI_IS_STATUS_AFTERTOUCH(status) || MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status)) + { + if (evIn.data[i].type & CARLA_EVENT_DATA_ATOM) { - if (evIn.data[i].type & CARLA_EVENT_DATA_ATOM) - { - LV2_Atom_Event* const aev = getLv2AtomEvent(evIn.data[i].atom, evInAtomOffsets[i]); - aev->time.frames = time; - aev->body.type = CARLA_URI_MAP_ID_MIDI_EVENT; - aev->body.size = minEvent->size; - memcpy(LV2_ATOM_BODY(&aev->body), minEvent->data, minEvent->size); - - const uint32_t evInPadSize = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + minEvent->size); - evInAtomOffsets[i] += evInPadSize; - evIn.data[i].atom->atom.size += evInPadSize; - } - else if (evIn.data[i].type & CARLA_EVENT_DATA_EVENT) - { - lv2_event_write(&evInEventIters[i], time, 0, CARLA_URI_MAP_ID_MIDI_EVENT, minEvent->size, minEvent->data); - } - else if (evIn.data[i].type & CARLA_EVENT_DATA_MIDI_LL) - { - lv2midi_put_event(&evInMidiStates[i], time, minEvent->size, minEvent->data); - } + LV2_Atom_Event* const aev = getLv2AtomEvent(evIn.data[i].atom, evInAtomOffsets[i]); + aev->time.frames = time; + aev->body.type = CARLA_URI_MAP_ID_MIDI_EVENT; + aev->body.size = minEvent->size; + memcpy(LV2_ATOM_BODY(&aev->body), minEvent->data, minEvent->size); - if (MIDI_IS_STATUS_NOTE_OFF(status)) - postponeEvent(PluginPostEventNoteOff, channel, minEvent->data[1], 0.0); - else if (MIDI_IS_STATUS_NOTE_ON(status)) - postponeEvent(PluginPostEventNoteOn, channel, minEvent->data[1], minEvent->data[2]); + const uint32_t evInPadSize = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + minEvent->size); + evInAtomOffsets[i] += evInPadSize; + evIn.data[i].atom->atom.size += evInPadSize; + } + else if (evIn.data[i].type & CARLA_EVENT_DATA_EVENT) + { + lv2_event_write(&evInEventIters[i], time, 0, CARLA_URI_MAP_ID_MIDI_EVENT, minEvent->size, minEvent->data); + } + else if (evIn.data[i].type & CARLA_EVENT_DATA_MIDI_LL) + { + lv2midi_put_event(&evInMidiStates[i], time, minEvent->size, minEvent->data); } - midiEventCount += 1; + if (MIDI_IS_STATUS_NOTE_OFF(status)) + postponeEvent(PluginPostEventNoteOff, channel, minEvent->data[1], 0.0); + else if (MIDI_IS_STATUS_NOTE_ON(status)) + postponeEvent(PluginPostEventNoteOn, channel, minEvent->data[1], minEvent->data[2]); } + + midiEventCount += 1; } } // End of MIDI Input (System) diff --git a/c++/carla-backend/plugins/carla_native.h b/c++/carla-backend/plugins/carla_native.h index 3ff2670..688c270 100644 --- a/c++/carla-backend/plugins/carla_native.h +++ b/c++/carla-backend/plugins/carla_native.h @@ -73,6 +73,7 @@ typedef struct _ParameterRanges { } ParameterRanges; typedef struct _MidiEvent { + uint32_t portOffset; uint32_t time; uint8_t size; uint8_t data[4]; @@ -108,7 +109,7 @@ typedef struct _HostDescriptor { uint32_t (*get_buffer_size)(HostHandle handle); double (*get_sample_rate)(HostHandle handle); const TimeInfo* (*get_time_info)(HostHandle handle); - bool (*write_midi_event)(HostHandle handle, uint32_t port_offset, MidiEvent* event); + bool (*write_midi_event)(HostHandle handle, MidiEvent* event); } HostDescriptor; typedef struct _PluginPortScalePoint { diff --git a/c++/carla-backend/plugins/carla_nativemm.h b/c++/carla-backend/plugins/carla_nativemm.h index 3625633..eff998f 100644 --- a/c++/carla-backend/plugins/carla_nativemm.h +++ b/c++/carla-backend/plugins/carla_nativemm.h @@ -97,12 +97,12 @@ public: return nullptr; } - void writeMidiEvent(uint32_t portOffset, MidiEvent* event) + void writeMidiEvent(MidiEvent* event) { Q_ASSERT(host); if (host) - host->write_midi_event(host->handle, portOffset, event); + host->write_midi_event(host->handle, event); } // ------------------------------------------------------------------- diff --git a/c++/carla-backend/plugins/midi-split.cpp b/c++/carla-backend/plugins/midi-split.cpp index 23a43e6..c9964b5 100644 --- a/c++/carla-backend/plugins/midi-split.cpp +++ b/c++/carla-backend/plugins/midi-split.cpp @@ -163,8 +163,11 @@ protected: continue; status -= channel; - midiEvent.data[0] = status; - //writeMidiEvent(channel, midiEvent); + + midiEvent.portOffset = channel; + midiEvent.data[0] = status; + + writeMidiEvent(&midiEvent); } } diff --git a/src/carla.py b/src/carla.py index c93cae0..7c09c81 100755 --- a/src/carla.py +++ b/src/carla.py @@ -648,7 +648,12 @@ class PluginDatabaseW(QDialog, ui_carla_database.Ui_PluginDatabaseW): QDialog.__init__(self, parent) self.setupUi(self) - self.warning_old_shown = False + self.m_showOldWarning = False + + self.settings = self.parent().settings + self.settings_db = self.parent().settings_db + self.loadSettings() + self.b_add.setEnabled(False) if BINARY_NATIVE in (BINARY_POSIX32, BINARY_WIN32): @@ -656,10 +661,6 @@ class PluginDatabaseW(QDialog, ui_carla_database.Ui_PluginDatabaseW): else: self.ch_bridged.setText(self.tr("Bridged (32bit)")) - self.settings = self.parent().settings - self.settings_db = self.parent().settings_db - self.loadSettings() - if not (LINUX or MACOS): self.ch_bridged_wine.setChecked(False) self.ch_bridged_wine.setEnabled(False) @@ -706,6 +707,9 @@ class PluginDatabaseW(QDialog, ui_carla_database.Ui_PluginDatabaseW): self.ret_plugin = None + if self.m_showOldWarning: + QTimer.singleShot(0, self, SLOT("slot_showOldWarning()")) + def showFilters(self, yesno): self.tb_filters.setArrowType(Qt.UpArrow if yesno else Qt.DownArrow) self.frame.setVisible(yesno) @@ -832,10 +836,8 @@ class PluginDatabaseW(QDialog, ui_carla_database.Ui_PluginDatabaseW): def addPluginToTable(self, plugin, ptype): index = self.last_table_index - if "build" not in plugin.keys(): - if not self.warning_old_shown: - QMessageBox.warning(self, self.tr("Warning"), self.tr("You're using a Carla-Database from an old version of Carla, please update *all* the plugins")) - self.warning_old_shown = True + if self.m_showOldWarning or 'API' not in plugin.keys() or plugin['API'] < PLUGIN_QUERY_API_VERSION: + self.m_showOldWarning = True return if plugin['build'] == BINARY_NATIVE: @@ -1005,6 +1007,10 @@ class PluginDatabaseW(QDialog, ui_carla_database.Ui_PluginDatabaseW): text in self.tableWidget.item(i, 13).text().lower())): self.tableWidget.hideRow(i) + @pyqtSlot() + def slot_showOldWarning(self): + QMessageBox.warning(self, self.tr("Warning"), self.tr("You're using a Carla-Database from an old version of Carla, please update *all* the plugins")) + def saveSettings(self): self.settings.setValue("PluginDatabase/Geometry", self.saveGeometry()) self.settings.setValue("PluginDatabase/TableGeometry", self.tableWidget.horizontalHeader().saveState()) @@ -1790,8 +1796,8 @@ class CarlaMainW(QMainWindow, ui_carla.Ui_CarlaMainW): plugin = None if plugin: - btype = plugin['build'] - ptype = plugin['type'] + btype = plugin['build'] + ptype = plugin['type'] filename = plugin['binary'] name = x_save_state_dict['Name'] label = plugin['label'] diff --git a/src/carla_backend.py b/src/carla_backend.py index 158323a..cf2db33 100644 --- a/src/carla_backend.py +++ b/src/carla_backend.py @@ -502,7 +502,10 @@ def findDSSIGUI(filename, name, label): # ------------------------------------------------------------------------------------------------ # Plugin Query +PLUGIN_QUERY_API_VERSION = 1 + PyPluginInfo = { + 'API': PLUGIN_QUERY_API_VERSION, 'build': 0, # BINARY_NONE 'type': 0, # PLUGIN_NONE, 'hints': 0x0,