@@ -1421,7 +1421,7 @@ CarlaPlugin* CarlaPlugin::newBridge(const Initializer& init, BinaryType btype, P | |||||
return nullptr; | return nullptr; | ||||
} | } | ||||
BridgePlugin* const plugin = new BridgePlugin(init.engine, init.id, btype, ptype); | |||||
BridgePlugin* const plugin(new BridgePlugin(init.engine, init.id, btype, ptype)); | |||||
if (! plugin->init(init.filename, init.name, init.label, bridgeBinary)) | if (! plugin->init(init.filename, init.name, init.label, bridgeBinary)) | ||||
{ | { | ||||
@@ -1942,7 +1942,7 @@ CarlaPlugin* CarlaPlugin::newDSSI(const Initializer& init, const char* const gui | |||||
carla_debug("CarlaPlugin::newDSSI({%p, \"%s\", \"%s\", \"%s\"}, \"%s\")", init.engine, init.filename, init.name, init.label, guiFilename); | carla_debug("CarlaPlugin::newDSSI({%p, \"%s\", \"%s\", \"%s\"}, \"%s\")", init.engine, init.filename, init.name, init.label, guiFilename); | ||||
#ifdef WANT_DSSI | #ifdef WANT_DSSI | ||||
DssiPlugin* const plugin = new DssiPlugin(init.engine, init.id); | |||||
DssiPlugin* const plugin(new DssiPlugin(init.engine, init.id)); | |||||
if (! plugin->init(init.filename, init.name, init.label, guiFilename)) | if (! plugin->init(init.filename, init.name, init.label, guiFilename)) | ||||
{ | { | ||||
@@ -25,6 +25,12 @@ | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
#if 0 | |||||
} | |||||
#endif | |||||
#define FLUID_DEFAULT_POLYPHONY 64 | |||||
class FluidSynthPlugin : public CarlaPlugin | class FluidSynthPlugin : public CarlaPlugin | ||||
{ | { | ||||
public: | public: | ||||
@@ -34,12 +40,14 @@ public: | |||||
fSettings(nullptr), | fSettings(nullptr), | ||||
fSynth(nullptr), | fSynth(nullptr), | ||||
fSynthId(-1), | fSynthId(-1), | ||||
fAudio16Buffers(nullptr) | |||||
fAudio16Buffers(nullptr), | |||||
fParamBuffers{0.0f} | |||||
{ | { | ||||
carla_debug("FluidSynthPlugin::FluidSynthPlugin(%p, %i, %s)", engine, id, bool2str(use16Outs)); | carla_debug("FluidSynthPlugin::FluidSynthPlugin(%p, %i, %s)", engine, id, bool2str(use16Outs)); | ||||
// create settings | // create settings | ||||
fSettings = new_fluid_settings(); | fSettings = new_fluid_settings(); | ||||
CARLA_ASSERT(fSettings != nullptr); | |||||
// define settings | // define settings | ||||
fluid_settings_setint(fSettings, "synth.audio-channels", use16Outs ? 16 : 1); | fluid_settings_setint(fSettings, "synth.audio-channels", use16Outs ? 16 : 1); | ||||
@@ -49,6 +57,7 @@ public: | |||||
// create synth | // create synth | ||||
fSynth = new_fluid_synth(fSettings); | fSynth = new_fluid_synth(fSettings); | ||||
CARLA_ASSERT(fSynth != nullptr); | |||||
#ifdef FLUIDSYNTH_VERSION_NEW_API | #ifdef FLUIDSYNTH_VERSION_NEW_API | ||||
fluid_synth_set_sample_rate(fSynth, kData->engine->getSampleRate()); | fluid_synth_set_sample_rate(fSynth, kData->engine->getSampleRate()); | ||||
@@ -61,9 +70,9 @@ public: | |||||
fluid_synth_set_chorus_on(fSynth, 0); | fluid_synth_set_chorus_on(fSynth, 0); | ||||
fluid_synth_set_chorus(fSynth, FLUID_CHORUS_DEFAULT_N, FLUID_CHORUS_DEFAULT_LEVEL, FLUID_CHORUS_DEFAULT_SPEED, FLUID_CHORUS_DEFAULT_DEPTH, FLUID_CHORUS_DEFAULT_TYPE); | fluid_synth_set_chorus(fSynth, FLUID_CHORUS_DEFAULT_N, FLUID_CHORUS_DEFAULT_LEVEL, FLUID_CHORUS_DEFAULT_SPEED, FLUID_CHORUS_DEFAULT_DEPTH, FLUID_CHORUS_DEFAULT_TYPE); | ||||
fluid_synth_set_polyphony(fSynth, 64); | |||||
fluid_synth_set_polyphony(fSynth, FLUID_DEFAULT_POLYPHONY); | |||||
for (int i=0; i < 16; i++) | |||||
for (int i=0; i < MAX_MIDI_CHANNELS; ++i) | |||||
fluid_synth_set_interp_method(fSynth, i, FLUID_INTERP_DEFAULT); | fluid_synth_set_interp_method(fSynth, i, FLUID_INTERP_DEFAULT); | ||||
} | } | ||||
@@ -77,7 +86,7 @@ public: | |||||
delete_fluid_synth(fSynth); | delete_fluid_synth(fSynth); | ||||
delete_fluid_settings(fSettings); | delete_fluid_settings(fSettings); | ||||
deleteBuffers(); | |||||
clearBuffers(); | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -346,7 +355,7 @@ public: | |||||
break; | break; | ||||
case FluidSynthInterpolation: | case FluidSynthInterpolation: | ||||
for (int i=0; i < 16; i++) | |||||
for (int i=0; i < MAX_MIDI_CHANNELS; ++i) | |||||
fluid_synth_set_interp_method(fSynth, i, value); | fluid_synth_set_interp_method(fSynth, i, value); | ||||
break; | break; | ||||
@@ -402,7 +411,10 @@ public: | |||||
// Safely disable plugin for reload | // Safely disable plugin for reload | ||||
const ScopedDisabler sd(this); | const ScopedDisabler sd(this); | ||||
deleteBuffers(); | |||||
if (kData->active) | |||||
deactivate(); | |||||
clearBuffers(); | |||||
uint32_t aOuts, params, j; | uint32_t aOuts, params, j; | ||||
aOuts = kUses16Outs ? 32 : 2; | aOuts = kUses16Outs ? 32 : 2; | ||||
@@ -419,7 +431,7 @@ public: | |||||
if (kUses16Outs) | if (kUses16Outs) | ||||
{ | { | ||||
for (j=0; j < 32; j++) | |||||
for (j=0; j < 32; ++j) | |||||
{ | { | ||||
portName.clear(); | portName.clear(); | ||||
@@ -449,7 +461,7 @@ public: | |||||
fAudio16Buffers = new float*[aOuts]; | fAudio16Buffers = new float*[aOuts]; | ||||
for (j=0; j < aOuts; j++) | |||||
for (j=0; j < aOuts; ++j) | |||||
fAudio16Buffers[j] = nullptr; | fAudio16Buffers[j] = nullptr; | ||||
} | } | ||||
else | else | ||||
@@ -756,19 +768,15 @@ public: | |||||
// extra plugin hints | // extra plugin hints | ||||
kData->extraHints = 0x0; | kData->extraHints = 0x0; | ||||
kData->extraHints |= PLUGIN_HINT_HAS_MIDI_IN; | |||||
kData->extraHints |= PLUGIN_HINT_CAN_RUN_RACK; | kData->extraHints |= PLUGIN_HINT_CAN_RUN_RACK; | ||||
// plugin options | |||||
fOptions = 0x0; | |||||
fOptions |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES; | |||||
fOptions |= PLUGIN_OPTION_SEND_CONTROL_CHANGES; | |||||
fOptions |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE; | |||||
fOptions |= PLUGIN_OPTION_SEND_PITCHBEND; | |||||
fOptions |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF; | |||||
bufferSizeChanged(kData->engine->getBufferSize()); | bufferSizeChanged(kData->engine->getBufferSize()); | ||||
reloadPrograms(true); | reloadPrograms(true); | ||||
if (kData->active) | |||||
activate(); | |||||
carla_debug("FluidSynthPlugin::reload() - end"); | carla_debug("FluidSynthPlugin::reload() - end"); | ||||
} | } | ||||
@@ -814,7 +822,7 @@ public: | |||||
if (kData->midiprog.data[i].bank == 128) | if (kData->midiprog.data[i].bank == 128) | ||||
hasDrums = true; | hasDrums = true; | ||||
i++; | |||||
++i; | |||||
} | } | ||||
//f_sfont->free(f_sfont); | //f_sfont->free(f_sfont); | ||||
@@ -825,7 +833,7 @@ public: | |||||
{ | { | ||||
kData->engine->osc_send_control_set_midi_program_count(fId, count); | kData->engine->osc_send_control_set_midi_program_count(fId, count); | ||||
for (i=0; i < count; i++) | |||||
for (i=0; i < count; ++i) | |||||
kData->engine->osc_send_control_set_midi_program_data(fId, i, kData->midiprog.data[i].bank, kData->midiprog.data[i].program, kData->midiprog.data[i].name); | kData->engine->osc_send_control_set_midi_program_data(fId, i, kData->midiprog.data[i].bank, kData->midiprog.data[i].program, kData->midiprog.data[i].name); | ||||
} | } | ||||
#endif | #endif | ||||
@@ -835,7 +843,7 @@ public: | |||||
fluid_synth_program_reset(fSynth); | fluid_synth_program_reset(fSynth); | ||||
// select first program, or 128 for ch10 | // select first program, or 128 for ch10 | ||||
for (i=0; i < 16 && i != 9; i++) | |||||
for (i=0; i < 16 && i != 9; ++i) | |||||
{ | { | ||||
fluid_synth_program_select(fSynth, i, fSynthId, kData->midiprog.data[0].bank, kData->midiprog.data[0].program); | fluid_synth_program_select(fSynth, i, fSynthId, kData->midiprog.data[0].bank, kData->midiprog.data[0].program); | ||||
#ifdef FLUIDSYNTH_VERSION_NEW_API | #ifdef FLUIDSYNTH_VERSION_NEW_API | ||||
@@ -879,17 +887,18 @@ public: | |||||
if (! kData->active) | if (! kData->active) | ||||
{ | { | ||||
// disable any output sound | // disable any output sound | ||||
for (i=0; i < kData->audioOut.count; i++) | |||||
for (i=0; i < kData->audioOut.count; ++i) | |||||
carla_zeroFloat(outBuffer[i], frames); | carla_zeroFloat(outBuffer[i], frames); | ||||
return; | return; | ||||
} | } | ||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Check if not active before | |||||
// Check if needs reset | |||||
if (kData->needsReset /*|| ! kData->activeBefore*/) | |||||
if (kData->needsReset) | |||||
{ | { | ||||
// TODO | |||||
if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF) | if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF) | ||||
{ | { | ||||
for (int c=0; c < MAX_MIDI_CHANNELS; c++) | for (int c=0; c < MAX_MIDI_CHANNELS; c++) | ||||
@@ -903,6 +912,9 @@ public: | |||||
#endif | #endif | ||||
} | } | ||||
} | } | ||||
else | |||||
{ | |||||
} | |||||
kData->needsReset = false; | kData->needsReset = false; | ||||
} | } | ||||
@@ -910,7 +922,6 @@ public: | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Event Input and Processing | // Event Input and Processing | ||||
//if (kData->activeBefore) | |||||
{ | { | ||||
// ---------------------------------------------------------------------------------------------------- | // ---------------------------------------------------------------------------------------------------- | ||||
// MIDI Input (External) | // MIDI Input (External) | ||||
@@ -946,7 +957,7 @@ public: | |||||
if (kData->midiprog.current >= 0 && kData->midiprog.count > 0 && kData->ctrlChannel >= 0 && kData->ctrlChannel < 16) | if (kData->midiprog.current >= 0 && kData->midiprog.count > 0 && kData->ctrlChannel >= 0 && kData->ctrlChannel < 16) | ||||
nextBankIds[kData->ctrlChannel] = kData->midiprog.data[kData->midiprog.current].bank; | nextBankIds[kData->ctrlChannel] = kData->midiprog.data[kData->midiprog.current].bank; | ||||
for (i=0; i < nEvents; i++) | |||||
for (i=0; i < nEvents; ++i) | |||||
{ | { | ||||
const EngineEvent& event = kData->event.portIn->getEvent(i); | const EngineEvent& event = kData->event.portIn->getEvent(i); | ||||
@@ -1036,7 +1047,7 @@ public: | |||||
} | } | ||||
// Control plugin parameters | // Control plugin parameters | ||||
for (k=0; k < kData->param.count; k++) | |||||
for (k=0; k < kData->param.count; ++k) | |||||
{ | { | ||||
if (kData->param.data[k].midiChannel != event.channel) | if (kData->param.data[k].midiChannel != event.channel) | ||||
continue; | continue; | ||||
@@ -1079,7 +1090,7 @@ public: | |||||
const uint32_t bankId = nextBankIds[event.channel]; | const uint32_t bankId = nextBankIds[event.channel]; | ||||
const uint32_t progId = ctrlEvent.param; | const uint32_t progId = ctrlEvent.param; | ||||
for (k=0; k < kData->midiprog.count; k++) | |||||
for (k=0; k < kData->midiprog.count; ++k) | |||||
{ | { | ||||
if (kData->midiprog.data[k].bank == bankId && kData->midiprog.data[k].program == progId) | if (kData->midiprog.data[k].bank == bankId && kData->midiprog.data[k].program == progId) | ||||
{ | { | ||||
@@ -1102,8 +1113,8 @@ public: | |||||
{ | { | ||||
if (! allNotesOffSent) | if (! allNotesOffSent) | ||||
{ | { | ||||
allNotesOffSent = true; | |||||
sendMidiAllNotesOff(); | sendMidiAllNotesOff(); | ||||
allNotesOffSent = true; | |||||
} | } | ||||
postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 0.0f); | postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 0.0f); | ||||
@@ -1125,8 +1136,8 @@ public: | |||||
{ | { | ||||
if (! allNotesOffSent) | if (! allNotesOffSent) | ||||
{ | { | ||||
allNotesOffSent = true; | |||||
sendMidiAllNotesOff(); | sendMidiAllNotesOff(); | ||||
allNotesOffSent = true; | |||||
} | } | ||||
if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF) | if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF) | ||||
@@ -1252,9 +1263,9 @@ public: | |||||
} | } | ||||
else if (! kData->singleMutex.tryLock()) | else if (! kData->singleMutex.tryLock()) | ||||
{ | { | ||||
for (i=0; i < kData->audioOut.count; i++) | |||||
for (i=0; i < kData->audioOut.count; ++i) | |||||
{ | { | ||||
for (k=0; k < frames; k++) | |||||
for (k=0; k < frames; ++k) | |||||
outBuffer[i][k+timeOffset] = 0.0f; | outBuffer[i][k+timeOffset] = 0.0f; | ||||
} | } | ||||
@@ -1266,7 +1277,7 @@ public: | |||||
if (kUses16Outs) | if (kUses16Outs) | ||||
{ | { | ||||
for (i=0; i < kData->audioOut.count; i++) | |||||
for (i=0; i < kData->audioOut.count; ++i) | |||||
carla_zeroFloat(fAudio16Buffers[i], frames); | carla_zeroFloat(fAudio16Buffers[i], frames); | ||||
fluid_synth_process(fSynth, frames, 0, nullptr, kData->audioOut.count, fAudio16Buffers); | fluid_synth_process(fSynth, frames, 0, nullptr, kData->audioOut.count, fAudio16Buffers); | ||||
@@ -1284,7 +1295,7 @@ public: | |||||
float oldBufLeft[doBalance ? frames : 1]; | float oldBufLeft[doBalance ? frames : 1]; | ||||
for (i=0; i < kData->audioOut.count; i++) | |||||
for (i=0; i < kData->audioOut.count; ++i) | |||||
{ | { | ||||
// Balance | // Balance | ||||
if (doBalance) | if (doBalance) | ||||
@@ -1295,7 +1306,7 @@ public: | |||||
float balRangeL = (kData->postProc.balanceLeft + 1.0f)/2.0f; | float balRangeL = (kData->postProc.balanceLeft + 1.0f)/2.0f; | ||||
float balRangeR = (kData->postProc.balanceRight + 1.0f)/2.0f; | float balRangeR = (kData->postProc.balanceRight + 1.0f)/2.0f; | ||||
for (k=0; k < frames; k++) | |||||
for (k=0; k < frames; ++k) | |||||
{ | { | ||||
if (i % 2 == 0) | if (i % 2 == 0) | ||||
{ | { | ||||
@@ -1315,12 +1326,12 @@ public: | |||||
// Volume | // Volume | ||||
if (kUses16Outs) | if (kUses16Outs) | ||||
{ | { | ||||
for (k=0; k < frames; k++) | |||||
for (k=0; k < frames; ++k) | |||||
outBuffer[i][k+timeOffset] = fAudio16Buffers[i][k] * kData->postProc.volume; | outBuffer[i][k+timeOffset] = fAudio16Buffers[i][k] * kData->postProc.volume; | ||||
} | } | ||||
else if (doVolume) | else if (doVolume) | ||||
{ | { | ||||
for (k=0; k < frames; k++) | |||||
for (k=0; k < frames; ++k) | |||||
outBuffer[i][k+timeOffset] *= kData->postProc.volume; | outBuffer[i][k+timeOffset] *= kData->postProc.volume; | ||||
} | } | ||||
} | } | ||||
@@ -1338,7 +1349,7 @@ public: | |||||
if (! kUses16Outs) | if (! kUses16Outs) | ||||
return; | return; | ||||
for (uint32_t i=0; i < kData->audioOut.count; i++) | |||||
for (uint32_t i=0; i < kData->audioOut.count; ++i) | |||||
{ | { | ||||
if (fAudio16Buffers[i] != nullptr) | if (fAudio16Buffers[i] != nullptr) | ||||
delete[] fAudio16Buffers[i]; | delete[] fAudio16Buffers[i]; | ||||
@@ -1349,13 +1360,13 @@ public: | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
// Plugin buffers | // Plugin buffers | ||||
void deleteBuffers() | |||||
void clearBuffers() | |||||
{ | { | ||||
carla_debug("FluidSynthPlugin::deleteBuffers() - start"); | |||||
carla_debug("FluidSynthPlugin::clearBuffers() - start"); | |||||
if (fAudio16Buffers != nullptr) | if (fAudio16Buffers != nullptr) | ||||
{ | { | ||||
for (uint32_t i=0; i < kData->audioOut.count; i++) | |||||
for (uint32_t i=0; i < kData->audioOut.count; ++i) | |||||
{ | { | ||||
if (fAudio16Buffers[i] != nullptr) | if (fAudio16Buffers[i] != nullptr) | ||||
{ | { | ||||
@@ -1368,9 +1379,9 @@ public: | |||||
fAudio16Buffers = nullptr; | fAudio16Buffers = nullptr; | ||||
} | } | ||||
kData->clearBuffers(); | |||||
CarlaPlugin::clearBuffers(); | |||||
carla_debug("FluidSynthPlugin::deleteBuffers() - end"); | |||||
carla_debug("FluidSynthPlugin::clearBuffers() - end"); | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -1446,6 +1457,25 @@ public: | |||||
return false; | return false; | ||||
} | } | ||||
// --------------------------------------------------------------- | |||||
// load plugin settings | |||||
{ | |||||
// set default options | |||||
fOptions = 0x0; | |||||
fOptions |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES; | |||||
fOptions |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE; | |||||
fOptions |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH; | |||||
fOptions |= PLUGIN_OPTION_SEND_PITCHBEND; | |||||
fOptions |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF; | |||||
// load settings | |||||
kData->idStr = "SF2/"; | |||||
kData->idStr += label; | |||||
fOptions = kData->loadSettings(fOptions, availableOptions()); | |||||
} | |||||
return true; | return true; | ||||
} | } | ||||
@@ -1477,7 +1507,7 @@ private: | |||||
int fSynthId; | int fSynthId; | ||||
float** fAudio16Buffers; | float** fAudio16Buffers; | ||||
double fParamBuffers[FluidSynthParametersMax]; | |||||
float fParamBuffers[FluidSynthParametersMax]; | |||||
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(FluidSynthPlugin) | CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(FluidSynthPlugin) | ||||
}; | }; | ||||
@@ -1507,7 +1537,7 @@ CarlaPlugin* CarlaPlugin::newSF2(const Initializer& init, const bool use16Outs) | |||||
return nullptr; | return nullptr; | ||||
} | } | ||||
FluidSynthPlugin* const plugin = new FluidSynthPlugin(init.engine, init.id, use16Outs); | |||||
FluidSynthPlugin* const plugin(new FluidSynthPlugin(init.engine, init.id, use16Outs)); | |||||
if (! plugin->init(init.filename, init.name, init.label)) | if (! plugin->init(init.filename, init.name, init.label)) | ||||
{ | { | ||||
@@ -1481,7 +1481,7 @@ CarlaPlugin* CarlaPlugin::newLADSPA(const Initializer& init, const LADSPA_RDF_De | |||||
carla_debug("CarlaPlugin::newLADSPA({%p, \"%s\", \"%s\", \"%s\"}, %p)", init.engine, init.filename, init.name, init.label, rdfDescriptor); | carla_debug("CarlaPlugin::newLADSPA({%p, \"%s\", \"%s\", \"%s\"}, %p)", init.engine, init.filename, init.name, init.label, rdfDescriptor); | ||||
#ifdef WANT_LADSPA | #ifdef WANT_LADSPA | ||||
LadspaPlugin* const plugin = new LadspaPlugin(init.engine, init.id); | |||||
LadspaPlugin* const plugin(new LadspaPlugin(init.engine, init.id)); | |||||
if (! plugin->init(init.filename, init.name, init.label, rdfDescriptor)) | if (! plugin->init(init.filename, init.name, init.label, rdfDescriptor)) | ||||
{ | { | ||||
@@ -159,6 +159,10 @@ public: | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
#if 0 | |||||
} | |||||
#endif | |||||
class LinuxSamplerPlugin : public CarlaPlugin | class LinuxSamplerPlugin : public CarlaPlugin | ||||
{ | { | ||||
public: | public: | ||||
@@ -311,10 +315,13 @@ public: | |||||
// Safely disable plugin for reload | // Safely disable plugin for reload | ||||
const ScopedDisabler sd(this); | const ScopedDisabler sd(this); | ||||
kData->clearBuffers(); | |||||
if (kData->active) | |||||
deactivate(); | |||||
clearBuffers(); | |||||
uint32_t aOuts; | uint32_t aOuts; | ||||
aOuts = 2; | |||||
aOuts = 2; | |||||
kData->audioOut.createNew(aOuts); | kData->audioOut.createNew(aOuts); | ||||
@@ -385,18 +392,15 @@ public: | |||||
// extra plugin hints | // extra plugin hints | ||||
kData->extraHints = 0x0; | kData->extraHints = 0x0; | ||||
kData->extraHints |= PLUGIN_HINT_HAS_MIDI_IN; | |||||
kData->extraHints |= PLUGIN_HINT_CAN_RUN_RACK; | kData->extraHints |= PLUGIN_HINT_CAN_RUN_RACK; | ||||
// plugin options | |||||
fOptions = 0x0; | |||||
fOptions |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES; | |||||
fOptions |= PLUGIN_OPTION_SEND_CONTROL_CHANGES; | |||||
fOptions |= PLUGIN_OPTION_SEND_PITCHBEND; | |||||
fOptions |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF; | |||||
bufferSizeChanged(kData->engine->getBufferSize()); | bufferSizeChanged(kData->engine->getBufferSize()); | ||||
reloadPrograms(true); | reloadPrograms(true); | ||||
if (kData->active) | |||||
activate(); | |||||
carla_debug("LinuxSamplerPlugin::reload() - end"); | carla_debug("LinuxSamplerPlugin::reload() - end"); | ||||
} | } | ||||
@@ -419,7 +423,7 @@ public: | |||||
kData->midiprog.createNew(count); | kData->midiprog.createNew(count); | ||||
// Update data | // Update data | ||||
for (i=0; i < kData->midiprog.count; i++) | |||||
for (i=0; i < kData->midiprog.count; ++i) | |||||
{ | { | ||||
LinuxSampler::InstrumentManager::instrument_info_t info = fInstrument->GetInstrumentInfo(fInstrumentIds[i]); | LinuxSampler::InstrumentManager::instrument_info_t info = fInstrument->GetInstrumentInfo(fInstrumentIds[i]); | ||||
@@ -434,7 +438,7 @@ public: | |||||
{ | { | ||||
kData->engine->osc_send_control_set_midi_program_count(fId, count); | kData->engine->osc_send_control_set_midi_program_count(fId, count); | ||||
for (i=0; i < count; i++) | |||||
for (i=0; i < count; ++i) | |||||
kData->engine->osc_send_control_set_midi_program_data(fId, i, kData->midiprog.data[i].bank, kData->midiprog.data[i].program, kData->midiprog.data[i].name); | kData->engine->osc_send_control_set_midi_program_data(fId, i, kData->midiprog.data[i].bank, kData->midiprog.data[i].program, kData->midiprog.data[i].name); | ||||
} | } | ||||
#endif | #endif | ||||
@@ -452,6 +456,20 @@ public: | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
// Plugin processing | // Plugin processing | ||||
void activate() | |||||
{ | |||||
CARLA_ASSERT(fAudioOutputDevice != nullptr); | |||||
fAudioOutputDevice->Play(); | |||||
} | |||||
void deactivate() | |||||
{ | |||||
CARLA_ASSERT(fAudioOutputDevice != nullptr); | |||||
fAudioOutputDevice->Stop(); | |||||
} | |||||
void process(float** const, float** const outBuffer, const uint32_t frames) | void process(float** const, float** const outBuffer, const uint32_t frames) | ||||
{ | { | ||||
uint32_t i, k; | uint32_t i, k; | ||||
@@ -462,32 +480,29 @@ public: | |||||
if (! kData->active) | if (! kData->active) | ||||
{ | { | ||||
// disable any output sound | // disable any output sound | ||||
for (i=0; i < kData->audioOut.count; i++) | |||||
for (i=0; i < kData->audioOut.count; ++i) | |||||
carla_zeroFloat(outBuffer[i], frames); | carla_zeroFloat(outBuffer[i], frames); | ||||
//if (kData->activeBefore) | |||||
// fAudioOutputDevice->Stop(); | |||||
return; | return; | ||||
} | } | ||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Check if not active before | |||||
// Check if needs reset | |||||
if (kData->needsReset /*|| ! kData->activeBefore*/) | |||||
if (kData->needsReset) | |||||
{ | { | ||||
// TODO | |||||
if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF) | if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF) | ||||
{ | { | ||||
for (k=0, i=MAX_MIDI_CHANNELS; k < MAX_MIDI_CHANNELS; k++) | |||||
for (k=0, i=MAX_MIDI_CHANNELS; k < MAX_MIDI_CHANNELS; ++k) | |||||
{ | { | ||||
fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_SOUND_OFF, 0, k, 0); | fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_SOUND_OFF, 0, k, 0); | ||||
fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_NOTES_OFF, 0, k, 0); | fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_NOTES_OFF, 0, k, 0); | ||||
} | } | ||||
} | } | ||||
//if (kData->activeBefore) | |||||
// fAudioOutputDevice->Stop(); | |||||
//fAudioOutputDevice->Play(); | |||||
else | |||||
{ | |||||
} | |||||
kData->needsReset = false; | kData->needsReset = false; | ||||
} | } | ||||
@@ -495,7 +510,6 @@ public: | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Event Input and Processing | // Event Input and Processing | ||||
if (kData->event.portIn != nullptr /*&& kData->activeBefore*/) | |||||
{ | { | ||||
// ---------------------------------------------------------------------------------------------------- | // ---------------------------------------------------------------------------------------------------- | ||||
// MIDI Input (External) | // MIDI Input (External) | ||||
@@ -532,7 +546,7 @@ public: | |||||
if (kData->midiprog.current >= 0 && kData->midiprog.count > 0) | if (kData->midiprog.current >= 0 && kData->midiprog.count > 0) | ||||
nextBankId = kData->midiprog.data[kData->midiprog.current].bank; | nextBankId = kData->midiprog.data[kData->midiprog.current].bank; | ||||
for (i=0; i < nEvents; i++) | |||||
for (i=0; i < nEvents; ++i) | |||||
{ | { | ||||
const EngineEvent& event = kData->event.portIn->getEvent(i); | const EngineEvent& event = kData->event.portIn->getEvent(i); | ||||
@@ -627,7 +641,7 @@ public: | |||||
} | } | ||||
// Control plugin parameters | // Control plugin parameters | ||||
for (k=0; k < kData->param.count; k++) | |||||
for (k=0; k < kData->param.count; ++k) | |||||
{ | { | ||||
if (kData->param.data[k].midiChannel != event.channel) | if (kData->param.data[k].midiChannel != event.channel) | ||||
continue; | continue; | ||||
@@ -669,7 +683,7 @@ public: | |||||
{ | { | ||||
const uint32_t nextProgramId = ctrlEvent.param; | const uint32_t nextProgramId = ctrlEvent.param; | ||||
for (k=0; k < kData->midiprog.count; k++) | |||||
for (k=0; k < kData->midiprog.count; ++k) | |||||
{ | { | ||||
if (kData->midiprog.data[k].bank == nextBankId && kData->midiprog.data[k].program == nextProgramId) | if (kData->midiprog.data[k].bank == nextBankId && kData->midiprog.data[k].program == nextProgramId) | ||||
{ | { | ||||
@@ -686,13 +700,10 @@ public: | |||||
{ | { | ||||
if (! allNotesOffSent) | if (! allNotesOffSent) | ||||
{ | { | ||||
allNotesOffSent = true; | |||||
sendMidiAllNotesOff(); | sendMidiAllNotesOff(); | ||||
allNotesOffSent = true; | |||||
} | } | ||||
fAudioOutputDevice->Stop(); | |||||
fAudioOutputDevice->Play(); | |||||
postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 0.0f); | postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 0.0f); | ||||
postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 1.0f); | postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 1.0f); | ||||
} | } | ||||
@@ -707,8 +718,8 @@ public: | |||||
{ | { | ||||
if (! allNotesOffSent) | if (! allNotesOffSent) | ||||
{ | { | ||||
allNotesOffSent = true; | |||||
sendMidiAllNotesOff(); | sendMidiAllNotesOff(); | ||||
allNotesOffSent = true; | |||||
} | } | ||||
} | } | ||||
@@ -790,15 +801,6 @@ public: | |||||
processSingle(outBuffer, frames - timeOffset, timeOffset); | processSingle(outBuffer, frames - timeOffset, timeOffset); | ||||
} // End of Event Input and Processing | } // End of Event Input and Processing | ||||
// -------------------------------------------------------------------------------------------------------- | |||||
// Plugin processing (no events) | |||||
else | |||||
{ | |||||
processSingle(outBuffer, frames, 0); | |||||
} // End of Plugin processing (no events) | |||||
} | } | ||||
bool processSingle(float** const outBuffer, const uint32_t frames, const uint32_t timeOffset) | bool processSingle(float** const outBuffer, const uint32_t frames, const uint32_t timeOffset) | ||||
@@ -822,9 +824,9 @@ public: | |||||
} | } | ||||
else if (! kData->singleMutex.tryLock()) | else if (! kData->singleMutex.tryLock()) | ||||
{ | { | ||||
for (i=0; i < kData->audioOut.count; i++) | |||||
for (i=0; i < kData->audioOut.count; ++i) | |||||
{ | { | ||||
for (k=0; k < frames; k++) | |||||
for (k=0; k < frames; ++k) | |||||
outBuffer[i][k+timeOffset] = 0.0f; | outBuffer[i][k+timeOffset] = 0.0f; | ||||
} | } | ||||
@@ -848,7 +850,7 @@ public: | |||||
float oldBufLeft[doBalance ? frames : 1]; | float oldBufLeft[doBalance ? frames : 1]; | ||||
for (i=0; i < kData->audioOut.count; i++) | |||||
for (i=0; i < kData->audioOut.count; ++i) | |||||
{ | { | ||||
// Balance | // Balance | ||||
if (doBalance) | if (doBalance) | ||||
@@ -859,7 +861,7 @@ public: | |||||
float balRangeL = (kData->postProc.balanceLeft + 1.0f)/2.0f; | float balRangeL = (kData->postProc.balanceLeft + 1.0f)/2.0f; | ||||
float balRangeR = (kData->postProc.balanceRight + 1.0f)/2.0f; | float balRangeR = (kData->postProc.balanceRight + 1.0f)/2.0f; | ||||
for (k=0; k < frames; k++) | |||||
for (k=0; k < frames; ++k) | |||||
{ | { | ||||
if (i % 2 == 0) | if (i % 2 == 0) | ||||
{ | { | ||||
@@ -879,7 +881,7 @@ public: | |||||
// Volume | // Volume | ||||
if (doVolume) | if (doVolume) | ||||
{ | { | ||||
for (k=0; k < frames; k++) | |||||
for (k=0; k < frames; ++k) | |||||
outBuffer[i][k+timeOffset] *= kData->postProc.volume; | outBuffer[i][k+timeOffset] *= kData->postProc.volume; | ||||
} | } | ||||
} | } | ||||
@@ -941,6 +943,7 @@ public: | |||||
// --------------------------------------------------------------- | // --------------------------------------------------------------- | ||||
// Create the LinuxSampler Engine | // Create the LinuxSampler Engine | ||||
const char* const stype = kIsGIG ? "gig" : "sfz"; | const char* const stype = kIsGIG ? "gig" : "sfz"; | ||||
try { | try { | ||||
@@ -955,12 +958,11 @@ public: | |||||
// --------------------------------------------------------------- | // --------------------------------------------------------------- | ||||
// Get the Engine's Instrument Manager | // Get the Engine's Instrument Manager | ||||
try { | |||||
fInstrument = fEngine->GetInstrumentManager(); | |||||
} | |||||
catch (LinuxSampler::Exception& e) | |||||
fInstrument = fEngine->GetInstrumentManager(); | |||||
if (fInstrument == nullptr) | |||||
{ | { | ||||
kData->engine->setLastError(e.what()); | |||||
kData->engine->setLastError("Failed to get LinuxSampler instrument manager"); | |||||
LinuxSampler::EngineFactory::Destroy(fEngine); | LinuxSampler::EngineFactory::Destroy(fEngine); | ||||
return false; | return false; | ||||
} | } | ||||
@@ -971,7 +973,7 @@ public: | |||||
try { | try { | ||||
fInstrumentIds = fInstrument->GetInstrumentFileContent(filename); | fInstrumentIds = fInstrument->GetInstrumentFileContent(filename); | ||||
} | } | ||||
catch (LinuxSampler::Exception& e) | |||||
catch (const LinuxSampler::InstrumentManagerException& e) | |||||
{ | { | ||||
kData->engine->setLastError(e.what()); | kData->engine->setLastError(e.what()); | ||||
LinuxSampler::EngineFactory::Destroy(fEngine); | LinuxSampler::EngineFactory::Destroy(fEngine); | ||||
@@ -987,20 +989,28 @@ public: | |||||
LinuxSampler::EngineFactory::Destroy(fEngine); | LinuxSampler::EngineFactory::Destroy(fEngine); | ||||
return false; | return false; | ||||
} | } | ||||
else | |||||
{ | |||||
LinuxSampler::InstrumentManager::instrument_info_t info = fInstrument->GetInstrumentInfo(fInstrumentIds[0]); | |||||
fRealName = info.InstrumentName.c_str(); | |||||
fLabel = info.Product.c_str(); | |||||
fMaker = info.Artists.c_str(); | |||||
fFilename = filename; | |||||
LinuxSampler::InstrumentManager::instrument_info_t info; | |||||
if (name != nullptr) | |||||
fName = kData->engine->getNewUniquePluginName(name); | |||||
else | |||||
fName = kData->engine->getNewUniquePluginName((const char*)fRealName); | |||||
try { | |||||
info = fInstrument->GetInstrumentInfo(fInstrumentIds[0]); | |||||
} | } | ||||
catch (const LinuxSampler::InstrumentManagerException& e) | |||||
{ | |||||
kData->engine->setLastError(e.what()); | |||||
LinuxSampler::EngineFactory::Destroy(fEngine); | |||||
return false; | |||||
} | |||||
fRealName = info.InstrumentName.c_str(); | |||||
fLabel = info.Product.c_str(); | |||||
fMaker = info.Artists.c_str(); | |||||
fFilename = filename; | |||||
if (name != nullptr) | |||||
fName = kData->engine->getNewUniquePluginName(name); | |||||
else | |||||
fName = kData->engine->getNewUniquePluginName((const char*)fRealName); | |||||
// --------------------------------------------------------------- | // --------------------------------------------------------------- | ||||
// Register client | // Register client | ||||
@@ -1029,6 +1039,24 @@ public: | |||||
fMidiInputPort->Connect(fSamplerChannel->GetEngineChannel(), LinuxSampler::midi_chan_all); | fMidiInputPort->Connect(fSamplerChannel->GetEngineChannel(), LinuxSampler::midi_chan_all); | ||||
// --------------------------------------------------------------- | |||||
// load plugin settings | |||||
{ | |||||
// set default options | |||||
fOptions = 0x0; | |||||
fOptions |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES; | |||||
fOptions |= PLUGIN_OPTION_SEND_PITCHBEND; | |||||
fOptions |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF; | |||||
// load settings | |||||
kData->idStr = kIsGIG ? "GIG" : "SFZ"; | |||||
kData->idStr += "/"; | |||||
kData->idStr += label; | |||||
fOptions = kData->loadSettings(fOptions, availableOptions()); | |||||
} | |||||
return true; | return true; | ||||
} | } | ||||
@@ -1037,7 +1065,7 @@ public: | |||||
static CarlaPlugin* newLinuxSampler(const Initializer& init, bool isGIG, const bool use16Outs); | static CarlaPlugin* newLinuxSampler(const Initializer& init, bool isGIG, const bool use16Outs); | ||||
private: | private: | ||||
const bool kIsGIG; | |||||
const bool kIsGIG; // sfz if false | |||||
const bool kUses16Outs; | const bool kUses16Outs; | ||||
CarlaString fRealName; | CarlaString fRealName; | ||||
@@ -1064,7 +1092,7 @@ CarlaPlugin* LinuxSamplerPlugin::newLinuxSampler(const Initializer& init, const | |||||
{ | { | ||||
carla_debug("LinuxSamplerPlugin::newLinuxSampler({%p, \"%s\", \"%s\", \"%s\"}, %s, %s)", init.engine, init.filename, init.name, init.label, bool2str(isGIG), bool2str(use16Outs)); | carla_debug("LinuxSamplerPlugin::newLinuxSampler({%p, \"%s\", \"%s\", \"%s\"}, %s, %s)", init.engine, init.filename, init.name, init.label, bool2str(isGIG), bool2str(use16Outs)); | ||||
LinuxSamplerPlugin* const plugin = new LinuxSamplerPlugin(init.engine, init.id, isGIG, use16Outs); | |||||
LinuxSamplerPlugin* const plugin(new LinuxSamplerPlugin(init.engine, init.id, isGIG, use16Outs)); | |||||
if (! plugin->init(init.filename, init.name, init.label)) | if (! plugin->init(init.filename, init.name, init.label)) | ||||
{ | { | ||||
@@ -2229,7 +2229,7 @@ CarlaPlugin* CarlaPlugin::newNative(const Initializer& init) | |||||
carla_debug("CarlaPlugin::newNative({%p, \"%s\", \"%s\", \"%s\"})", init.engine, init.filename, init.name, init.label); | carla_debug("CarlaPlugin::newNative({%p, \"%s\", \"%s\", \"%s\"})", init.engine, init.filename, init.name, init.label); | ||||
#ifdef WANT_NATIVE | #ifdef WANT_NATIVE | ||||
NativePlugin* const plugin = new NativePlugin(init.engine, init.id); | |||||
NativePlugin* const plugin(new NativePlugin(init.engine, init.id)); | |||||
if (! plugin->init(init.name, init.label)) | if (! plugin->init(init.name, init.label)) | ||||
{ | { | ||||
@@ -2453,7 +2453,7 @@ CarlaPlugin* CarlaPlugin::newVST(const Initializer& init) | |||||
carla_debug("CarlaPlugin::newVST({%p, \"%s\", \"%s\"})", init.engine, init.filename, init.name); | carla_debug("CarlaPlugin::newVST({%p, \"%s\", \"%s\"})", init.engine, init.filename, init.name); | ||||
#ifdef WANT_VST | #ifdef WANT_VST | ||||
VstPlugin* const plugin = new VstPlugin(init.engine, init.id); | |||||
VstPlugin* const plugin(new VstPlugin(init.engine, init.id)); | |||||
if (! plugin->init(init.filename, init.name)) | if (! plugin->init(init.filename, init.name)) | ||||
{ | { | ||||
@@ -874,21 +874,21 @@ class CarlaAboutW(QDialog): | |||||
self.ui.l_extended.setText(cString(Carla.host.get_extended_license_text())) | self.ui.l_extended.setText(cString(Carla.host.get_extended_license_text())) | ||||
self.ui.le_osc_url.setText(cString(Carla.host.get_host_osc_url()) if Carla.host.is_engine_running() else self.tr("(Engine not running)")) | self.ui.le_osc_url.setText(cString(Carla.host.get_host_osc_url()) if Carla.host.is_engine_running() else self.tr("(Engine not running)")) | ||||
self.ui.l_osc_cmds.setText( | |||||
" /set_active <i-value>\n" | |||||
" /set_drywet <f-value>\n" | |||||
" /set_volume <f-value>\n" | |||||
" /set_balance_left <f-value>\n" | |||||
" /set_balance_right <f-value>\n" | |||||
" /set_panning <f-value>\n" | |||||
" /set_parameter_value <i-index> <f-value>\n" | |||||
" /set_parameter_midi_cc <i-index> <i-cc>\n" | |||||
" /set_parameter_midi_channel <i-index> <i-channel>\n" | |||||
" /set_program <i-index>\n" | |||||
" /set_midi_program <i-index>\n" | |||||
" /note_on <i-note> <i-velo>\n" | |||||
" /note_off <i-note>\n" | |||||
) | |||||
self.ui.l_osc_cmds.setText("" | |||||
" /set_active <i-value>\n" | |||||
" /set_drywet <f-value>\n" | |||||
" /set_volume <f-value>\n" | |||||
" /set_balance_left <f-value>\n" | |||||
" /set_balance_right <f-value>\n" | |||||
" /set_panning <f-value>\n" | |||||
" /set_parameter_value <i-index> <f-value>\n" | |||||
" /set_parameter_midi_cc <i-index> <i-cc>\n" | |||||
" /set_parameter_midi_channel <i-index> <i-channel>\n" | |||||
" /set_program <i-index>\n" | |||||
" /set_midi_program <i-index>\n" | |||||
" /note_on <i-note> <i-velo>\n" | |||||
" /note_off <i-note>\n" | |||||
) | |||||
self.ui.l_example.setText("/Carla/2/set_parameter_value 5 1.0") | self.ui.l_example.setText("/Carla/2/set_parameter_value 5 1.0") | ||||
self.ui.l_example_help.setText("<i>(as in this example, \"2\" is the plugin number and \"5\" the parameter)</i>") | self.ui.l_example_help.setText("<i>(as in this example, \"2\" is the plugin number and \"5\" the parameter)</i>") | ||||
@@ -896,35 +896,35 @@ class CarlaAboutW(QDialog): | |||||
self.ui.l_ladspa.setText(self.tr("Everything! (Including LRDF)")) | self.ui.l_ladspa.setText(self.tr("Everything! (Including LRDF)")) | ||||
self.ui.l_dssi.setText(self.tr("Everything! (Including CustomData/Chunks)")) | self.ui.l_dssi.setText(self.tr("Everything! (Including CustomData/Chunks)")) | ||||
self.ui.l_lv2.setText(self.tr("About 95% complete (using custom extensions).<br/>" | self.ui.l_lv2.setText(self.tr("About 95% complete (using custom extensions).<br/>" | ||||
"Implemented Feature/Extensions:" | |||||
"<ul>" | |||||
"<li>http://lv2plug.in/ns/ext/atom</li>" | |||||
"<li>http://lv2plug.in/ns/ext/buf-size</li>" | |||||
"<li>http://lv2plug.in/ns/ext/data-access</li>" | |||||
#"<li>http://lv2plug.in/ns/ext/dynmanifest</li>" | |||||
"<li>http://lv2plug.in/ns/ext/event</li>" | |||||
"<li>http://lv2plug.in/ns/ext/instance-access</li>" | |||||
"<li>http://lv2plug.in/ns/ext/log</li>" | |||||
"<li>http://lv2plug.in/ns/ext/midi</li>" | |||||
"<li>http://lv2plug.in/ns/ext/options</li>" | |||||
#"<li>http://lv2plug.in/ns/ext/parameters</li>" | |||||
"<li>http://lv2plug.in/ns/ext/patch</li>" | |||||
#"<li>http://lv2plug.in/ns/ext/port-groups</li>" | |||||
"<li>http://lv2plug.in/ns/ext/port-props</li>" | |||||
#"<li>http://lv2plug.in/ns/ext/presets</li>" | |||||
"<li>http://lv2plug.in/ns/ext/state</li>" | |||||
"<li>http://lv2plug.in/ns/ext/time</li>" | |||||
"<li>http://lv2plug.in/ns/ext/uri-map</li>" | |||||
"<li>http://lv2plug.in/ns/ext/urid</li>" | |||||
"<li>http://lv2plug.in/ns/ext/worker</li>" | |||||
"<li>http://lv2plug.in/ns/extensions/ui</li>" | |||||
"<li>http://lv2plug.in/ns/extensions/units</li>" | |||||
"<li>http://kxstudio.sf.net/ns/lv2ext/external-ui</li>" | |||||
"<li>http://kxstudio.sf.net/ns/lv2ext/programs</li>" | |||||
"<li>http://kxstudio.sf.net/ns/lv2ext/rtmempool</li>" | |||||
"<li>http://ll-plugins.nongnu.org/lv2/ext/midimap</li>" | |||||
"<li>http://ll-plugins.nongnu.org/lv2/ext/miditype</li>" | |||||
"</ul>")) | |||||
"Implemented Feature/Extensions:" | |||||
"<ul>" | |||||
"<li>http://lv2plug.in/ns/ext/atom</li>" | |||||
"<li>http://lv2plug.in/ns/ext/buf-size</li>" | |||||
"<li>http://lv2plug.in/ns/ext/data-access</li>" | |||||
#"<li>http://lv2plug.in/ns/ext/dynmanifest</li>" | |||||
"<li>http://lv2plug.in/ns/ext/event</li>" | |||||
"<li>http://lv2plug.in/ns/ext/instance-access</li>" | |||||
"<li>http://lv2plug.in/ns/ext/log</li>" | |||||
"<li>http://lv2plug.in/ns/ext/midi</li>" | |||||
"<li>http://lv2plug.in/ns/ext/options</li>" | |||||
#"<li>http://lv2plug.in/ns/ext/parameters</li>" | |||||
"<li>http://lv2plug.in/ns/ext/patch</li>" | |||||
#"<li>http://lv2plug.in/ns/ext/port-groups</li>" | |||||
"<li>http://lv2plug.in/ns/ext/port-props</li>" | |||||
#"<li>http://lv2plug.in/ns/ext/presets</li>" | |||||
"<li>http://lv2plug.in/ns/ext/state</li>" | |||||
"<li>http://lv2plug.in/ns/ext/time</li>" | |||||
"<li>http://lv2plug.in/ns/ext/uri-map</li>" | |||||
"<li>http://lv2plug.in/ns/ext/urid</li>" | |||||
"<li>http://lv2plug.in/ns/ext/worker</li>" | |||||
"<li>http://lv2plug.in/ns/extensions/ui</li>" | |||||
"<li>http://lv2plug.in/ns/extensions/units</li>" | |||||
"<li>http://kxstudio.sf.net/ns/lv2ext/external-ui</li>" | |||||
"<li>http://kxstudio.sf.net/ns/lv2ext/programs</li>" | |||||
"<li>http://kxstudio.sf.net/ns/lv2ext/rtmempool</li>" | |||||
"<li>http://ll-plugins.nongnu.org/lv2/ext/midimap</li>" | |||||
"<li>http://ll-plugins.nongnu.org/lv2/ext/miditype</li>" | |||||
"</ul>")) | |||||
self.ui.l_vst.setText(self.tr("<p>About 85% complete (missing vst bank/presets and some minor stuff)</p>")) | self.ui.l_vst.setText(self.tr("<p>About 85% complete (missing vst bank/presets and some minor stuff)</p>")) | ||||
#TODO | #TODO | ||||