diff --git a/source/backend/plugin/FluidSynthPlugin.cpp b/source/backend/plugin/FluidSynthPlugin.cpp index 2e5df3930..8a8c0afcc 100644 --- a/source/backend/plugin/FluidSynthPlugin.cpp +++ b/source/backend/plugin/FluidSynthPlugin.cpp @@ -46,7 +46,7 @@ public: fUses16Outs(use16Outs), fSettings(nullptr), fSynth(nullptr), - fSynthId(-1), + fSynthId(0), fAudio16Buffers(nullptr), fLabel(nullptr) { @@ -471,15 +471,15 @@ public: if (midiProgramList.count() == MAX_MIDI_CHANNELS) { - uint i = 0; + int i = 0; foreach (const QString& midiProg, midiProgramList) { CARLA_SAFE_ASSERT_BREAK(i < MAX_MIDI_CHANNELS); bool ok; - uint index = midiProg.toUInt(&ok); + int index = midiProg.toInt(&ok); - if (ok && index < pData->midiprog.count) + if (ok && index >= 0 && index < static_cast(pData->midiprog.count)) { const uint32_t bank = pData->midiprog.data[index].bank; const uint32_t program = pData->midiprog.data[index].program; @@ -557,7 +557,7 @@ public: pData->audioOut.createNew(aOuts); pData->param.createNew(params, false); - const int portNameSize(pData->engine->getMaxPortNameSize()); + const uint portNameSize(pData->engine->getMaxPortNameSize()); CarlaString portName; // --------------------------------------- @@ -565,7 +565,7 @@ public: if (fUses16Outs) { - for (int i=0; i < 32; ++i) + for (uint32_t i=0; i < 32; ++i) { portName.clear(); @@ -679,14 +679,15 @@ public: pData->param.data[j].hints = PARAMETER_IS_ENABLED /*| PARAMETER_IS_AUTOMABLE*/ | PARAMETER_IS_BOOLEAN; pData->param.data[j].index = j; pData->param.data[j].rindex = j; - pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; + pData->param.data[j].midiChannel = 0; pData->param.ranges[j].min = 0.0f; pData->param.ranges[j].max = 1.0f; pData->param.ranges[j].def = 1.0f; pData->param.ranges[j].step = 1.0f; pData->param.ranges[j].stepSmall = 1.0f; pData->param.ranges[j].stepLarge = 1.0f; + pData->param.special[j] = PARAMETER_SPECIAL_NULL; fParamBuffers[j] = pData->param.ranges[j].def; // ---------------------- @@ -695,14 +696,15 @@ public: pData->param.data[j].hints = PARAMETER_IS_ENABLED /*| PARAMETER_IS_AUTOMABLE*/; pData->param.data[j].index = j; pData->param.data[j].rindex = j; - pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; + pData->param.data[j].midiChannel = 0; pData->param.ranges[j].min = 0.0f; pData->param.ranges[j].max = 1.2f; pData->param.ranges[j].def = FLUID_REVERB_DEFAULT_ROOMSIZE; pData->param.ranges[j].step = 0.01f; pData->param.ranges[j].stepSmall = 0.0001f; pData->param.ranges[j].stepLarge = 0.1f; + pData->param.special[j] = PARAMETER_SPECIAL_NULL; fParamBuffers[j] = pData->param.ranges[j].def; // ---------------------- @@ -711,14 +713,15 @@ public: pData->param.data[j].hints = PARAMETER_IS_ENABLED /*| PARAMETER_IS_AUTOMABLE*/; pData->param.data[j].index = j; pData->param.data[j].rindex = j; - pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; + pData->param.data[j].midiChannel = 0; pData->param.ranges[j].min = 0.0f; pData->param.ranges[j].max = 1.0f; pData->param.ranges[j].def = FLUID_REVERB_DEFAULT_DAMP; pData->param.ranges[j].step = 0.01f; pData->param.ranges[j].stepSmall = 0.0001f; pData->param.ranges[j].stepLarge = 0.1f; + pData->param.special[j] = PARAMETER_SPECIAL_NULL; fParamBuffers[j] = pData->param.ranges[j].def; // ---------------------- @@ -727,14 +730,15 @@ public: pData->param.data[j].hints = PARAMETER_IS_ENABLED /*| PARAMETER_IS_AUTOMABLE*/; pData->param.data[j].index = j; pData->param.data[j].rindex = j; - pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = MIDI_CONTROL_REVERB_SEND_LEVEL; + pData->param.data[j].midiChannel = 0; pData->param.ranges[j].min = 0.0f; pData->param.ranges[j].max = 1.0f; pData->param.ranges[j].def = FLUID_REVERB_DEFAULT_LEVEL; pData->param.ranges[j].step = 0.01f; pData->param.ranges[j].stepSmall = 0.0001f; pData->param.ranges[j].stepLarge = 0.1f; + pData->param.special[j] = PARAMETER_SPECIAL_NULL; fParamBuffers[j] = pData->param.ranges[j].def; // ---------------------- @@ -743,14 +747,15 @@ public: pData->param.data[j].hints = PARAMETER_IS_ENABLED /*| PARAMETER_IS_AUTOMABLE*/; pData->param.data[j].index = j; pData->param.data[j].rindex = j; - pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; + pData->param.data[j].midiChannel = 0; pData->param.ranges[j].min = 0.0f; pData->param.ranges[j].max = 10.0f; // should be 100, but that sounds too much pData->param.ranges[j].def = FLUID_REVERB_DEFAULT_WIDTH; pData->param.ranges[j].step = 0.01f; pData->param.ranges[j].stepSmall = 0.0001f; pData->param.ranges[j].stepLarge = 0.1f; + pData->param.special[j] = PARAMETER_SPECIAL_NULL; fParamBuffers[j] = pData->param.ranges[j].def; // ---------------------- @@ -759,14 +764,15 @@ public: pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_BOOLEAN; pData->param.data[j].index = j; pData->param.data[j].rindex = j; - pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; + pData->param.data[j].midiChannel = 0; pData->param.ranges[j].min = 0.0f; pData->param.ranges[j].max = 1.0f; pData->param.ranges[j].def = 1.0f; pData->param.ranges[j].step = 1.0f; pData->param.ranges[j].stepSmall = 1.0f; pData->param.ranges[j].stepLarge = 1.0f; + pData->param.special[j] = PARAMETER_SPECIAL_NULL; fParamBuffers[j] = pData->param.ranges[j].def; // ---------------------- @@ -775,14 +781,15 @@ public: pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_INTEGER; pData->param.data[j].index = j; pData->param.data[j].rindex = j; - pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; + pData->param.data[j].midiChannel = 0; pData->param.ranges[j].min = 0.0f; pData->param.ranges[j].max = 99.0f; pData->param.ranges[j].def = FLUID_CHORUS_DEFAULT_N; pData->param.ranges[j].step = 1.0f; pData->param.ranges[j].stepSmall = 1.0f; pData->param.ranges[j].stepLarge = 10.0f; + pData->param.special[j] = PARAMETER_SPECIAL_NULL; fParamBuffers[j] = pData->param.ranges[j].def; // ---------------------- @@ -791,14 +798,15 @@ public: pData->param.data[j].hints = PARAMETER_IS_ENABLED; pData->param.data[j].index = j; pData->param.data[j].rindex = j; - pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = 0; //MIDI_CONTROL_CHORUS_SEND_LEVEL; + pData->param.data[j].midiChannel = 0; pData->param.ranges[j].min = 0.0f; pData->param.ranges[j].max = 10.0f; pData->param.ranges[j].def = FLUID_CHORUS_DEFAULT_LEVEL; pData->param.ranges[j].step = 0.01f; pData->param.ranges[j].stepSmall = 0.0001f; pData->param.ranges[j].stepLarge = 0.1f; + pData->param.special[j] = PARAMETER_SPECIAL_NULL; fParamBuffers[j] = pData->param.ranges[j].def; // ---------------------- @@ -807,14 +815,15 @@ public: pData->param.data[j].hints = PARAMETER_IS_ENABLED; pData->param.data[j].index = j; pData->param.data[j].rindex = j; - pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; + pData->param.data[j].midiChannel = 0; pData->param.ranges[j].min = 0.29f; pData->param.ranges[j].max = 5.0f; pData->param.ranges[j].def = FLUID_CHORUS_DEFAULT_SPEED; pData->param.ranges[j].step = 0.01f; pData->param.ranges[j].stepSmall = 0.0001f; pData->param.ranges[j].stepLarge = 0.1f; + pData->param.special[j] = PARAMETER_SPECIAL_NULL; fParamBuffers[j] = pData->param.ranges[j].def; // ---------------------- @@ -823,14 +832,15 @@ public: pData->param.data[j].hints = PARAMETER_IS_ENABLED; pData->param.data[j].index = j; pData->param.data[j].rindex = j; - pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; + pData->param.data[j].midiChannel = 0; pData->param.ranges[j].min = 0.0f; pData->param.ranges[j].max = float(2048.0 * 1000.0 / pData->engine->getSampleRate()); // FIXME? pData->param.ranges[j].def = FLUID_CHORUS_DEFAULT_DEPTH; pData->param.ranges[j].step = 0.01f; pData->param.ranges[j].stepSmall = 0.0001f; pData->param.ranges[j].stepLarge = 0.1f; + pData->param.special[j] = PARAMETER_SPECIAL_NULL; fParamBuffers[j] = pData->param.ranges[j].def; // ---------------------- @@ -839,14 +849,15 @@ public: pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_INTEGER | PARAMETER_USES_SCALEPOINTS; pData->param.data[j].index = j; pData->param.data[j].rindex = j; - pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; + pData->param.data[j].midiChannel = 0; pData->param.ranges[j].min = FLUID_CHORUS_MOD_SINE; pData->param.ranges[j].max = FLUID_CHORUS_MOD_TRIANGLE; pData->param.ranges[j].def = FLUID_CHORUS_DEFAULT_TYPE; pData->param.ranges[j].step = 1.0f; pData->param.ranges[j].stepSmall = 1.0f; pData->param.ranges[j].stepLarge = 1.0f; + pData->param.special[j] = PARAMETER_SPECIAL_NULL; fParamBuffers[j] = pData->param.ranges[j].def; // ---------------------- @@ -855,14 +866,15 @@ public: pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_INTEGER; pData->param.data[j].index = j; pData->param.data[j].rindex = j; - pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; + pData->param.data[j].midiChannel = 0; pData->param.ranges[j].min = 1.0f; pData->param.ranges[j].max = 512.0f; // max theoric is 65535 pData->param.ranges[j].def = (float)fluid_synth_get_polyphony(fSynth); pData->param.ranges[j].step = 1.0f; pData->param.ranges[j].stepSmall = 1.0f; pData->param.ranges[j].stepLarge = 10.0f; + pData->param.special[j] = PARAMETER_SPECIAL_NULL; fParamBuffers[j] = pData->param.ranges[j].def; // ---------------------- @@ -871,14 +883,15 @@ public: pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_INTEGER | PARAMETER_USES_SCALEPOINTS; pData->param.data[j].index = j; pData->param.data[j].rindex = j; - pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; + pData->param.data[j].midiChannel = 0; pData->param.ranges[j].min = FLUID_INTERP_NONE; pData->param.ranges[j].max = FLUID_INTERP_HIGHEST; pData->param.ranges[j].def = FLUID_INTERP_DEFAULT; pData->param.ranges[j].step = 1.0f; pData->param.ranges[j].stepSmall = 1.0f; pData->param.ranges[j].stepLarge = 1.0f; + pData->param.special[j] = PARAMETER_SPECIAL_NULL; fParamBuffers[j] = pData->param.ranges[j].def; // ---------------------- @@ -887,14 +900,15 @@ public: pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE | PARAMETER_IS_INTEGER; pData->param.data[j].index = j; pData->param.data[j].rindex = j; - pData->param.data[j].midiChannel = 0; pData->param.data[j].midiCC = -1; + pData->param.data[j].midiChannel = 0; pData->param.ranges[j].min = 0.0f; pData->param.ranges[j].max = 65535.0f; pData->param.ranges[j].def = 0.0f; pData->param.ranges[j].step = 1.0f; pData->param.ranges[j].stepSmall = 1.0f; pData->param.ranges[j].stepLarge = 1.0f; + pData->param.special[j] = PARAMETER_SPECIAL_NULL; fParamBuffers[j] = pData->param.ranges[j].def; } @@ -924,13 +938,14 @@ public: carla_debug("FluidSynthPlugin::reload() - end"); } - void reloadPrograms(const bool init) override + void reloadPrograms(const bool doInit) override { - carla_debug("FluidSynthPlugin::reloadPrograms(%s)", bool2str(init)); + carla_debug("FluidSynthPlugin::reloadPrograms(%s)", bool2str(doInit)); // save drum info in case we have one program for it bool hasDrums = false; - uint32_t drumIndex, drumProg; + int32_t drumIndex; + uint32_t drumProg; // Delete old programs pData->midiprog.clear(); @@ -953,6 +968,7 @@ public: pData->midiprog.createNew(count); // Update data + int tmp; uint32_t i = 0; f_sfont->iteration_start(f_sfont); @@ -960,14 +976,18 @@ public: { CARLA_SAFE_ASSERT_BREAK(i < count); - pData->midiprog.data[i].bank = f_preset.get_banknum(&f_preset); - pData->midiprog.data[i].program = f_preset.get_num(&f_preset); - pData->midiprog.data[i].name = carla_strdup(f_preset.get_name(&f_preset)); + tmp = f_preset.get_banknum(&f_preset); + pData->midiprog.data[i].bank = (tmp >= 0) ? static_cast(tmp) : 0; + + tmp = f_preset.get_num(&f_preset); + pData->midiprog.data[i].program = (tmp >= 0) ? static_cast(tmp) : 0; + + pData->midiprog.data[i].name = carla_strdup(f_preset.get_name(&f_preset)); if (pData->midiprog.data[i].bank == 128 && ! hasDrums) { hasDrums = true; - drumIndex = i; + drumIndex = static_cast(i); drumProg = pData->midiprog.data[i].program; } @@ -992,12 +1012,12 @@ public: } #endif - if (init) + if (doInit) { fluid_synth_program_reset(fSynth); // select first program, or 128 for ch10 - for (uint32_t i=0; i < MAX_MIDI_CHANNELS && i != 9; ++i) + for (int i=0; i < MAX_MIDI_CHANNELS && i != 9; ++i) { #ifdef FLUIDSYNTH_VERSION_NEW_API fluid_synth_set_channel_type(fSynth, i, CHANNEL_TYPE_MELODIC); @@ -1255,10 +1275,10 @@ public: if (pData->midiprog.data[k].bank == bankId && pData->midiprog.data[k].program == progId) { fluid_synth_program_select(fSynth, event.channel, fSynthId, bankId, progId); - fCurMidiProgs[event.channel] = k; + fCurMidiProgs[event.channel] = static_cast(k); if (event.channel == pData->ctrlChannel) - pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0f); + pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, static_cast(k), 0, 0.0f); break; } @@ -1380,7 +1400,7 @@ public: if (pData->param.data[k].midiCC > 0) { float value(pData->param.ranges[k].getNormalizedValue(fParamBuffers[k])); - pData->event.portOut->writeControlEvent(0, pData->param.data[k].midiChannel, kEngineControlEventTypeParameter, pData->param.data[k].midiCC, value); + pData->event.portOut->writeControlEvent(0, pData->param.data[k].midiChannel, kEngineControlEventTypeParameter, static_cast(pData->param.data[k].midiCC), value); } } // End of Control Output @@ -1417,10 +1437,11 @@ public: for (uint32_t i=0; i < pData->audioOut.count; ++i) FLOAT_CLEAR(fAudio16Buffers[i], frames); - fluid_synth_process(fSynth, frames, 0, nullptr, pData->audioOut.count, fAudio16Buffers); + // FIXME use '32' or '16' instead of outs + fluid_synth_process(fSynth, static_cast(frames), 0, nullptr, static_cast(pData->audioOut.count), fAudio16Buffers); } else - fluid_synth_write_float(fSynth, frames, outBuffer[0] + timeOffset, 0, 1, outBuffer[1] + timeOffset, 0, 1); + fluid_synth_write_float(fSynth, static_cast(frames), outBuffer[0] + timeOffset, 0, 1, outBuffer[1] + timeOffset, 0, 1); #ifndef BUILD_BRIDGE // -------------------------------------------------------------------------------------------------------- @@ -1588,14 +1609,16 @@ public: // --------------------------------------------------------------- // open soundfont - fSynthId = fluid_synth_sfload(fSynth, filename, 0); + const int synthId(fluid_synth_sfload(fSynth, filename, 0)); - if (fSynthId < 0) + if (synthId < 0) { pData->engine->setLastError("Failed to load SoundFont file"); return false; } + fSynthId = static_cast(synthId); + // --------------------------------------------------------------- // get info @@ -1675,7 +1698,7 @@ private: fluid_settings_t* fSettings; fluid_synth_t* fSynth; - int fSynthId; + uint fSynthId; float** fAudio16Buffers; float fParamBuffers[FluidSynthParametersMax]; diff --git a/source/backend/plugin/LinuxSamplerPlugin.cpp b/source/backend/plugin/LinuxSamplerPlugin.cpp index 1b037e79e..2540ed39a 100644 --- a/source/backend/plugin/LinuxSamplerPlugin.cpp +++ b/source/backend/plugin/LinuxSamplerPlugin.cpp @@ -122,8 +122,8 @@ private: class MidiInputPortPlugin : public MidiInputPort { public: - MidiInputPortPlugin(MidiInputDevice* const device, const int portNumber) - : MidiInputPort(device, portNumber) + MidiInputPortPlugin(MidiInputDevice* const device, const int portNum) + : MidiInputPort(device, portNum) { } @@ -412,9 +412,9 @@ public: CARLA_SAFE_ASSERT_BREAK(i < MAX_MIDI_CHANNELS); bool ok; - uint index = midiProg.toUInt(&ok); + int index = midiProg.toInt(&ok); - if (ok && index < pData->midiprog.count) + if (ok && index >= 0 && index < static_cast(pData->midiprog.count)) { const uint32_t bank = pData->midiprog.data[index].bank; const uint32_t program = pData->midiprog.data[index].program; @@ -510,7 +510,7 @@ public: pData->audioOut.createNew(aOuts); - const int portNameSize(pData->engine->getMaxPortNameSize()); + const uint portNameSize(pData->engine->getMaxPortNameSize()); CarlaString portName; // --------------------------------------- @@ -518,7 +518,7 @@ public: if (fUses16Outs) { - for (int i=0; i < 32; ++i) + for (uint32_t i=0; i < 32; ++i) { portName.clear(); @@ -623,9 +623,9 @@ public: carla_debug("LinuxSamplerPlugin::reload() - end"); } - void reloadPrograms(bool init) override + void reloadPrograms(bool doInit) override { - carla_debug("LinuxSamplerPlugin::reloadPrograms(%s)", bool2str(init)); + carla_debug("LinuxSamplerPlugin::reloadPrograms(%s)", bool2str(doInit)); // Delete old programs pData->midiprog.clear(); @@ -668,7 +668,7 @@ public: } #endif - if (init) + if (doInit) { for (int i=0; i < MAX_MIDI_CHANNELS; ++i) { @@ -762,9 +762,9 @@ public: CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS); if (note.velo > 0) - fMidiInputPort->DispatchNoteOn(note.note, note.velo, note.channel); + fMidiInputPort->DispatchNoteOn(note.note, note.velo, static_cast(note.channel)); else - fMidiInputPort->DispatchNoteOff(note.note, note.velo, note.channel); + fMidiInputPort->DispatchNoteOff(note.note, note.velo, static_cast(note.channel)); } pData->extNotes.mutex.unlock(); @@ -777,7 +777,7 @@ public: bool allNotesOffSent = false; bool sampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0; - uint32_t time, nEvents = pData->event.portIn->getEventCount(); + uint32_t nEvents = pData->event.portIn->getEventCount(); uint32_t startTime = 0; uint32_t timeOffset = 0; @@ -790,17 +790,15 @@ public: { const EngineEvent& event(pData->event.portIn->getEvent(i)); - time = event.time; + CARLA_SAFE_ASSERT_CONTINUE(event.time < frames); + CARLA_SAFE_ASSERT_BREAK(event.time >= timeOffset); - CARLA_SAFE_ASSERT_CONTINUE(time < frames); - CARLA_SAFE_ASSERT_BREAK(time >= timeOffset); - - if (time > timeOffset && sampleAccurate) + if (event.time > timeOffset && sampleAccurate) { - if (processSingle(outBuffer, time - timeOffset, timeOffset)) + if (processSingle(outBuffer, event.time - timeOffset, timeOffset)) { startTime = 0; - timeOffset = time; + timeOffset = event.time; if (pData->midiprog.current >= 0 && pData->midiprog.count > 0 && pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS) nextBankIds[pData->ctrlChannel] = pData->midiprog.data[pData->midiprog.current].bank; @@ -907,7 +905,7 @@ public: if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param <= 0x5F) { - fMidiInputPort->DispatchControlChange(uint8_t(ctrlEvent.param), uint8_t(ctrlEvent.value*127.0f), event.channel, int32_t(sampleAccurate ? startTime : time)); + fMidiInputPort->DispatchControlChange(uint8_t(ctrlEvent.param), uint8_t(ctrlEvent.value*127.0f), event.channel, static_cast(sampleAccurate ? startTime : event.time)); } break; @@ -941,10 +939,10 @@ public: fInstrument->LoadInstrumentInBackground(fInstrumentIds[rIndex], engineChannel); } - fCurMidiProgs[event.channel] = k; + fCurMidiProgs[event.channel] = static_cast(k); if (event.channel == pData->ctrlChannel) - pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0f); + pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, static_cast(k), 0, 0.0f); break; } @@ -955,7 +953,7 @@ public: case kEngineControlEventTypeAllSoundOff: if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF) { - fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_SOUND_OFF, 0, event.channel, sampleAccurate ? startTime : time); + fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_SOUND_OFF, 0, event.channel, static_cast(sampleAccurate ? startTime : event.time)); } break; @@ -968,7 +966,7 @@ public: sendMidiAllNotesOffToCallback(); } - fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_NOTES_OFF, 0, event.channel, sampleAccurate ? startTime : time); + fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_NOTES_OFF, 0, event.channel, static_cast(sampleAccurate ? startTime : event.time)); } break; } @@ -1002,7 +1000,7 @@ public: if (status < 0xF0 && channel < MAX_MIDI_CHANNELS) data[0] = uint8_t(data[0] + channel); - fMidiInputPort->DispatchRaw(data, sampleAccurate ? startTime : time); + fMidiInputPort->DispatchRaw(data, static_cast(sampleAccurate ? startTime : event.time)); if (status == MIDI_STATUS_NOTE_ON) pData->postponeRtEvent(kPluginPostRtEventNoteOn, channel, data[1], data[2]); @@ -1193,7 +1191,7 @@ public: fMidiInputDevice = new LinuxSampler::MidiInputDevicePlugin(&fSampler); fMidiInputPort = fMidiInputDevice->CreateMidiPortPlugin(); - for (int i=0; i < MAX_MIDI_CHANNELS; ++i) + for (uint i=0; i < MAX_MIDI_CHANNELS; ++i) { fSamplerChannels[i] = fSampler.AddSamplerChannel(); CARLA_SAFE_ASSERT_CONTINUE(fSamplerChannels[i] != nullptr); diff --git a/source/backend/plugin/Lv2Plugin.cpp b/source/backend/plugin/Lv2Plugin.cpp index 86792ad49..4c9ba059f 100644 --- a/source/backend/plugin/Lv2Plugin.cpp +++ b/source/backend/plugin/Lv2Plugin.cpp @@ -42,6 +42,12 @@ CARLA_BACKEND_START_NAMESPACE } #endif +// Extra Plugin Hints +const unsigned int PLUGIN_HAS_EXTENSION_OPTIONS = 0x1000; +const unsigned int PLUGIN_HAS_EXTENSION_PROGRAMS = 0x2000; +const unsigned int PLUGIN_HAS_EXTENSION_STATE = 0x4000; +const unsigned int PLUGIN_HAS_EXTENSION_WORKER = 0x8000; + // Extra Parameter Hints const unsigned int PARAMETER_IS_STRICT_BOUNDS = 0x1000; const unsigned int PARAMETER_IS_TRIGGER = 0x2000; @@ -740,7 +746,9 @@ public: } } - if ((pData->options & PLUGIN_OPTION_FORCE_STEREO) != 0 && (aIns == 1 || aOuts == 1) /*&& fExt.state == nullptr && fExt.worker == nullptr*/) + recheckExtensions(); + + if ((pData->options & PLUGIN_OPTION_FORCE_STEREO) != 0 && (aIns == 1 || aOuts == 1) && fExt.state == nullptr && fExt.worker == nullptr) { if (fHandle2 == nullptr) fHandle2 = fDescriptor->instantiate(fDescriptor, sampleRate, fRdfDescriptor->Bundle, fFeatures); @@ -1121,8 +1129,16 @@ public: // extra plugin hints pData->extraHints = 0x0; - if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0)) - pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK; // FIXME + if (fExt.state != nullptr || fExt.worker != nullptr) + { + if ((aIns == 0 || aIns == 2) && (aOuts == 0 || aOuts == 2) /*&& evIns.count() <= 1 && evOuts.count() <= 1*/) + pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK; + } + else + { + if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0) /*&& evIns.count() <= 1 && evOuts.count() <= 1*/) + pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK; + } bufferSizeChanged(pData->engine->getBufferSize()); reloadPrograms(true); @@ -1576,6 +1592,46 @@ public: return false; } + void recheckExtensions() + { + CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr,); + + fExt.options = nullptr; + fExt.programs = nullptr; + fExt.state = nullptr; + fExt.worker = nullptr; + + for (uint32_t i=0; i < fRdfDescriptor->ExtensionCount; ++i) + { + if (std::strcmp(fRdfDescriptor->Extensions[i], LV2_OPTIONS__interface) == 0) + pData->hints |= PLUGIN_HAS_EXTENSION_OPTIONS; + else if (std::strcmp(fRdfDescriptor->Extensions[i], LV2_PROGRAMS__Interface) == 0) + pData->hints |= PLUGIN_HAS_EXTENSION_PROGRAMS; + else if (std::strcmp(fRdfDescriptor->Extensions[i], LV2_STATE__interface) == 0) + pData->hints |= PLUGIN_HAS_EXTENSION_STATE; + else if (std::strcmp(fRdfDescriptor->Extensions[i], LV2_WORKER__interface) == 0) + pData->hints |= PLUGIN_HAS_EXTENSION_WORKER; + else + carla_stdout("Plugin has non-supported extension: '%s'", fRdfDescriptor->Extensions[i]); + } + + if (fDescriptor->extension_data != nullptr) + { + if (pData->hints & PLUGIN_HAS_EXTENSION_OPTIONS) + fExt.options = (const LV2_Options_Interface*)fDescriptor->extension_data(LV2_OPTIONS__interface); + + if (pData->hints & PLUGIN_HAS_EXTENSION_PROGRAMS) + fExt.programs = (const LV2_Programs_Interface*)fDescriptor->extension_data(LV2_PROGRAMS__Interface); + + if (pData->hints & PLUGIN_HAS_EXTENSION_STATE) + fExt.state = (const LV2_State_Interface*)fDescriptor->extension_data(LV2_STATE__interface); + + if (pData->hints & PLUGIN_HAS_EXTENSION_WORKER) + fExt.worker = (const LV2_Worker_Interface*)fDescriptor->extension_data(LV2_WORKER__interface); + } + + } + // ------------------------------------------------------------------- LV2_URID getCustomURID(const char* const uri) @@ -1602,7 +1658,7 @@ public: return urid; } - const char* getCustomURIDString(const LV2_URID urid) + const char* getCustomURIDString(const LV2_URID urid) const noexcept { CARLA_SAFE_ASSERT_RETURN(urid != CARLA_URI_MAP_ID_NULL, nullptr); CARLA_SAFE_ASSERT_RETURN(urid < fCustomURIDs.count(), nullptr); @@ -1624,25 +1680,23 @@ public: return reloadPrograms(false); } -#if 0 if (index < static_cast(pData->midiprog.count) && fExt.programs != nullptr && fExt.programs->get_program != nullptr) { - if (const LV2_Program_Descriptor* progDesc = fExt.programs->get_program(fHandle, index)) + if (const LV2_Program_Descriptor* const progDesc = fExt.programs->get_program(fHandle, static_cast(index))) { - CARLA_ASSERT(progDesc->name != nullptr); + CARLA_SAFE_ASSERT_RETURN(progDesc->name != nullptr,); - if (kData->midiprog.data[index].name != nullptr) - delete[] kData->midiprog.data[index].name; + if (pData->midiprog.data[index].name != nullptr) + delete[] pData->midiprog.data[index].name; - kData->midiprog.data[index].name = carla_strdup(progDesc->name ? progDesc->name : ""); + pData->midiprog.data[index].name = carla_strdup(progDesc->name); - if (index == kData->midiprog.current) - kData->engine->callback(CALLBACK_UPDATE, fId, 0, 0, 0.0, nullptr); + if (index == pData->midiprog.current) + pData->engine->callback(ENGINE_CALLBACK_UPDATE, pData->id, 0, 0, 0.0, nullptr); else - kData->engine->callback(CALLBACK_RELOAD_PROGRAMS, fId, 0, 0, 0.0, nullptr); + pData->engine->callback(ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, 0, 0, 0.0, nullptr); } } -#endif } // ------------------------------------------------------------------- @@ -1998,6 +2052,27 @@ public: // ------------------------------------------------------------------- + void handleTransferAtom(const uint32_t portIndex, const LV2_Atom* const atom) + { + CARLA_SAFE_ASSERT_RETURN(atom != nullptr,); + carla_debug("Lv2Plugin::handleTransferAtom(%i, %p)", portIndex, atom); + + //fAtomQueueIn.put(portIndex, atom); + return; (void)portIndex; + } + + void handleUridMap(const LV2_URID urid, const char* const uri) + { + CARLA_SAFE_ASSERT_RETURN(urid != CARLA_URI_MAP_ID_NULL,); + CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(urid == fCustomURIDs.count(),); + carla_debug("Lv2Plugin::handleUridMap(%i, \"%s\")", urid, uri); + + fCustomURIDs.append(carla_strdup(uri)); + } + + // ------------------------------------------------------------------- + private: LV2_Handle fHandle; LV2_Handle fHandle2; @@ -2013,6 +2088,53 @@ private: LinkedList fCustomURIDs; + struct Extensions { + const LV2_Options_Interface* options; + const LV2_State_Interface* state; + const LV2_Worker_Interface* worker; + const LV2_Programs_Interface* programs; + const LV2UI_Idle_Interface* uiidle; + const LV2_Programs_UI_Interface* uiprograms; + + Extensions() + : options(nullptr), + state(nullptr), + worker(nullptr), + programs(nullptr), + uiidle(nullptr), + uiprograms(nullptr) {} + } fExt; + + struct UI { + enum Type { + TYPE_NULL, + TYPE_EMBED, + TYPE_EXTERNAL, + TYPE_OSC + }; + + Type type; + LV2UI_Handle handle; + LV2UI_Widget widget; + const LV2UI_Descriptor* descriptor; + const LV2_RDF_UI* rdfDescriptor; + + UI() + : type(TYPE_NULL), + handle(nullptr), + widget(nullptr), + descriptor(nullptr), + rdfDescriptor(nullptr) {} + + ~UI() + { + CARLA_ASSERT(handle == nullptr); + CARLA_ASSERT(widget == nullptr); + CARLA_ASSERT(descriptor == nullptr); + CARLA_ASSERT(rdfDescriptor == nullptr); + } + } fUi; + // ------------------------------------------------------------------- // Event Feature @@ -2041,6 +2163,7 @@ private: { CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 0); CARLA_SAFE_ASSERT_RETURN(type != CARLA_URI_MAP_ID_NULL, 0); + CARLA_SAFE_ASSERT_RETURN(fmt != nullptr, 0); #ifndef DEBUG if (type == CARLA_URI_MAP_ID_LOG_TRACE) @@ -2059,6 +2182,7 @@ private: { CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 0); CARLA_SAFE_ASSERT_RETURN(type != CARLA_URI_MAP_ID_NULL, 0); + CARLA_SAFE_ASSERT_RETURN(fmt != nullptr, 0); #ifndef DEBUG if (type == CARLA_URI_MAP_ID_LOG_TRACE) @@ -2375,11 +2499,19 @@ int CarlaEngineOsc::handleMsgLv2AtomTransfer(CARLA_ENGINE_OSC_HANDLE_ARGS2) CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "is"); carla_debug("CarlaOsc::handleMsgLv2AtomTransfer()"); - return 0; + const int32_t portIndex = argv[0]->i; + const char* const atomBuf = (const char*)&argv[1]->s; + + if (portIndex < 0) + return 0; + + QByteArray chunk(QByteArray::fromBase64(atomBuf)); + + CARLA_SAFE_ASSERT_RETURN(chunk.size() > 0, 0); - // unused for now - (void)argv; - (void)plugin; + const LV2_Atom* const atom((const LV2_Atom*)chunk.constData()); + lv2PluginPtr->handleTransferAtom(static_cast(portIndex), atom); + return 0; } int CarlaEngineOsc::handleMsgLv2UridMap(CARLA_ENGINE_OSC_HANDLE_ARGS2) @@ -2387,11 +2519,14 @@ int CarlaEngineOsc::handleMsgLv2UridMap(CARLA_ENGINE_OSC_HANDLE_ARGS2) CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "is"); carla_debug("CarlaOsc::handleMsgLv2EventTransfer()"); - return 0; + const int32_t urid = argv[0]->i; + const char* const uri = (const char*)&argv[1]->s; - // unused for now - (void)argv; - (void)plugin; + if (urid <= 0) + return 0; + + lv2PluginPtr->handleUridMap(static_cast(urid), uri); + return 0; } #undef lv2PluginPtr diff --git a/source/backend/plugin/Makefile b/source/backend/plugin/Makefile index cee945a23..1c1cfcef4 100644 --- a/source/backend/plugin/Makefile +++ b/source/backend/plugin/Makefile @@ -74,7 +74,7 @@ DssiPlugin.cpp.o: DssiPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ Lv2Plugin.cpp.o: Lv2Plugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_LV2_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) $(LV2_ATOM_QUEUE_HPP) $(CARLA_ENGINE_OSC_HPP) - $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ # FIXME - remove qtcore? + $(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ VstPlugin.cpp.o: VstPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_VST_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) $(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ diff --git a/source/backend/plugin/NativePlugin.cpp b/source/backend/plugin/NativePlugin.cpp index d096b95e0..1b8477ecf 100644 --- a/source/backend/plugin/NativePlugin.cpp +++ b/source/backend/plugin/NativePlugin.cpp @@ -564,9 +564,9 @@ public: foreach (const QString& midiProg, midiProgramList) { bool ok; - const uint index(midiProg.toUInt(&ok)); + const int index(midiProg.toInt(&ok)); - if (ok && index < pData->midiprog.count) + if (ok && index >= 0 && index < static_cast(pData->midiprog.count)) { const uint32_t bank = pData->midiprog.data[index].bank; const uint32_t program = pData->midiprog.data[index].program; @@ -671,7 +671,7 @@ public: if (fDescriptor->ui_set_midi_program != nullptr && pData->midiprog.current >= 0 && pData->midiprog.count > 0) { - const uint32_t index = pData->midiprog.current; + const int32_t index = pData->midiprog.current; const uint8_t channel = uint8_t((pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS) ? pData->ctrlChannel : 0); const uint32_t bank = pData->midiprog.data[index].bank; const uint32_t program = pData->midiprog.data[index].program; @@ -911,10 +911,11 @@ public: pData->param.data[j].type = PARAMETER_UNKNOWN; pData->param.data[j].hints = 0x0; - pData->param.data[j].index = j; - pData->param.data[j].rindex = j; + pData->param.data[j].index = static_cast(j); + pData->param.data[j].rindex = static_cast(j); pData->param.data[j].midiCC = -1; pData->param.data[j].midiChannel = 0; + pData->param.special[j] = PARAMETER_SPECIAL_NULL; float min, max, def, step, stepSmall, stepLarge; @@ -1139,7 +1140,7 @@ public: if (count == oldCount+1) { // one midi program added, probably created by user - pData->midiprog.current = oldCount; + pData->midiprog.current = static_cast(oldCount); programChanged = true; } else if (current < 0 && count > 0) @@ -1510,10 +1511,10 @@ public: if (fHandle2 != nullptr) fDescriptor->set_midi_program(fHandle2, event.channel, nextBankId, nextProgramId); - fCurMidiProgs[event.channel] = k; + fCurMidiProgs[event.channel] = static_cast(k); if (event.channel == pData->ctrlChannel) - pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0f); + pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, static_cast(k), 0, 0.0f); break; } @@ -1645,7 +1646,7 @@ public: if (pData->param.data[k].midiCC > 0) { value = pData->param.ranges[k].getNormalizedValue(curValue); - pData->event.portOut->writeControlEvent(0, pData->param.data[k].midiChannel, kEngineControlEventTypeParameter, pData->param.data[k].midiCC, value); + pData->event.portOut->writeControlEvent(0, pData->param.data[k].midiChannel, kEngineControlEventTypeParameter, static_cast(pData->param.data[k].midiCC), value); } } diff --git a/source/includes/CarlaDefines.h b/source/includes/CarlaDefines.h index fd4447a93..1c7c44237 100644 --- a/source/includes/CarlaDefines.h +++ b/source/includes/CarlaDefines.h @@ -138,10 +138,10 @@ /* Define CARLA_SAFE_ASSERT* */ #define CARLA_SAFE_ASSERT(cond) if (cond) pass(); else carla_safe_assert (#cond, __FILE__, __LINE__); -#define CARLA_SAFE_ASSERT_INT(cond, value) if (cond) pass(); else carla_safe_assert_int (#cond, __FILE__, __LINE__, value); -#define CARLA_SAFE_ASSERT_INT2(cond, v1, v2) if (cond) pass(); else carla_safe_assert_int2 (#cond, __FILE__, __LINE__, v1, v2); -#define CARLA_SAFE_ASSERT_UINT(cond, value) if (cond) pass(); else carla_safe_assert_uint (#cond, __FILE__, __LINE__, value); -#define CARLA_SAFE_ASSERT_UINT2(cond, v1, v2) if (cond) pass(); else carla_safe_assert_uint2(#cond, __FILE__, __LINE__, v1, v2); +#define CARLA_SAFE_ASSERT_INT(cond, value) if (cond) pass(); else carla_safe_assert_int (#cond, __FILE__, __LINE__, static_cast(value)); +#define CARLA_SAFE_ASSERT_INT2(cond, v1, v2) if (cond) pass(); else carla_safe_assert_int2 (#cond, __FILE__, __LINE__, static_cast(v1), static_cast(v2)); +#define CARLA_SAFE_ASSERT_UINT(cond, value) if (cond) pass(); else carla_safe_assert_uint (#cond, __FILE__, __LINE__, static_cast(value)); +#define CARLA_SAFE_ASSERT_UINT2(cond, v1, v2) if (cond) pass(); else carla_safe_assert_uint2(#cond, __FILE__, __LINE__, static_cast(v1), static_cast(v2)); #define CARLA_SAFE_ASSERT_BREAK(cond) if (cond) pass(); else { carla_safe_assert(#cond, __FILE__, __LINE__); break; } #define CARLA_SAFE_ASSERT_CONTINUE(cond) if (cond) pass(); else { carla_safe_assert(#cond, __FILE__, __LINE__); continue; } diff --git a/source/includes/lv2/atom-util.h b/source/includes/lv2/atom-util.h index e39a937e2..1d14eea5d 100644 --- a/source/includes/lv2/atom-util.h +++ b/source/includes/lv2/atom-util.h @@ -41,7 +41,7 @@ extern "C" { static inline uint32_t lv2_atom_pad_size(uint32_t size) { - return uint32_t(int32_t(size + 7) & (~7)); + return (uint32_t)((int32_t)(size + 7) & (~7)); } /** Return the total size of @p atom, including the header. */ diff --git a/source/utils/CarlaLv2Utils.hpp b/source/utils/CarlaLv2Utils.hpp index 32c1662a4..661c5de1f 100644 --- a/source/utils/CarlaLv2Utils.hpp +++ b/source/utils/CarlaLv2Utils.hpp @@ -1250,6 +1250,10 @@ bool is_lv2_port_supported(const LV2_Property types) return true; if (LV2_IS_PORT_AUDIO(types)) return true; + + // TODO + return false; + if (LV2_IS_PORT_ATOM_SEQUENCE(types)) return true; if (LV2_IS_PORT_CV(types)) diff --git a/source/utils/LinkedList.hpp b/source/utils/LinkedList.hpp index ad46bbeba..e47c89462 100644 --- a/source/utils/LinkedList.hpp +++ b/source/utils/LinkedList.hpp @@ -199,7 +199,7 @@ public: return false; } - T& getAt(const size_t index) noexcept + T& getAt(const size_t index) const noexcept { if (fCount == 0 || index >= fCount) return fRetValue; @@ -374,7 +374,7 @@ protected: virtual void _deallocate(Data*& dataPtr) = 0; private: - T fRetValue; + mutable T fRetValue; void _init() noexcept {