@@ -119,39 +119,6 @@ ifneq ($(shell pkg-config --exists QtXml && echo true),true) | |||
$(error QtXml missing, cannot continue) | |||
endif | |||
# -------------------------------------------------------------- | |||
# Check for optional libs (required by backend or bridges) | |||
HAVE_FFMPEG = $(shell pkg-config --exists libavcodec libavformat libavutil && pkg-config --max-version=1.9 libavcodec && echo true) | |||
HAVE_GTK2 = $(shell pkg-config --exists gtk+-2.0 && echo true) | |||
HAVE_GTK3 = $(shell pkg-config --exists gtk+-3.0 && echo true) | |||
HAVE_QT4 = $(shell pkg-config --exists QtCore QtGui && echo true) | |||
HAVE_QT5 = $(shell pkg-config --exists Qt5Core Qt5Gui Qt5Widgets && echo true) | |||
HAVE_X11 = $(shell pkg-config --exists x11 && echo true) | |||
ifeq ($(LINUX),true) | |||
HAVE_ALSA = $(shell pkg-config --exists alsa && echo true) | |||
HAVE_PULSEAUDIO = $(shell pkg-config --exists libpulse-simple && echo true) | |||
endif | |||
ifeq ($(CARLA_CSOUND_SUPPORT),true) | |||
# FIXME ? | |||
HAVE_CSOUND = $(shell pkg-config --exists sndfile && echo true) | |||
endif | |||
ifeq ($(CARLA_SAMPLERS_SUPPORT),true) | |||
HAVE_FLUIDSYNTH = $(shell pkg-config --exists fluidsynth && echo true) | |||
HAVE_LINUXSAMPLER = $(shell pkg-config --exists linuxsampler && echo true) | |||
endif | |||
# -------------------------------------------------------------- | |||
# Check for optional libs (needed by internal plugins) | |||
HAVE_AF_DEPS = $(shell pkg-config --exists sndfile && echo true) | |||
HAVE_MF_DEPS = $(shell pkg-config --exists smf && echo true) | |||
HAVE_ZYN_DEPS = $(shell pkg-config --exists fftw3 mxml zlib && echo true) | |||
HAVE_ZYN_UI_DEPS = $(shell pkg-config --exists ntk_images ntk && echo true) | |||
# -------------------------------------------------------------- | |||
# Check for dgl support | |||
@@ -190,6 +157,40 @@ ifeq ($(WIN32),true) | |||
HAVE_JUCE = true | |||
endif | |||
# -------------------------------------------------------------- | |||
# Check for optional libs (required by backend or bridges) | |||
HAVE_FFMPEG = $(shell pkg-config --exists libavcodec libavformat libavutil && pkg-config --max-version=1.9 libavcodec && echo true) | |||
HAVE_GTK2 = $(shell pkg-config --exists gtk+-2.0 && echo true) | |||
HAVE_GTK3 = $(shell pkg-config --exists gtk+-3.0 && echo true) | |||
HAVE_QT4 = $(shell pkg-config --exists QtCore QtGui && echo true) | |||
HAVE_QT5 = $(shell pkg-config --exists Qt5Core Qt5Gui Qt5Widgets && echo true) | |||
HAVE_X11 = $(shell pkg-config --exists x11 && echo true) | |||
ifeq ($(LINUX),true) | |||
HAVE_ALSA = $(shell pkg-config --exists alsa && echo true) | |||
HAVE_PULSEAUDIO = $(shell pkg-config --exists libpulse-simple && echo true) | |||
endif | |||
ifeq ($(CARLA_CSOUND_SUPPORT),true) | |||
ifeq ($(HAVE_JUCE),true) | |||
HAVE_CSOUND = $(shell pkg-config --exists sndfile && echo true) | |||
endif | |||
endif | |||
ifeq ($(CARLA_SAMPLERS_SUPPORT),true) | |||
HAVE_FLUIDSYNTH = $(shell pkg-config --exists fluidsynth && echo true) | |||
HAVE_LINUXSAMPLER = $(shell pkg-config --exists linuxsampler && echo true) | |||
endif | |||
# -------------------------------------------------------------- | |||
# Check for optional libs (needed by internal plugins) | |||
HAVE_AF_DEPS = $(shell pkg-config --exists sndfile && echo true) | |||
HAVE_MF_DEPS = $(shell pkg-config --exists smf && echo true) | |||
HAVE_ZYN_DEPS = $(shell pkg-config --exists fftw3 mxml zlib && echo true) | |||
HAVE_ZYN_UI_DEPS = $(shell pkg-config --exists ntk_images ntk && echo true) | |||
# -------------------------------------------------------------- | |||
# Set base stuff | |||
@@ -1613,6 +1613,10 @@ const EngineDriverDeviceInfo* CarlaEngine::getJuceDeviceInfo(const unsigned int, | |||
CARLA_BACKEND_END_NAMESPACE | |||
#ifdef WANT_DSSI | |||
# include "CarlaDssiUtils.cpp" | |||
#endif | |||
#include "CarlaStateUtils.cpp" | |||
#endif | |||
@@ -1732,7 +1732,7 @@ void CarlaPlugin::sendMidiAllNotesOffToCallback() | |||
postEvent.value2 = 0; | |||
postEvent.value3 = 0.0f; | |||
for (unsigned short i=0; i < MAX_MIDI_NOTE; ++i) | |||
for (int32_t i=0; i < MAX_MIDI_NOTE; ++i) | |||
{ | |||
postEvent.value2 = i; | |||
pData->postRtEvents.appendRT(postEvent); | |||
@@ -23,45 +23,7 @@ | |||
#include "CarlaDssiUtils.hpp" | |||
#include "CarlaMathUtils.hpp" | |||
// TODO - put this in a cpp file | |||
#include <QtCore/QDir> | |||
#include <QtCore/QFileInfo> | |||
#include <QtCore/QStringList> | |||
const char* find_dssi_ui(const char* const filename, const char* const label) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr); | |||
CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0', nullptr); | |||
carla_debug("find_dssi_ui(\"%s\", \"%s\")", filename, label); | |||
QString guiFilename; | |||
QString pluginDir(filename); | |||
pluginDir.resize(pluginDir.lastIndexOf(".")); | |||
QString checkLabel(label); | |||
QString checkSName(QFileInfo(pluginDir).baseName()); | |||
if (! checkLabel.endsWith("_")) checkLabel += "_"; | |||
if (! checkSName.endsWith("_")) checkSName += "_"; | |||
QStringList guiFiles(QDir(pluginDir).entryList()); | |||
foreach (const QString& gui, guiFiles) | |||
{ | |||
if (gui.startsWith(checkLabel) || gui.startsWith(checkSName)) | |||
{ | |||
QFileInfo finalname(pluginDir + QDir::separator() + gui); | |||
guiFilename = finalname.absoluteFilePath(); | |||
break; | |||
} | |||
} | |||
if (guiFilename.isEmpty()) | |||
return nullptr; | |||
return carla_strdup(guiFilename.toUtf8().constData()); | |||
} | |||
#include <QtCore/QByteArray> | |||
CARLA_BACKEND_START_NAMESPACE | |||
@@ -79,7 +41,7 @@ public: | |||
fDescriptor(nullptr), | |||
fDssiDescriptor(nullptr), | |||
fUsesCustomData(false), | |||
fGuiFilename(nullptr), | |||
fUiFilename(nullptr), | |||
fAudioInBuffers(nullptr), | |||
fAudioOutBuffers(nullptr), | |||
fParamBuffers(nullptr) | |||
@@ -132,10 +94,10 @@ public: | |||
fDssiDescriptor = nullptr; | |||
} | |||
if (fGuiFilename != nullptr) | |||
if (fUiFilename != nullptr) | |||
{ | |||
delete[] fGuiFilename; | |||
fGuiFilename = nullptr; | |||
delete[] fUiFilename; | |||
fUiFilename = nullptr; | |||
} | |||
clearBuffers(); | |||
@@ -589,12 +551,12 @@ public: | |||
else if (LADSPA_IS_PORT_CONTROL(portType)) | |||
{ | |||
uint32_t j = iCtrl++; | |||
pData->param.data[j].type = PARAMETER_UNKNOWN; | |||
pData->param.data[j].hints = 0x0; | |||
pData->param.data[j].index = static_cast<int32_t>(j); | |||
pData->param.data[j].rindex = static_cast<int32_t>(i); | |||
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; | |||
@@ -689,18 +651,8 @@ public: | |||
stepSmall = 1.0f; | |||
stepLarge = 1.0f; | |||
pData->param.data[j].type = PARAMETER_SPECIAL; | |||
pData->param.data[j].hints = 0; // TODO PARAMETER_LATENCY | |||
} | |||
else if (std::strcmp(fDescriptor->PortNames[i], "_sample-rate") == 0) | |||
{ | |||
def = sampleRate; | |||
step = 1.0f; | |||
stepSmall = 1.0f; | |||
stepLarge = 1.0f; | |||
pData->param.data[j].type = PARAMETER_SPECIAL; | |||
pData->param.data[j].hints = 0; // TODO PARAMETER_SAMPLE_RATE | |||
pData->param.data[j].type = PARAMETER_SPECIAL; | |||
pData->param.special[j] = PARAMETER_SPECIAL_LATENCY; | |||
} | |||
else | |||
{ | |||
@@ -790,7 +742,7 @@ public: | |||
if (LADSPA_IS_HARD_RT_CAPABLE(fDescriptor->Properties)) | |||
pData->hints |= PLUGIN_IS_RTSAFE; | |||
if (fGuiFilename != nullptr) | |||
if (fUiFilename != nullptr) | |||
pData->hints |= PLUGIN_HAS_CUSTOM_UI; | |||
if (aOuts > 0 && (aIns == aOuts || aIns == 1)) | |||
@@ -816,8 +768,8 @@ public: | |||
{ | |||
for (uint32_t i=0; i < pData->param.count; ++i) | |||
{ | |||
//if (pData->param.data[i].type != PARAMETER_LATENCY) | |||
// continue; | |||
if (pData->param.special[i] != PARAMETER_SPECIAL_LATENCY) | |||
continue; | |||
// we need to pre-run the plugin so it can update its latency control-port | |||
@@ -883,8 +835,8 @@ public: | |||
uint32_t newCount = 0; | |||
if (fDssiDescriptor->get_program != nullptr && fDssiDescriptor->select_program != nullptr) | |||
{ | |||
while (fDssiDescriptor->get_program(fHandle, newCount)) | |||
newCount++; | |||
for (; fDssiDescriptor->get_program(fHandle, newCount) != nullptr;) | |||
++newCount; | |||
} | |||
if (newCount > 0) | |||
@@ -1061,8 +1013,6 @@ public: | |||
} | |||
pData->needsReset = false; | |||
CARLA_PROCESS_CONTINUE_CHECK; | |||
} | |||
// -------------------------------------------------------------------------------------------------------- | |||
@@ -1075,7 +1025,7 @@ public: | |||
if (pData->extNotes.mutex.tryLock()) | |||
{ | |||
while (midiEventCount < kPluginMaxMidiEvents && ! pData->extNotes.data.isEmpty()) | |||
for (; midiEventCount < kPluginMaxMidiEvents && ! pData->extNotes.data.isEmpty();) | |||
{ | |||
const ExternalMidiNote& note(pData->extNotes.data.getFirst(true)); | |||
@@ -1100,33 +1050,31 @@ public: | |||
bool allNotesOffSent = false; | |||
bool isSampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0; | |||
uint32_t time, numEvents = pData->event.portIn->getEventCount(); | |||
uint32_t numEvents = pData->event.portIn->getEventCount(); | |||
uint32_t startTime = 0; | |||
uint32_t timeOffset = 0; | |||
uint32_t nextBankId = 0; | |||
uint32_t nextBankId; | |||
if (pData->midiprog.current >= 0 && pData->midiprog.count > 0) | |||
nextBankId = pData->midiprog.data[pData->midiprog.current].bank; | |||
else | |||
nextBankId = 0; | |||
for (uint32_t i=0; i < numEvents; ++i) | |||
{ | |||
const EngineEvent& event(pData->event.portIn->getEvent(i)); | |||
time = event.time; | |||
CARLA_ASSERT_INT2(time < frames, time, frames); | |||
if (time >= frames) | |||
if (event.time >= frames) | |||
continue; | |||
CARLA_ASSERT_INT2(time >= timeOffset, time, timeOffset); | |||
CARLA_ASSERT_INT2(event.time >= timeOffset, event.time, timeOffset); | |||
if (time > timeOffset && isSampleAccurate) | |||
if (isSampleAccurate && event.time > timeOffset) | |||
{ | |||
if (processSingle(inBuffer, outBuffer, time - timeOffset, timeOffset, midiEventCount)) | |||
if (processSingle(inBuffer, outBuffer, event.time - timeOffset, timeOffset, midiEventCount)) | |||
{ | |||
startTime = 0; | |||
timeOffset = time; | |||
timeOffset = event.time; | |||
midiEventCount = 0; | |||
if (pData->midiprog.current >= 0 && pData->midiprog.count > 0) | |||
@@ -1143,8 +1091,7 @@ public: | |||
case kEngineEventTypeNull: | |||
break; | |||
case kEngineEventTypeControl: | |||
{ | |||
case kEngineEventTypeControl: { | |||
const EngineControlEvent& ctrlEvent(event.ctrl); | |||
switch (ctrlEvent.type) | |||
@@ -1152,8 +1099,7 @@ public: | |||
case kEngineControlEventTypeNull: | |||
break; | |||
case kEngineControlEventTypeParameter: | |||
{ | |||
case kEngineControlEventTypeParameter: { | |||
#ifndef BUILD_BRIDGE | |||
// Control backend stuff | |||
if (event.channel == pData->ctrlChannel) | |||
@@ -1165,6 +1111,7 @@ public: | |||
value = ctrlEvent.value; | |||
setDryWet(value, false, false); | |||
pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, value); | |||
break; | |||
} | |||
if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0) | |||
@@ -1172,6 +1119,7 @@ public: | |||
value = ctrlEvent.value*127.0f/100.0f; | |||
setVolume(value, false, false); | |||
pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value); | |||
break; | |||
} | |||
if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0) | |||
@@ -1199,12 +1147,14 @@ public: | |||
setBalanceRight(right, false, false); | |||
pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left); | |||
pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right); | |||
break; | |||
} | |||
} | |||
#endif | |||
// Control plugin parameters | |||
for (uint32_t k=0; k < pData->param.count; ++k) | |||
uint32_t k; | |||
for (k=0; k < pData->param.count; ++k) | |||
{ | |||
if (pData->param.data[k].midiChannel != event.channel) | |||
continue; | |||
@@ -1231,8 +1181,13 @@ public: | |||
setParameterValue(k, value, false, false, false); | |||
pData->postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value); | |||
break; | |||
} | |||
// check if event is already handled | |||
if (k == pData->param.count) | |||
break; | |||
if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param <= 0x5F) | |||
{ | |||
if (midiEventCount >= kPluginMaxMidiEvents) | |||
@@ -1241,7 +1196,7 @@ public: | |||
snd_seq_event_t& midiEvent(fMidiEvents[midiEventCount++]); | |||
carla_zeroStruct<snd_seq_event_t>(midiEvent); | |||
midiEvent.time.tick = isSampleAccurate ? startTime : time; | |||
midiEvent.time.tick = isSampleAccurate ? startTime : event.time; | |||
midiEvent.type = SND_SEQ_EVENT_CONTROLLER; | |||
midiEvent.data.control.channel = event.channel; | |||
@@ -1250,7 +1205,7 @@ public: | |||
} | |||
break; | |||
} | |||
} // case kEngineControlEventTypeParameter | |||
case kEngineControlEventTypeMidiBank: | |||
if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0) | |||
@@ -1284,7 +1239,7 @@ public: | |||
snd_seq_event_t& midiEvent(fMidiEvents[midiEventCount++]); | |||
carla_zeroStruct<snd_seq_event_t>(midiEvent); | |||
midiEvent.time.tick = isSampleAccurate ? startTime : time; | |||
midiEvent.time.tick = isSampleAccurate ? startTime : event.time; | |||
midiEvent.type = SND_SEQ_EVENT_CONTROLLER; | |||
midiEvent.data.control.channel = event.channel; | |||
@@ -1307,7 +1262,7 @@ public: | |||
snd_seq_event_t& midiEvent(fMidiEvents[midiEventCount++]); | |||
carla_zeroStruct<snd_seq_event_t>(midiEvent); | |||
midiEvent.time.tick = isSampleAccurate ? startTime : time; | |||
midiEvent.time.tick = isSampleAccurate ? startTime : event.time; | |||
midiEvent.type = SND_SEQ_EVENT_CONTROLLER; | |||
midiEvent.data.control.channel = event.channel; | |||
@@ -1316,13 +1271,11 @@ public: | |||
midiEventCount += 1; | |||
} | |||
break; | |||
} | |||
} // switch (ctrlEvent.type) | |||
break; | |||
} | |||
} // case kEngineEventTypeControl | |||
case kEngineEventTypeMidi: | |||
{ | |||
case kEngineEventTypeMidi: { | |||
if (midiEventCount >= kPluginMaxMidiEvents) | |||
continue; | |||
@@ -1338,12 +1291,11 @@ public: | |||
snd_seq_event_t& midiEvent(fMidiEvents[midiEventCount]); | |||
carla_zeroStruct<snd_seq_event_t>(midiEvent); | |||
midiEvent.time.tick = isSampleAccurate ? startTime : time; | |||
midiEvent.time.tick = isSampleAccurate ? startTime : event.time; | |||
switch (status) | |||
{ | |||
case MIDI_STATUS_NOTE_OFF: | |||
{ | |||
case MIDI_STATUS_NOTE_OFF: { | |||
const uint8_t note = engineEvent.data[1]; | |||
midiEvent.type = SND_SEQ_EVENT_NOTEOFF; | |||
@@ -1353,8 +1305,8 @@ public: | |||
pData->postponeRtEvent(kPluginPostRtEventNoteOff, channel, note, 0.0f); | |||
break; | |||
} | |||
case MIDI_STATUS_NOTE_ON: | |||
{ | |||
case MIDI_STATUS_NOTE_ON: { | |||
const uint8_t note = engineEvent.data[1]; | |||
const uint8_t velo = engineEvent.data[2]; | |||
@@ -1366,8 +1318,8 @@ public: | |||
pData->postponeRtEvent(kPluginPostRtEventNoteOn, channel, note, velo); | |||
break; | |||
} | |||
case MIDI_STATUS_POLYPHONIC_AFTERTOUCH: | |||
{ | |||
if (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) | |||
{ | |||
const uint8_t note = engineEvent.data[1]; | |||
@@ -1379,9 +1331,8 @@ public: | |||
midiEvent.data.note.velocity = pressure; | |||
} | |||
break; | |||
} | |||
case MIDI_STATUS_CONTROL_CHANGE: | |||
{ | |||
if (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) | |||
{ | |||
const uint8_t control = engineEvent.data[1]; | |||
@@ -1393,9 +1344,8 @@ public: | |||
midiEvent.data.control.value = value; | |||
} | |||
break; | |||
} | |||
case MIDI_STATUS_CHANNEL_PRESSURE: | |||
{ | |||
if (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) | |||
{ | |||
const uint8_t pressure = engineEvent.data[1]; | |||
@@ -1405,9 +1355,8 @@ public: | |||
midiEvent.data.control.value = pressure; | |||
} | |||
break; | |||
} | |||
case MIDI_STATUS_PITCH_WHEEL_CONTROL: | |||
{ | |||
if (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) | |||
{ | |||
const uint8_t lsb = engineEvent.data[1]; | |||
@@ -1418,16 +1367,16 @@ public: | |||
midiEvent.data.control.value = ((msb << 7) | lsb) - 8192; | |||
} | |||
break; | |||
} | |||
default: | |||
continue; | |||
break; | |||
} | |||
} // switch (status) | |||
midiEventCount += 1; | |||
break; | |||
} | |||
} | |||
} // case kEngineEventTypeMidi | |||
} // switch (event.type) | |||
} | |||
pData->postRtEvents.trySplice(); | |||
@@ -1814,7 +1763,7 @@ public: | |||
const void* getExtraStuff() const noexcept override | |||
{ | |||
return fGuiFilename; | |||
return fUiFilename; | |||
} | |||
bool init(const char* const filename, const char* const name, const char* const label) | |||
@@ -1945,7 +1894,7 @@ public: | |||
if (const char* const guiFilename = find_dssi_ui(filename, fDescriptor->Label)) | |||
{ | |||
pData->osc.thread.setOscData(guiFilename, fDescriptor->Label); | |||
fGuiFilename = guiFilename; | |||
fUiFilename = guiFilename; | |||
} | |||
// --------------------------------------------------------------- | |||
@@ -2015,7 +1964,7 @@ private: | |||
const DSSI_Descriptor* fDssiDescriptor; | |||
bool fUsesCustomData; | |||
const char* fGuiFilename; | |||
const char* fUiFilename; | |||
float** fAudioInBuffers; | |||
float** fAudioOutBuffers; | |||
@@ -550,7 +550,6 @@ public: | |||
else if (LADSPA_IS_PORT_CONTROL(portType)) | |||
{ | |||
uint32_t j = iCtrl++; | |||
pData->param.data[j].type = PARAMETER_UNKNOWN; | |||
pData->param.data[j].hints = 0x0; | |||
pData->param.data[j].index = static_cast<int32_t>(j); | |||
pData->param.data[j].rindex = static_cast<int32_t>(i); | |||
@@ -645,16 +644,6 @@ public: | |||
pData->param.data[j].type = PARAMETER_SPECIAL; | |||
pData->param.special[j] = PARAMETER_SPECIAL_LATENCY; | |||
} | |||
else if (std::strcmp(fDescriptor->PortNames[i], "_sample-rate") == 0) | |||
{ | |||
def = sampleRate; | |||
step = 1.0f; | |||
stepSmall = 1.0f; | |||
stepLarge = 1.0f; | |||
pData->param.data[j].type = PARAMETER_SPECIAL; | |||
pData->param.special[j] = PARAMETER_SPECIAL_SAMPLE_RATE; | |||
} | |||
else | |||
{ | |||
pData->param.data[j].type = PARAMETER_OUTPUT; | |||
@@ -665,6 +654,7 @@ public: | |||
} | |||
else | |||
{ | |||
pData->param.data[j].type = PARAMETER_UNKNOWN; | |||
carla_stderr2("WARNING - Got a broken Port (Control, but not input or output)"); | |||
} | |||
@@ -872,7 +862,6 @@ public: | |||
// disable any output sound | |||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | |||
FLOAT_CLEAR(outBuffer[i], frames); | |||
return; | |||
} | |||
@@ -900,34 +889,30 @@ public: | |||
bool isSampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0; | |||
uint32_t time, numEvents = pData->event.portIn->getEventCount(); | |||
uint32_t numEvents = pData->event.portIn->getEventCount(); | |||
uint32_t timeOffset = 0; | |||
for (uint32_t i=0; i < numEvents; ++i) | |||
{ | |||
const EngineEvent& event(pData->event.portIn->getEvent(i)); | |||
time = event.time; | |||
if (time >= frames) | |||
if (event.time >= frames) | |||
continue; | |||
CARLA_ASSERT_INT2(time >= timeOffset, time, timeOffset); | |||
CARLA_ASSERT_INT2(event.time >= timeOffset, event.time, timeOffset); | |||
if (time > timeOffset && isSampleAccurate) | |||
if (isSampleAccurate && event.time > timeOffset) | |||
{ | |||
if (processSingle(inBuffer, outBuffer, time - timeOffset, timeOffset)) | |||
timeOffset = time; | |||
if (processSingle(inBuffer, outBuffer, event.time - timeOffset, timeOffset)) | |||
timeOffset = event.time; | |||
} | |||
// Control change | |||
switch (event.type) | |||
{ | |||
case kEngineEventTypeNull: | |||
break; | |||
case kEngineEventTypeControl: | |||
{ | |||
case kEngineEventTypeControl: { | |||
const EngineControlEvent& ctrlEvent(event.ctrl); | |||
switch (ctrlEvent.type) | |||
@@ -935,8 +920,7 @@ public: | |||
case kEngineControlEventTypeNull: | |||
break; | |||
case kEngineControlEventTypeParameter: | |||
{ | |||
case kEngineControlEventTypeParameter: { | |||
#ifndef BUILD_BRIDGE | |||
// Control backend stuff | |||
if (event.channel == pData->ctrlChannel) | |||
@@ -948,6 +932,7 @@ public: | |||
value = ctrlEvent.value; | |||
setDryWet(value, false, false); | |||
pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, value); | |||
break; | |||
} | |||
if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0) | |||
@@ -955,6 +940,7 @@ public: | |||
value = ctrlEvent.value*127.0f/100.0f; | |||
setVolume(value, false, false); | |||
pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value); | |||
break; | |||
} | |||
if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0) | |||
@@ -982,6 +968,7 @@ public: | |||
setBalanceRight(right, false, false); | |||
pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left); | |||
pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right); | |||
break; | |||
} | |||
} | |||
#endif | |||
@@ -1014,25 +1001,24 @@ public: | |||
setParameterValue(k, value, false, false, false); | |||
pData->postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value); | |||
break; | |||
} | |||
break; | |||
} | |||
} // case kEngineControlEventTypeParameter | |||
case kEngineControlEventTypeMidiBank: | |||
case kEngineControlEventTypeMidiProgram: | |||
case kEngineControlEventTypeAllSoundOff: | |||
case kEngineControlEventTypeAllNotesOff: | |||
break; | |||
} | |||
} // switch (ctrlEvent.type) | |||
break; | |||
} | |||
} // case kEngineEventTypeControl | |||
case kEngineEventTypeMidi: | |||
// ignored in LADSPA | |||
break; | |||
} | |||
} // switch (event.type) | |||
} | |||
pData->postRtEvents.trySplice(); | |||
@@ -71,10 +71,10 @@ LadspaPlugin.cpp.o: LadspaPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE | |||
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||
DssiPlugin.cpp.o: DssiPlugin.cpp $(CARLA_PLUGIN_INTERNAL_HPP) $(CARLA_ENGINE_HPP) $(CARLA_DSSI_UTILS_HPP) $(CARLA_MATH_UTILS_HPP) | |||
$(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ # FIXME | |||
$(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 | |||
$(CXX) $< $(BUILD_CXX_FLAGS) $(QTCORE_FLAGS) -c -o $@ # FIXME - remove qtcore? | |||
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 $@ | |||
@@ -1924,6 +1924,10 @@ const char* carla_get_host_osc_url_udp() | |||
// ------------------------------------------------------------------------------------------------------------------- | |||
#ifdef WANT_DSSI | |||
# include "CarlaDssiUtils.cpp" | |||
#endif | |||
#include "CarlaStateUtils.cpp" | |||
#if 0 | |||
@@ -1376,7 +1376,7 @@ class PluginEdit(QDialog): | |||
self.fTabIconTimers.append(ICON_STATE_NULL) | |||
def _updateCtrlMidiProgram(self): | |||
if self.fPluginInfo['type'] not in (PLUGIN_INTERNAL, PLUGIN_SF2): | |||
if self.fPluginInfo['type'] not in (PLUGIN_INTERNAL, PLUGIN_FILE_SF2): | |||
return | |||
elif self.fPluginInfo['category'] != PLUGIN_CATEGORY_SYNTH: | |||
return | |||
@@ -10,6 +10,10 @@ include ../Makefile.mk | |||
BUILD_CXX_FLAGS += -I../backend -I../includes -I../utils -isystem ../modules -Wno-multichar | |||
ifeq ($(MACOS),true) | |||
BUILD_CXX_FLAGS += -ObjC++ | |||
endif | |||
BUILD_CXX_FLAGS += $(QTCORE_FLAGS) | |||
LINK_FLAGS += $(QTCORE_LIBS) | |||
@@ -18,7 +22,8 @@ LINK_FLAGS += $(QTCORE_LIBS) | |||
BUILD_CXX_FLAGS += -DWANT_NATIVE | |||
ifeq ($(CARLA_PLUGIN_SUPPORT),true) | |||
BUILD_CXX_FLAGS += -DWANT_LADSPA -DWANT_DSSI -DWANT_LV2 | |||
BUILD_CXX_FLAGS += -DWANT_LADSPA -DWANT_DSSI | |||
# -DWANT_LV2 | |||
# -DWANT_VST | |||
# ifeq ($(CARLA_VESTIGE_HEADER),true) | |||
# BUILD_CXX_FLAGS += -DVESTIGE_HEADER | |||
@@ -78,11 +83,8 @@ WIN_32BIT_FLAGS = $(32BIT_FLAGS) | |||
WIN_64BIT_FLAGS = $(64BIT_FLAGS) | |||
WIN_LINK_FLAGS = $(LINK_FLAGS) $(EXTRA_LIBS) | |||
ifeq ($(MACOS),true) | |||
OBJS = carla-discovery.mm.o | |||
else | |||
OBJS = carla-discovery.cpp | |||
endif | |||
# -------------------------------------------------------------- | |||
@@ -66,14 +66,14 @@ CARLA_BACKEND_USE_NAMESPACE | |||
// -------------------------------------------------------------------------- | |||
// Dummy values to test plugins with | |||
const uint32_t kBufferSize = 512; | |||
const double kSampleRate = 44100.0; | |||
const float kSampleRatef = 44100.0f; | |||
static const uint32_t kBufferSize = 512; | |||
static const double kSampleRate = 44100.0; | |||
static const float kSampleRatef = 44100.0f; | |||
// -------------------------------------------------------------------------- | |||
// Don't print ELF/EXE related errors since discovery can find multi-architecture binaries | |||
void print_lib_error(const char* const filename) | |||
static void print_lib_error(const char* const filename) | |||
{ | |||
const char* const error(lib_error(filename)); | |||
@@ -86,22 +86,22 @@ void print_lib_error(const char* const filename) | |||
// VST stuff | |||
// Check if plugin is currently processing | |||
bool gVstIsProcessing = false; | |||
static bool gVstIsProcessing = false; | |||
// Check if plugin needs idle | |||
bool gVstNeedsIdle = false; | |||
static bool gVstNeedsIdle = false; | |||
// Check if plugin wants midi | |||
bool gVstWantsMidi = false; | |||
static bool gVstWantsMidi = false; | |||
// Check if plugin wants time | |||
bool gVstWantsTime = false; | |||
static bool gVstWantsTime = false; | |||
// Current uniqueId for VST shell plugins | |||
intptr_t gVstCurrentUniqueId = 0; | |||
static intptr_t gVstCurrentUniqueId = 0; | |||
// Supported Carla features | |||
intptr_t vstHostCanDo(const char* const feature) | |||
static intptr_t vstHostCanDo(const char* const feature) | |||
{ | |||
carla_debug("vstHostCanDo(\"%s\")", feature); | |||
@@ -153,7 +153,7 @@ intptr_t vstHostCanDo(const char* const feature) | |||
} | |||
// Host-side callback | |||
intptr_t VSTCALLBACK vstHostCallback(AEffect* const effect, const int32_t opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt) | |||
static intptr_t VSTCALLBACK vstHostCallback(AEffect* const effect, const int32_t opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt) | |||
{ | |||
carla_debug("vstHostCallback(%p, %i:%s, %i, " P_INTPTR ", %p, %f)", effect, opcode, vstMasterOpcode2str(opcode), index, value, ptr, opt); | |||
@@ -431,7 +431,7 @@ private: | |||
// ------------------------------ Plugin Checks ----------------------------- | |||
void do_ladspa_check(void*& libHandle, const char* const filename, const bool init) | |||
static void do_ladspa_check(void*& libHandle, const char* const filename, const bool init) | |||
{ | |||
#ifdef WANT_LADSPA | |||
LADSPA_Descriptor_Function descFn = (LADSPA_Descriptor_Function)lib_symbol(libHandle, "ladspa_descriptor"); | |||
@@ -508,7 +508,7 @@ void do_ladspa_check(void*& libHandle, const char* const filename, const bool in | |||
DISCOVERY_OUT("warning", "Plugin '" << descriptor->Name << "' is not hard real-time capable"); | |||
} | |||
int hints = 0x0; | |||
uint hints = 0x0; | |||
int audioIns = 0; | |||
int audioOuts = 0; | |||
int audioTotal = 0; | |||
@@ -675,7 +675,7 @@ void do_ladspa_check(void*& libHandle, const char* const filename, const bool in | |||
#endif | |||
} | |||
void do_dssi_check(void*& libHandle, const char* const filename, const bool init) | |||
static void do_dssi_check(void*& libHandle, const char* const filename, const bool init) | |||
{ | |||
#ifdef WANT_DSSI | |||
DSSI_Descriptor_Function descFn = (DSSI_Descriptor_Function)lib_symbol(libHandle, "dssi_descriptor"); | |||
@@ -726,7 +726,7 @@ void do_dssi_check(void*& libHandle, const char* const filename, const bool init | |||
return; | |||
} | |||
DSSI_Descriptor_Function descFn = (DSSI_Descriptor_Function)lib_symbol(libHandle, "dssi_descriptor"); | |||
descFn = (DSSI_Descriptor_Function)lib_symbol(libHandle, "dssi_descriptor"); | |||
if (descFn == nullptr) | |||
{ | |||
@@ -772,7 +772,7 @@ void do_dssi_check(void*& libHandle, const char* const filename, const bool init | |||
DISCOVERY_OUT("warning", "Plugin '" << ldescriptor->Name << "' is not hard real-time capable"); | |||
} | |||
int hints = 0x0; | |||
uint hints = 0x0; | |||
int audioIns = 0; | |||
int audioOuts = 0; | |||
int audioTotal = 0; | |||
@@ -780,7 +780,7 @@ void do_dssi_check(void*& libHandle, const char* const filename, const bool init | |||
int parametersIns = 0; | |||
int parametersOuts = 0; | |||
int parametersTotal = 0; | |||
int programs = 0; | |||
ulong programs = 0; | |||
if (LADSPA_IS_HARD_RT_CAPABLE(ldescriptor->Properties)) | |||
hints |= PLUGIN_IS_RTSAFE; | |||
@@ -816,13 +816,11 @@ void do_dssi_check(void*& libHandle, const char* const filename, const bool init | |||
if (midiIns > 0 && audioIns == 0 && audioOuts > 0) | |||
hints |= PLUGIN_IS_SYNTH; | |||
#if 0 // FIXME | |||
if (const char* const ui = find_dssi_ui(filename, ldescriptor->Label)) | |||
{ | |||
hints |= PLUGIN_HAS_CUSTOM_UI; | |||
delete[] ui; | |||
} | |||
#endif | |||
if (init) | |||
{ | |||
@@ -850,8 +848,8 @@ void do_dssi_check(void*& libHandle, const char* const filename, const bool init | |||
if (descriptor->get_program != nullptr && descriptor->select_program != nullptr) | |||
{ | |||
while (descriptor->get_program(handle, programs++) != nullptr) | |||
continue; | |||
for (; descriptor->get_program(handle, programs) != nullptr;) | |||
++programs; | |||
} | |||
LADSPA_Data bufferAudio[kBufferSize][audioTotal]; | |||
@@ -997,7 +995,7 @@ void do_dssi_check(void*& libHandle, const char* const filename, const bool init | |||
#endif | |||
} | |||
void do_lv2_check(const char* const bundle, const bool init) | |||
static void do_lv2_check(const char* const bundle, const bool init) | |||
{ | |||
#ifdef WANT_LV2 | |||
Lv2WorldClass& lv2World(Lv2WorldClass::getInstance()); | |||
@@ -1212,7 +1210,7 @@ void do_lv2_check(const char* const bundle, const bool init) | |||
#endif | |||
} | |||
void do_vst_check(void*& libHandle, const bool init) | |||
static void do_vst_check(void*& libHandle, const bool init) | |||
{ | |||
#ifdef WANT_VST | |||
VST_Function vstFn = (VST_Function)lib_symbol(libHandle, "VSTPluginMain"); | |||
@@ -1456,7 +1454,7 @@ void do_vst_check(void*& libHandle, const bool init) | |||
#endif | |||
} | |||
void do_au_check(void*& libHandle, const bool init) | |||
static void do_au_check(void*& libHandle, const bool init) | |||
{ | |||
#if 0 //def WANT_AU | |||
#else | |||
@@ -1470,7 +1468,7 @@ void do_au_check(void*& libHandle, const bool init) | |||
}; | |||
#ifdef HAVE_JUCE | |||
void do_juce_check(const char* const filename, const char* const stype, const bool init) | |||
static void do_juce_check(const char* const filename, const char* const stype, const bool init) | |||
{ | |||
using namespace juce; | |||
@@ -1556,7 +1554,7 @@ void do_juce_check(const char* const filename, const char* const stype, const bo | |||
} | |||
#endif | |||
void do_csound_check(const char* const filename, const bool init) | |||
static void do_csound_check(const char* const filename, const bool init) | |||
{ | |||
#ifdef WANT_CSOUND | |||
Csound csound; | |||
@@ -1659,7 +1657,7 @@ void do_csound_check(const char* const filename, const bool init) | |||
#endif | |||
} | |||
void do_fluidsynth_check(const char* const filename, const bool init) | |||
static void do_fluidsynth_check(const char* const filename, const bool init) | |||
{ | |||
#ifdef WANT_FLUIDSYNTH | |||
if (! fluid_is_soundfont(filename)) | |||
@@ -1685,7 +1683,7 @@ void do_fluidsynth_check(const char* const filename, const bool init) | |||
fluid_sfont_t* f_sfont; | |||
fluid_preset_t f_preset; | |||
f_sfont = fluid_synth_get_sfont_by_id(f_synth, f_id); | |||
f_sfont = fluid_synth_get_sfont_by_id(f_synth, static_cast<uint>(f_id)); | |||
f_sfont->iteration_start(f_sfont); | |||
while (f_sfont->iteration_next(f_sfont, &f_preset)) | |||
@@ -1745,7 +1743,7 @@ void do_fluidsynth_check(const char* const filename, const bool init) | |||
#endif | |||
} | |||
void do_linuxsampler_check(const char* const filename, const char* const stype, const bool init) | |||
static void do_linuxsampler_check(const char* const filename, const char* const stype, const bool init) | |||
{ | |||
#ifdef WANT_LINUXSAMPLER | |||
const QFileInfo file(filename); | |||
@@ -1932,6 +1930,13 @@ int main(int argc, char* argv[]) | |||
return 0; | |||
} | |||
// -------------------------------------------------------------------------- | |||
// Extras | |||
#ifdef WANT_DSSI | |||
# include "CarlaDssiUtils.cpp" | |||
#endif | |||
#ifdef HAVE_JUCE | |||
// -------------------------------------------------------------------------- | |||
// we want juce_audio_processors but without UI code | |||
@@ -1,18 +0,0 @@ | |||
/* | |||
* Carla Plugin discovery, MacOS objc++ file | |||
* Copyright (C) 2014 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 doc/GPL.txt file. | |||
*/ | |||
#include "carla-discovery.cpp" |
@@ -0,0 +1,60 @@ | |||
/* | |||
* Carla DSSI utils | |||
* Copyright (C) 2013-2014 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 doc/GPL.txt file. | |||
*/ | |||
#include "CarlaDssiUtils.hpp" | |||
#include <QtCore/QDir> | |||
#include <QtCore/QFileInfo> | |||
#include <QtCore/QStringList> | |||
// ----------------------------------------------------------------------- | |||
const char* find_dssi_ui(const char* const filename, const char* const label) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr); | |||
CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0', nullptr); | |||
carla_debug("find_dssi_ui(\"%s\", \"%s\")", filename, label); | |||
QString guiFilename; | |||
QString pluginDir(filename); | |||
pluginDir.resize(pluginDir.lastIndexOf(".")); | |||
QString checkLabel(label); | |||
QString checkSName(QFileInfo(pluginDir).baseName()); | |||
if (! checkLabel.endsWith("_")) checkLabel += "_"; | |||
if (! checkSName.endsWith("_")) checkSName += "_"; | |||
QStringList guiFiles(QDir(pluginDir).entryList()); | |||
foreach (const QString& gui, guiFiles) | |||
{ | |||
if (gui.startsWith(checkLabel) || gui.startsWith(checkSName)) | |||
{ | |||
QFileInfo finalname(pluginDir + QDir::separator() + gui); | |||
guiFilename = finalname.absoluteFilePath(); | |||
break; | |||
} | |||
} | |||
if (guiFilename.isEmpty()) | |||
return nullptr; | |||
return carla_strdup(guiFilename.toUtf8().constData()); | |||
} | |||
// ----------------------------------------------------------------------- |
@@ -1,6 +1,6 @@ | |||
/* | |||
* Carla DSSI utils | |||
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||
* Copyright (C) 2013-2014 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 | |||
@@ -21,50 +21,10 @@ | |||
#include "CarlaLadspaUtils.hpp" | |||
#include "dssi/dssi.h" | |||
// TODO - put this in a cpp file | |||
//#include <QtCore/QDir> | |||
//#include <QtCore/QFileInfo> | |||
//#include <QtCore/QStringList> | |||
// ----------------------------------------------------------------------- | |||
// Find UI binary for a plugin (returned value must be deleted) | |||
//static inline | |||
const char* find_dssi_ui(const char* const filename, const char* const label); | |||
#if 0 | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', nullptr); | |||
CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0', nullptr); | |||
carla_debug("find_dssi_ui(\"%s\", \"%s\")", filename, label); | |||
QString guiFilename; | |||
QString pluginDir(filename); | |||
pluginDir.resize(pluginDir.lastIndexOf(".")); | |||
QString checkLabel(label); | |||
QString checkSName(QFileInfo(pluginDir).baseName()); | |||
if (! checkLabel.endsWith("_")) checkLabel += "_"; | |||
if (! checkSName.endsWith("_")) checkSName += "_"; | |||
QStringList guiFiles(QDir(pluginDir).entryList()); | |||
foreach (const QString& gui, guiFiles) | |||
{ | |||
if (gui.startsWith(checkLabel) || gui.startsWith(checkSName)) | |||
{ | |||
QFileInfo finalname(pluginDir + QDir::separator() + gui); | |||
guiFilename = finalname.absoluteFilePath(); | |||
break; | |||
} | |||
} | |||
if (guiFilename.isEmpty()) | |||
return nullptr; | |||
return carla_strdup(guiFilename.toUtf8().constData()); | |||
} | |||
#endif | |||
// ----------------------------------------------------------------------- | |||