Browse Source

Rack-mode works again

tags/1.9.4
falkTX 12 years ago
parent
commit
57011aab0e
5 changed files with 196 additions and 194 deletions
  1. +49
    -56
      source/backend/engine/CarlaEngine.cpp
  2. +27
    -45
      source/backend/engine/CarlaEngine.pro
  3. +10
    -1
      source/backend/engine/CarlaEngineInternal.hpp
  4. +105
    -87
      source/backend/engine/CarlaEngineJack.cpp
  5. +5
    -5
      source/backend/standalone/CarlaStandalone.cpp

+ 49
- 56
source/backend/engine/CarlaEngine.cpp View File

@@ -516,6 +516,8 @@ bool CarlaEngine::init(const char* const clientName)
{
case PROCESS_MODE_CONTINUOUS_RACK:
kData->maxPluginNumber = MAX_RACK_PLUGINS;
kData->rack.in = new EngineEvent[RACK_EVENT_COUNT];
kData->rack.out = new EngineEvent[RACK_EVENT_COUNT];
break;
case PROCESS_MODE_PATCHBAY:
kData->maxPluginNumber = MAX_PATCHBAY_PLUGINS;
@@ -574,6 +576,18 @@ bool CarlaEngine::close()
kData->plugins = nullptr;
}

if (kData->rack.in != nullptr)
{
delete[] kData->rack.in;
kData->rack.in = nullptr;
}

if (kData->rack.out != nullptr)
{
delete[] kData->rack.out;
kData->rack.out = nullptr;
}

fName.clear();

return true;
@@ -1319,11 +1333,13 @@ void CarlaEngine::setPeaks(const unsigned int pluginId, float const inPeaks[MAX_
#ifndef BUILD_BRIDGE
EngineEvent* CarlaEngine::getRackEventBuffer(const bool isInput)
{
// TODO
return nullptr;
return isInput ? kData->rack.in : kData->rack.out;
}

// unused
(void)isInput;
void setValueIfHigher(float& value, const float& compare)
{
if (value < compare)
value = compare;
}

void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t frames)
@@ -1331,57 +1347,34 @@ void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t
// initialize outputs (zero)
carla_zeroFloat(outBuf[0], frames);
carla_zeroFloat(outBuf[1], frames);

//std::memset(rackEventsOut, 0, sizeof(EngineEvent)*MAX_EVENTS);
carla_zeroMem(kData->rack.out, sizeof(EngineEvent)*RACK_EVENT_COUNT);

bool processed = false;

// process plugins
for (unsigned int i=0; i < kData->curPluginCount; i++)
{
CarlaPlugin* const plugin = getPluginUnchecked(i);
CarlaPlugin* const plugin = kData->plugins[i].plugin;

if (plugin == nullptr || ! plugin->enabled())
continue;

// TODO
#if 0
if (processed)
{
// initialize inputs (from previous outputs)
memcpy(inBuf[0], outBuf[0], sizeof(float)*frames);
memcpy(inBuf[1], outBuf[1], sizeof(float)*frames);
memcpy(rackMidiEventsIn, rackMidiEventsOut, sizeof(CarlaEngineMidiEvent)*MAX_MIDI_EVENTS);
std::memcpy(inBuf[0], outBuf[0], sizeof(float)*frames);
std::memcpy(inBuf[1], outBuf[1], sizeof(float)*frames);
std::memcpy(kData->rack.in, kData->rack.out, sizeof(EngineEvent)*RACK_EVENT_COUNT);

// initialize outputs (zero)
carla_zeroFloat(outBuf[0], frames);
carla_zeroFloat(outBuf[1], frames);
memset(rackMidiEventsOut, 0, sizeof(CarlaEngineMidiEvent)*MAX_MIDI_EVENTS);
carla_zeroMem(kData->rack.out, sizeof(EngineEvent)*RACK_EVENT_COUNT);
}

// process
processLock();
plugin->initBuffers();

if (false /*plugin->data->processHighPrecision*/)
{
float* inBuf2[2];
float* outBuf2[2];

for (uint32_t j=0; j < frames; j += 8)
{
inBuf2[0] = inBuf[0] + j;
inBuf2[1] = inBuf[1] + j;

outBuf2[0] = outBuf[0] + j;
outBuf2[1] = outBuf[1] + j;

plugin->process(inBuf2, outBuf2, 8, j);
}
}
else
plugin->process(inBuf, outBuf, frames);

processUnlock();
plugin->process(inBuf, outBuf, frames);

// if plugin has no audio inputs, add previous buffers
if (plugin->audioInCount() == 0)
@@ -1393,38 +1386,38 @@ void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t
}
}

// if plugin has no midi output, add previous midi input
#if 0
// if plugin has no midi output, add previous events
if (plugin->midiOutCount() == 0)
{
memcpy(rackMidiEventsOut, rackMidiEventsIn, sizeof(CarlaEngineMidiEvent)*MAX_MIDI_EVENTS);
for (uint32_t j=0, k=0; j < frames; j++)
{

}
std::memcpy(kData->rack.out, kData->rack.in, sizeof(EngineEvent)*RACK_EVENT_COUNT);
}
#endif

// set peaks
{
double inPeak1 = 0.0;
double inPeak2 = 0.0;
double outPeak1 = 0.0;
double outPeak2 = 0.0;
float inPeak1 = 0.0f;
float inPeak2 = 0.0f;
float outPeak1 = 0.0f;
float outPeak2 = 0.0f;

for (uint32_t k=0; k < frames; k++)
{
// TODO - optimize this
if (std::abs(inBuf[0][k]) > inPeak1)
inPeak1 = std::abs(inBuf[0][k]);
if (std::abs(inBuf[1][k]) > inPeak2)
inPeak2 = std::abs(inBuf[1][k]);
if (std::abs(outBuf[0][k]) > outPeak1)
outPeak1 = std::abs(outBuf[0][k]);
if (std::abs(outBuf[1][k]) > outPeak2)
outPeak2 = std::abs(outBuf[1][k]);
setValueIfHigher(inPeak1, std::fabs(inBuf[0][k]));
setValueIfHigher(inPeak2, std::fabs(inBuf[1][k]));
setValueIfHigher(outPeak1, std::fabs(outBuf[0][k]));
setValueIfHigher(outPeak2, std::fabs(outBuf[1][k]));
}

data->insPeak[i*MAX_PEAKS + 0] = inPeak1;
data->insPeak[i*MAX_PEAKS + 1] = inPeak2;
data->outsPeak[i*MAX_PEAKS + 0] = outPeak1;
data->outsPeak[i*MAX_PEAKS + 1] = outPeak2;
kData->plugins[i].insPeak[0] = inPeak1;
kData->plugins[i].insPeak[1] = inPeak2;
kData->plugins[i].outsPeak[0] = outPeak1;
kData->plugins[i].outsPeak[1] = outPeak2;
}
#endif

processed = true;
}
@@ -1434,7 +1427,7 @@ void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t
{
std::memcpy(outBuf[0], inBuf[0], sizeof(float)*frames);
std::memcpy(outBuf[1], inBuf[1], sizeof(float)*frames);
//std::memcpy(rackEventsOut, rackEventsIn, sizeof(EngineEvent)*MAX_EVENTS);
std::memcpy(kData->rack.out, kData->rack.in, sizeof(EngineEvent)*RACK_EVENT_COUNT);
}
}



+ 27
- 45
source/backend/engine/CarlaEngine.pro View File

@@ -1,7 +1,9 @@
# QtCreator project file

QT = core

CONFIG = debug
CONFIG += link_pkgconfig shared warn_on
CONFIG += link_pkgconfig shared qt warn_on

DEFINES = DEBUG
DEFINES += QTCREATOR_TEST
@@ -31,37 +33,37 @@ TEMPLATE = lib
VERSION = 0.5.0

SOURCES = \
carla_engine.cpp \
carla_engine_osc.cpp \
carla_engine_thread.cpp \
jack.cpp \
plugin.cpp \
rtaudio.cpp
CarlaEngine.cpp \
CarlaEngineOsc.cpp \
CarlaEngineThread.cpp \
CarlaEngineJack.cpp \
CarlaEnginePlugin.cpp \
CarlaEngineRtAudio.cpp

HEADERS = \
carla_engine_internal.hpp \
carla_engine_osc.hpp \
carla_engine_thread.hpp
CarlaEngineInternal.hpp \
CarlaEngineOsc.hpp \
CarlaEngineThread.hpp

HEADERS += \
../carla_backend.hpp \
../carla_engine.hpp \
../carla_plugin.hpp
../CarlaBackend.hpp \
../CarlaEngine.hpp \
../CarlaPlugin.hpp

HEADERS += \
../../includes/carla_defines.hpp \
../../includes/carla_midi.h \
../../utils/carla_mutex.hpp \
../../utils/carla_string.hpp \
../../utils/carla_thread.hpp \
../../utils/carla_utils.hpp \
../../utils/carla_backend_utils.hpp \
../../utils/carla_juce_utils.hpp \
../../utils/carla_osc_utils.hpp \
../../utils/carla_state_utils.hpp
../../includes/CarlaDefines.hpp \
../../includes/CarlaMIDI.h \
../../utils/CarlaMutex.hpp \
../../utils/CarlaString.hpp \
../../utils/CarlaThread.hpp \
../../utils/CarlaUtils.hpp \
../../utils/CarlaBackendUtils.hpp \
../../utils/CarlaJuceUtils.hpp \
../../utils/CarlaOscUtils.hpp \
../../utils/CarlaStateUtils.hpp

HEADERS += \
plugin/DistrhoPluginInfo.h
distrho/DistrhoPluginInfo.h

INCLUDEPATH = . .. \
../../includes \
@@ -76,24 +78,4 @@ SOURCES += rtmidi-2.0.1/RtMidi.cpp
# Plugin
INCLUDEPATH += plugin ../../libs/distrho-plugin-toolkit

# ---------------------------------------------------------------------------------------

PKGCONFIG += QtCore

# Fake includes
INCLUDEPATH += \
/usr/include/qt4/ \
/opt/kxstudio/include/

# System includes
QMAKE_CXXFLAGS += -isystem /usr/include/qt4/
QMAKE_CXXFLAGS += -isystem /opt/kxstudio/include/

WARN_FLAGS = \
-ansi -pedantic -pedantic-errors -Wall -Wextra -Wformat=2 -Wunused-parameter -Wuninitialized \
-Wcast-qual -Wconversion -Wsign-conversion -Wlogical-op -Waggregate-return -Wno-vla \
-fipa-pure-const -Wsuggest-attribute=const #pure,const,noreturn

QMAKE_CFLAGS += $${WARN_FLAGS} -std=c99 -Wc++-compat -Wunsuffixed-float-constants -Wwrite-strings
# QMAKE_CXXFLAGS += $${WARN_FLAGS} -std=c++0x -fPIC
QMAKE_CXXFLAGS += $${WARN_FLAGS} -std=c++11 -Wzero-as-null-pointer-constant
QMAKE_CXXFLAGS += -std=c++0x

+ 10
- 1
source/backend/engine/CarlaEngineInternal.hpp View File

@@ -98,7 +98,7 @@ const char* EngineControlEventType2Str(const EngineControlEventType type)
*/
const uint32_t PATCHBAY_BUFFER_SIZE = 128;
const unsigned short PATCHBAY_EVENT_COUNT = 512;
const unsigned short RACK_EVENT_COUNT = 1024;
const unsigned short RACK_EVENT_COUNT = 512;

#if 0
struct EnginePostEvent {
@@ -167,6 +167,15 @@ struct CarlaEngineProtectedData {
}
} nextAction;

struct Rack {
EngineEvent* in;
EngineEvent* out;

Rack()
: in(nullptr),
out(nullptr) {}
} rack;

EnginePluginData* plugins;

CarlaEngineProtectedData(CarlaEngine* const engine)


+ 105
- 87
source/backend/engine/CarlaEngineJack.cpp View File

@@ -805,150 +805,168 @@ protected:
float* inBuf[2] = { audioIn1, audioIn2 };
float* outBuf[2] = { audioOut1, audioOut2 };

#if 0
// initialize control input
memset(rackControlEventsIn, 0, sizeof(CarlaEngineControlEvent)*MAX_CONTROL_EVENTS);
// initialize input events
carla_zeroMem(kData->rack.in, sizeof(EngineEvent)*RACK_EVENT_COUNT);
{
jack_midi_event_t jackEvent;
const uint32_t jackEventCount = jackbridge_midi_get_event_count(controlIn);
uint32_t engineEventIndex = 0;

uint32_t carlaEventIndex = 0;
jack_midi_event_t jackEvent;
const uint32_t jackEventCount = jackbridge_midi_get_event_count(eventIn);

for (uint32_t jackEventIndex=0; jackEventIndex < jackEventCount; jackEventIndex++)
{
if (jackbridge_midi_event_get(&jackEvent, controlIn, jackEventIndex) != 0)
if (jackbridge_midi_event_get(&jackEvent, eventIn, jackEventIndex) != 0)
continue;

CarlaEngineControlEvent* const carlaEvent = &rackControlEventsIn[carlaEventIndex++];
EngineEvent* const engineEvent = &kData->rack.in[engineEventIndex++];
engineEvent->clear();

const uint8_t midiStatus = jackEvent.buffer[0];
const uint8_t midiChannel = midiStatus & 0x0F;
const uint8_t midiStatus = MIDI_GET_STATUS_FROM_DATA(jackEvent.buffer);
const uint8_t midiChannel = MIDI_GET_CHANNEL_FROM_DATA(jackEvent.buffer);

carlaEvent->time = jackEvent.time;
carlaEvent->channel = midiChannel;
engineEvent->time = jackEvent.time;
engineEvent->channel = midiChannel;

if (MIDI_IS_STATUS_CONTROL_CHANGE(midiStatus))
{
const uint8_t midiControl = jackEvent.buffer[1];
engineEvent->type = kEngineEventTypeControl;

if (MIDI_IS_CONTROL_BANK_SELECT(midiControl))
{
const uint8_t midiBank = jackEvent.buffer[2];
carlaEvent->type = CarlaEngineMidiBankChangeEvent;
carlaEvent->value = midiBank;
const uint8_t midiBank = jackEvent.buffer[2];

engineEvent->ctrl.type = kEngineControlEventTypeMidiBank;
engineEvent->ctrl.param = midiBank;
engineEvent->ctrl.value = 0.0;
}
else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF)
{
carlaEvent->type = CarlaEngineAllSoundOffEvent;
engineEvent->ctrl.type = kEngineControlEventTypeAllSoundOff;
engineEvent->ctrl.param = 0;
engineEvent->ctrl.value = 0.0;
}
else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF)
{
carlaEvent->type = CarlaEngineAllNotesOffEvent;
engineEvent->ctrl.type = kEngineControlEventTypeAllNotesOff;
engineEvent->ctrl.param = 0;
engineEvent->ctrl.value = 0.0;
}
else
{
const uint8_t midiValue = jackEvent.buffer[2];
carlaEvent->type = CarlaEngineParameterChangeEvent;
carlaEvent->parameter = midiControl;
carlaEvent->value = double(midiValue)/127;

engineEvent->ctrl.type = kEngineControlEventTypeParameter;
engineEvent->ctrl.param = midiControl;
engineEvent->ctrl.value = double(midiValue)/127.0;
}
}
else if (MIDI_IS_STATUS_PROGRAM_CHANGE(midiStatus))
{
const uint8_t midiProgram = jackEvent.buffer[1];
carlaEvent->type = CarlaEngineMidiProgramChangeEvent;
carlaEvent->value = midiProgram;
engineEvent->type = kEngineEventTypeControl;

engineEvent->ctrl.type = kEngineControlEventTypeMidiProgram;
engineEvent->ctrl.param = midiProgram;
engineEvent->ctrl.value = 0.0;
}
}
}
else
{
engineEvent->type = kEngineEventTypeMidi;

// initialize midi input
memset(rackMidiEventsIn, 0, sizeof(CarlaEngineMidiEvent)*MAX_MIDI_EVENTS);
{
uint32_t i = 0, j = 0;
jack_midi_event_t jackEvent;
engineEvent->midi.data[0] = midiStatus;
engineEvent->midi.data[1] = jackEvent.buffer[1];
engineEvent->midi.data[2] = jackEvent.buffer[2];
engineEvent->midi.size = static_cast<uint8_t>(jackEvent.size);
}

while (jackbridge_midi_event_get(&jackEvent, midiIn, j++) == 0)
{
if (i == MAX_MIDI_EVENTS)
if (engineEventIndex >= RACK_EVENT_COUNT)
break;

if (jackEvent.size < 4)
{
rackMidiEventsIn[i].time = jackEvent.time;
rackMidiEventsIn[i].size = jackEvent.size;
memcpy(rackMidiEventsIn[i].data, jackEvent.buffer, jackEvent.size);
i += 1;
}
}
}
#endif

// process rack
processRack(inBuf, outBuf, nframes);

#if 0
// output control
{
jackbridge_midi_clear_buffer(controlOut);
jackbridge_midi_clear_buffer(eventOut);

for (unsigned short i=0; i < MAX_CONTROL_EVENTS; i++)
for (unsigned short i=0; i < RACK_EVENT_COUNT; i++)
{
CarlaEngineControlEvent* const event = &rackControlEventsOut[i];
EngineEvent* const engineEvent = &kData->rack.out[i];

if (event->type == CarlaEngineParameterChangeEvent && MIDI_IS_CONTROL_BANK_SELECT(event->parameter))
event->type = CarlaEngineMidiBankChangeEvent;
uint8_t data[3] = { 0 };
uint8_t size = 0;

uint8_t data[4] = { 0 };

switch (event->type)
switch (engineEvent->type)
{
case CarlaEngineNullEvent:
break;
case CarlaEngineParameterChangeEvent:
data[0] = MIDI_STATUS_CONTROL_CHANGE + event->channel;
data[1] = event->parameter;
data[2] = event->value * 127;
jackbridge_midi_event_write(controlOut, event->time, data, 3);
case kEngineEventTypeNull:
break;
case CarlaEngineMidiBankChangeEvent:
data[0] = MIDI_STATUS_CONTROL_CHANGE + event->channel;
data[1] = MIDI_CONTROL_BANK_SELECT;
data[2] = event->value;
jackbridge_midi_event_write(controlOut, event->time, data, 3);
break;
case CarlaEngineMidiProgramChangeEvent:
data[0] = MIDI_STATUS_PROGRAM_CHANGE + event->channel;
data[1] = event->value;
jackbridge_midi_event_write(controlOut, event->time, data, 2);
break;
case CarlaEngineAllSoundOffEvent:
data[0] = MIDI_STATUS_CONTROL_CHANGE + event->channel;
data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
jackbridge_midi_event_write(controlOut, event->time, data, 2);
break;
case CarlaEngineAllNotesOffEvent:
data[0] = MIDI_STATUS_CONTROL_CHANGE + event->channel;
data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
jackbridge_midi_event_write(controlOut, event->time, data, 2);

case kEngineEventTypeControl:
{
EngineControlEvent* const ctrlEvent = &engineEvent->ctrl;

if (ctrlEvent->type == kEngineControlEventTypeParameter && MIDI_IS_CONTROL_BANK_SELECT(ctrlEvent->param))
{
// FIXME?
ctrlEvent->type = kEngineControlEventTypeMidiBank;
ctrlEvent->param = ctrlEvent->value;
ctrlEvent->value = 0.0;
}

switch (ctrlEvent->type)
{
case kEngineControlEventTypeNull:
break;
case kEngineControlEventTypeParameter:
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent->channel;
data[1] = static_cast<uint8_t>(ctrlEvent->param);
data[2] = uint8_t(ctrlEvent->value * 127.0);
size = 3;
break;
case kEngineControlEventTypeMidiBank:
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent->channel;
data[1] = MIDI_CONTROL_BANK_SELECT;
data[2] = static_cast<uint8_t>(ctrlEvent->param);
size = 3;
break;
case kEngineControlEventTypeMidiProgram:
data[0] = MIDI_STATUS_PROGRAM_CHANGE + engineEvent->channel;
data[1] = static_cast<uint8_t>(ctrlEvent->param);
size = 2;
break;
case kEngineControlEventTypeAllSoundOff:
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent->channel;
data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
size = 2;
break;
case kEngineControlEventTypeAllNotesOff:
data[0] = MIDI_STATUS_CONTROL_CHANGE + engineEvent->channel;
data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
size = 2;
break;
}
break;
}
}
}

// output midi
{
jackbridge_midi_clear_buffer(midiOut);
case kEngineEventTypeMidi:
{
EngineMidiEvent* const midiEvent = &engineEvent->midi;

for (unsigned short i=0; i < MAX_MIDI_EVENTS; i++)
{
if (rackMidiEventsOut[i].size == 0)
data[0] = midiEvent->data[0];
data[1] = midiEvent->data[1];
data[2] = midiEvent->data[2];
size = midiEvent->size;
break;
}
}

jackbridge_midi_event_write(midiOut, rackMidiEventsOut[i].time, rackMidiEventsOut[i].data, rackMidiEventsOut[i].size);
if (size > 0)
jackbridge_midi_event_write(eventOut, engineEvent->time, data, size);
}
}
#endif
}
#endif // ! BUILD_BRIDGE



+ 5
- 5
source/backend/standalone/CarlaStandalone.cpp View File

@@ -212,12 +212,12 @@ bool carla_engine_init(const char* driverName, const char* clientName)
standalone.engine->setCallback(standalone.callback, nullptr);

#ifndef BUILD_BRIDGE
standalone.engine->setOption(CarlaBackend::OPTION_PROCESS_MODE, standalone.options.processMode ? 1 : 0, nullptr);
standalone.engine->setOption(CarlaBackend::OPTION_FORCE_STEREO, standalone.options.forceStereo ? 1 : 0, nullptr);
standalone.engine->setOption(CarlaBackend::OPTION_PREFER_PLUGIN_BRIDGES, standalone.options.preferPluginBridges ? 1 : 0, nullptr);
standalone.engine->setOption(CarlaBackend::OPTION_PREFER_UI_BRIDGES, standalone.options.preferUiBridges ? 1 : 0, nullptr);
standalone.engine->setOption(CarlaBackend::OPTION_PROCESS_MODE, static_cast<int>(standalone.options.processMode), nullptr);
standalone.engine->setOption(CarlaBackend::OPTION_FORCE_STEREO, standalone.options.forceStereo ? 1 : 0, nullptr);
standalone.engine->setOption(CarlaBackend::OPTION_PREFER_PLUGIN_BRIDGES, standalone.options.preferPluginBridges ? 1 : 0, nullptr);
standalone.engine->setOption(CarlaBackend::OPTION_PREFER_UI_BRIDGES, standalone.options.preferUiBridges ? 1 : 0, nullptr);
# ifdef WANT_DSSI
standalone.engine->setOption(CarlaBackend::OPTION_USE_DSSI_VST_CHUNKS, standalone.options.useDssiVstChunks ? 1 : 0, nullptr);
standalone.engine->setOption(CarlaBackend::OPTION_USE_DSSI_VST_CHUNKS, standalone.options.useDssiVstChunks ? 1 : 0, nullptr);
# endif
standalone.engine->setOption(CarlaBackend::OPTION_MAX_PARAMETERS, static_cast<int>(standalone.options.maxParameters), nullptr);
standalone.engine->setOption(CarlaBackend::OPTION_PREFERRED_BUFFER_SIZE, static_cast<int>(standalone.options.preferredBufferSize), nullptr);


Loading…
Cancel
Save